在日常开发中,我们经常遇到这样的场景:正埋头实现一个新特性,突然接到一个紧急 Bug 需要切换到其他分支修复。此时,当前的修改还没完成,直接提交(Commit)会产生无意义的历史记录,而不处理又无法切换分支。
git stash 就是专门为解决这种“进退两难”而设计的工具。它能将当前未提交的修改暂时“存”起来,让工作区恢复整洁。本文将深入解析 Git Stash 的全套用法,从基础保存到高级的选择性暂存。
什么是 Git Stash?
git stash 会临时搁置你当前的修改(包括已暂存和未暂存的已跟踪文件),使你能够返回到一个干净的工作目录。
从底层逻辑看,Stash 是以“后进先出”(LIFO)的堆栈形式存储的。最近一次存入的内容标识为 stash@{0},倒数第二次为 stash@{1},以此类推。
默认情况下,git stash 只会保存:
- 已修改的受版本控制的文件(Modified tracked files)
- 已放入暂存区的修改(Staged changes)
注意:它默认不会保存新创建的、尚未被 Git 跟踪的文件(Untracked files)以及被 .gitignore 忽略的文件。
保存修改的几种姿势
假设你正在处理一个复杂的脚本,修改了 config.yaml 却还没准备好提交。
1. 基础暂存
运行以下命令,你的工作区将恢复到最后一次提交的状态:
git stash
2. 包含未跟踪的文件
如果你新建了一些测试文件,普通的 git stash 会漏掉它们。使用 -u 参数可以连同未跟踪的文件一起存入堆栈:
git stash -u
如果需要把被忽略(Ignored)的文件也一并存入,可以使用 -a(即 --all),但通常建议谨慎使用,避免把本地环境的日志或缓存也存了进去。
3. 为暂存命名
当堆栈里有多个记录时,默认的 WIP on main... 描述会让你非常困惑。养成给 Stash 命名的习惯至关重要:
git stash push -m "重构了数据管道的配置逻辑"
查看与检视
在恢复代码之前,先确认 Stash 里到底存了什么是比较稳妥的做法。
列出所有记录
git stash list
输出会显示所有已存入的记录及其索引。
检查具体变更
如果想看某个 Stash 修改了哪些文件:
git stash show stash@{0}
如果想看更详细的行级代码差异(Diff):
git stash show -p stash@{0}
恢复暂存的代码
恢复代码主要有两种方式,区别在于是否保留堆栈中的记录。
pop:恢复并删除
这是最常用的方式。它会将堆栈顶部的记录应用到当前分支,并将其从堆栈中彻底移除:
git stash pop
apply:只恢复不删除
如果你希望将同一份修改应用到多个分支,或者只是想测试一下恢复效果,使用 apply:
git stash apply stash@{1}
应用后,该记录依然保留在堆栈中,除非你手动删除。
进阶:选择性暂存
有时候你只想暂存一部分代码,而保留另一部分继续开发。
暂存特定文件
通过文件路径指定只暂存某个文件:
git stash push -m "仅暂存配置修改" config.yaml
交互式暂存(补丁模式)
如果你连一个文件内的代码都想拆分处理,可以使用 -p 参数。Git 会询问你是否暂存每一个代码块(Hunk):
git stash push -p -m "选择性暂存部分逻辑"
常用交互选项:
y: 暂存此代码块n: 不暂存q: 退出并放弃暂存后续块d: 不暂存此文件及后续块
清理与分支化管理
手动删除
如果你确定某个暂存不再需要:
git stash drop stash@{0}
如果要清空所有记录(慎用):
git stash clear
将暂存转化为新分支
如果你的代码在 Stash 里放了太久,原分支已经发生了巨大变化,直接恢复可能会引发复杂的冲突。此时,最优雅的方案是基于暂存创建一个新分支:
git stash branch recovery-branch stash@{0}
该命令会:
- 以创建暂存时的那个提交为基点创建一个新分支。
- 将暂存的代码应用到新分支。
- 成功后自动从堆栈中删除该记录。
常见问题与坑点
1. “No local changes to save”
当你运行 git stash 却看到这个提示时,通常是因为:
- 你确实没改代码。
- 你的修改全部是新文件,但没加参数
-u。
2. 恢复冲突
如果 git stash pop 提示冲突,Git 会保留该记录在堆栈中。你需要像处理常规 Merge 冲突一样:
- 打开文件解决冲突。
- 运行
git add <file>。 - 手动运行
git stash drop删除已应用的记录。
总结
git stash 是开发者的“后悔药”和“临时置物架”。保持 Stash 记录短小且描述清晰是最佳实践。如果某个修改在 Stash 里放了一周还没动,那通常说明你应该为它创建一个专门的开发分支(WIP Branch),而不是继续让它躺在堆栈里。
关于
关注我获取更多资讯