正在改代码时突然来了个线上 bug,要立刻切分支修复——但手头的改动还没写完,不想提交又不敢丢。这时候 git stash 就是你的救星:它能把当前改动"寄存"到一边,让工作区瞬间干净,忙完再取回来。
1. stash 是什么
git stash 会把工作区和暂存区的改动保存到一个独立的"暂存栈"里,然后让工作区恢复到干净状态。它不产生提交记录,不污染历史,适合存放"还没到提交时机"的半成品。
和 git commit 最大的区别:stash 不会出现在 git log 里,也不会被推送;它纯粹是本地的一个"寄存处",用完随时可以丢弃,完全不影响仓库的正式历史。
2. 保存与恢复:push / pop
# 保存当前所有改动
git stash push -m "登录页样式进行中"
# 查看暂存栈
git stash list
# stash@{0}: On main: 登录页样式进行中
# 恢复最近一次 stash 并把它从栈中移除
git stash pop
# 恢复但不移除(可能想多次使用)
git stash apply stash@{0}
pop 与 apply 的区别:前者用完即弃,后者留着备份。恢复时如果与当前改动冲突,Git 会提示你手动解决,这和普通合并冲突的处理方式一样。
3. 查看 stash 里的细节
存多了容易记不清每个 stash 是什么,先用 show 看一眼再决定恢复哪个:
# 查看最近一个 stash 改动了哪些文件
git stash show stash@{0}
# 查看完整 diff(加 --stat 只看统计)
git stash show -p stash@{1}
4. 处理未跟踪文件
默认 git stash 只保存已被 Git 跟踪的文件,新建的文件(untracked)会被留在原地。想连新文件一起寄存,加参数:
# 连未跟踪文件一起存
git stash push -u -m "含新文件"
# 连被忽略的文件(.gitignore 里的)也存
git stash push -a -m "全部带走"
实战里最常用 -u:切分支做修复时,新写的代码文件也能干净带走,不会把半成品漏在分支里。
5. 清理与找回
# 删除指定的 stash
git stash drop stash@{0}
# 清空整个暂存栈
git stash clear
# 误删了?用 reflog 找回
git fsck --unreachable | grep commit
建议定期整理:stash 栈里堆了几十个"临时"改动,基本等于没有 stash,drop 掉确定不要的,保持栈里最多两三个。
6. 实战:紧急切换分支
- 正在
feature/payment开发,线上出 bug; git stash push -u -m "支付功能进行中"寄存一切;git checkout -b hotfix/xxx main拉修复分支,改完提交;- 切回
feature/payment,git stash pop取回改动,继续开发。
git stash push -u -m "支付功能进行中"
git checkout -b hotfix/timeout main
# ...修复并提交...
git checkout feature/payment
git stash pop
💡 学习建议:stash 是"切换上下文"的工具,不是"长期保存"的地方。养成习惯:离开一个分支前先 stash,回来第一件事 pop;如果改动超过一天没取回,认真考虑是不是应该直接提交或删掉。