正在改代码时突然来了个线上 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}

popapply 的区别:前者用完即弃,后者留着备份。恢复时如果与当前改动冲突,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. 实战:紧急切换分支

  1. 正在 feature/payment 开发,线上出 bug;
  2. git stash push -u -m "支付功能进行中" 寄存一切;
  3. git checkout -b hotfix/xxx main 拉修复分支,改完提交;
  4. 切回 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;如果改动超过一天没取回,认真考虑是不是应该直接提交或删掉。