你正改到一半,突然要切去修一个紧急 bug,手头的改动又没写完不能提交,这时候 Git 暂存改动就派上用场。核心答案先给:临时藏起已跟踪的改动用 git stash;要连未跟踪的新文件一起藏用 git stash -u(或 --include-untracked);想给这次储藏起个名字、方便以后找回用 git stash push -m "说明"。这篇以 Git 2.4x 为例,把三种暂存场景、恢复方式和协作中的坑一次讲清。下面先用一张决策表把三种方式摆清楚,再逐个拆命令和坑,今天这篇文章,编程狮就把这块讲透。

先看结论
Git 暂存改动有三种常见姿势,对应不同的“藏多干净”:
| 你的场景 | 首选写法 | 一句话理由 |
|---|---|---|
| 只藏已跟踪文件的改动 | git stash | 最常用、最快 |
| 连新文件一起藏 | git stash -u | 防止未跟踪文件漏网 |
| 给储藏起名便于找回 | git stash push -m | 多份储藏不混淆 |

一、Git 暂存改动到底在解决什么
Git 的“暂存”在这里指 stash:它把工作区和暂存区里还没提交的改动临时收进一个栈(stack)里,让目录回到最近一次提交的干净状态,方便你去切分支、拉代码或修紧急 bug。等忙完再把它弹出来,改动原样回到工作区继续。可以把它理解成“改动的中途寄存处”,和 commit 不同,stash 不写入历史。想系统学可以过一遍 Git 教程。
它解决的正是“改动没写完、却又必须离开当前分支”的尴尬,是日常高频的急救操作。无论是本地临时切走、还是并行验证另一个问题,stash 都能让你在不提交半成品的前提下腾出干净工作区,避免把没想清楚的代码过早 commit 而污染历史。
二、git stash:藏起已跟踪的改动
git stash 默认只收“已跟踪文件”的修改(也就是已经被 Git 记录过的文件),新建的、还没 git add 过的文件不会进栈。命令速查可以翻 Git 速查手册。
# 把当前改动藏起来,工作区恢复干净
git stash
# 之后想拿回来
git stash pop
git stash 把改动压栈并打印一个标识(如 stash@{0}),git stash pop 把它恢复并出栈。预期结果是工作区回到上次提交的干净状态,切分支或拉取都不会被拦。日常最常用就是裸 git stash:你改了一半、又不想 commit,它就帮你把现场收起来。典型场景是收到一个线上告警,需要立刻切到 main 拉最新代码排查,但手头的 feature 还没写完。stash 之后工作区干净,切换不再被拦。注意它只收已跟踪文件,新建文件要用下一节的 -u。
三、git stash -u:连未跟踪文件一起藏
git stash -u(等价 --include-untracked)会把未跟踪的新文件也一并收进栈,避免“切走后再回来,新文件却不知道丢没丢”的焦虑。
# 已跟踪 + 未跟踪 一起藏
git stash -u
# 连被忽略的文件也要藏(少见)
git stash -a
关键区别:不带 -u 时,新建但没 add 的文件会留在工作区,切换分支可能被带过去或冲突;加 -u 后工作区彻底干净。注意 -a 会连 .gitignore 里的忽略文件也藏,一般用不到。实战里 -u 比想象中更常用:比如你正在调研某个功能,顺手新建了几个草稿文件,正准备切去别的分支时,这些文件既没 add 又不想丢,就靠 -u 一并寄存。恢复时 git stash pop 会把这些未跟踪文件也一并放回工作区。
⚠️ 注意:stash 只是“临时栈”,不是提交。它不会进历史,长时间不 pop 容易忘。多人协作时别把含密钥的配置 stash 后到处切分支。
四、git stash push -m 与三种方式横向对比
git stash push -m "说明" 是给这次储藏加一段描述,尤其在有多份储藏时,靠名字比靠 stash@{0} 编号好认得多。命名储藏在团队协作里尤其值钱:当多个人都在各自分支上 stash 了改动,仅靠 stash@{0} 这种编号根本分不清谁是谁。给每份储藏加一句场景说明,比如“订单导出优化改到一半”,之后用 git stash list 一眼就能找到要恢复的那一份。
# 起名储藏,便于后续按名字找
git stash push -m "登录页改到一半"
# 列出所有储藏
git stash list
# 恢复指定那一份
git stash pop stash@{0}

把三种方式摆在一起对比:
| 方式 | 藏已跟踪 | 藏未跟踪 | 可命名 |
|---|---|---|---|
| git stash | 是 | 否 | 否 |
| git stash -u | 是 | 是 | 否 |
| git stash push -m | 是 | 否(可加 -u) | 是 |
踩坑清单
- 现象:stash 后新文件还在;原因:没加
-u;修复:用git stash -u重新藏。 - 现象:pop 时冲突;原因:恢复点与当前改动重叠;修复:先提交或再 stash,解决冲突后再
pop。 - 现象:忘了哪份储藏是什么;原因:没起名;修复:以后用
git stash push -m起名,或git stash list查看。 - 现象:储藏丢了找不回;原因:误用
git stash drop清掉;修复:用git fsck --lost-found碰碰运气,但最好养成及时 pop 的习惯。
总结
Git 暂存改动的选型逻辑是“看要不要连新文件、要不要起名”:普通藏已跟踪改动用 git stash;新建文件也要带走用 git stash -u;多份储藏怕混用 git stash push -m 起名。记住最痛的一课——stash 不是提交,不会进历史,藏完记得及时 git stash pop 恢复,别让它静静躺在栈里被遗忘。如果短期不打算恢复,也建议用 git stash list 定期清点,别让一堆“寄存”的改动在栈里越积越多,真到要用时反而找不到。
要点带走:
- git stash 只藏已跟踪改动,最快最常用;
- git stash -u 连未跟踪文件一起藏,工作区更干净;
- git stash push -m 给储藏起名,多份时不混淆。
顺手记一句:stash 栈是“先进后出”,最后压入的 stash@{0} 会最先弹出,恢复顺序和压栈顺序相反,批量处理时要留意别弹错那份。
下一步可以在本地故意改一半、建个新文件,分别用三种方式 stash 再 pop,体会藏匿范围的差别。
动手验证清单
下面这组动作帮你在本机验证三种暂存写法,按你自己的环境执行,结果以实际输出为准(本文命令未在作者本机执行,仅给出预期形态):
- 安装:装好 Git 2.4x 并进入任意一个仓库;
- 配置:改一个已跟踪文件,再新建一个未跟踪文件;
- 命令:执行
git stash看新文件是否还在; - 运行:
git stash -u再git status看工作区是否全干净; - 检查:
git stash list确认有两份储藏; - 预期:第一次新文件残留,第二次工作区彻底干净;
- 失败:pop 冲突时先
git stash当前改动再恢复; - 修复:用
git stash push -m起名避免混淆; - 验证:
git stash pop stash@{0}把指定储藏恢复回来。
延伸学习
想把 Git 工作流补完整,可以顺着这条线:
常见问题
Q:git stash 和 git commit 有什么区别?
A:git commit 把改动正式记入历史,永久可追溯;git stash 只是临时收进栈里,不进历史,适合“还没写完、但要先离开”的过渡。改动确定要保留就用 commit,只是暂歇才用 stash。
Q:stash 之后切分支,改动会丢吗?
A:不会。stash 把改动存进了栈,切分支不影响它;等你 git stash pop 回到原分支就能恢复。但要注意未跟踪文件默认不进栈,需加 -u。
Q:pop 和 apply 有什么不同?
A:git stash pop 恢复的同时把这份储藏从栈里删掉;git stash apply 只恢复、不删除,方便同一份改动在多个分支重复使用。确定只恢复一次就用 pop。

TRAE-AI编程



