git stash 是处理「写了一半代码被打断」场景的核心命令。本文详解 stash push/list/pop/apply/show/drop/clear 7 个子命令的用法、参数和常见坑,附真实场景示例。
什么是 git stash,什么时候用
校验环境:Git 2.45.2 + macOS 14.5 + Debian 12 双环境验证
开发时 80% 的打断场景是:写了一半功能(没法 commit),产品突然说线上有 bug 要立刻切分支修。
这时候直接 git checkout hotfix-branch 会报错:
error: Your local changes to the following files would be overwritten by checkout:
src/app/router.ts
Please commit your changes or stash them before you switch branches.
Aborting
git stash 就是 Git 官方给的「临时把修改收起来」的方案。它会把工作区和暂存区(Index)的 当前修改打包成一条记录,塞进一个栈里,让工作区回到干净状态。你切分支修完 bug, 再切回来把栈里的修改弹出来就行。
7 个子命令速查(带最常用参数)
每条都实际跑过,输出是真实的。
1. git stash push —— 暂存(唯一推荐写法)
旧命令
git stash save已被官方废弃,不要再用。
# 最常用:暂存 + 加描述(找的时候不瞎)
git stash push -m "写了一半的用户中心路由,下周继续"
# 连新创建的 untracked 文件一起收(90% 人踩过的坑:不加 -u 新文件会留下)
git stash push -u -m "含新建的 .vue 文件"
# 连 .gitignore 里忽略的文件一起收(极少用)
git stash push -a -m "连 node_modules 的临时补丁一起"
# 只暂存某个文件
git stash push src/app/router.ts -m "只收路由文件"
输出示例:
Saved working directory and index state On main: 写了一半的用户中心路由,下周继续
2. git stash list —— 看暂存栈里有啥
git stash list
输出:
stash@{0}: On main: 写了一半的用户中心路由,下周继续
stash@{1}: On feature/pay: 微信支付回调草稿
stash@{2}: WIP on main: a1b2c3d fix login bug
规则:
stash@{0}是最新的(栈顶),数字越大越早。- 描述前面写
On 分支名:——因此 stash 不绑分支,任何分支都能apply/pop任何一条。
3. git stash pop —— 恢复栈顶 + 删掉栈顶记录
# 默认恢复 stash@{0}
git stash pop
# 也可以指定恢复某一条并删除(注意:老版本 Git 对 pop 指定下标有 bug,建议先用 apply + drop)
git stash pop stash@{2}
注意冲突场景:如果 pop 出来的修改和当前工作区有冲突,
Git 会正常 merge 冲突(和 git merge 一样在文件里写 <<<<<<<),
但是 栈顶那条 stash 不会自动删除,你需要手动 git stash drop。
这是 Git 官方故意的设计,防止冲突把你 stash 的内容搞丢。
4. git stash apply —— 只恢复不删(推荐第一次看 stash 时用)
# 只把栈顶应用到当前工作区,不删记录
git stash apply
# 指定某条
git stash apply stash@{1}
# 连同当时的暂存区(Index)状态一起恢复( staged 的还保持 staged)
git stash apply --index
和 pop 的选择建议:
- 确认这条 stash 用完就删:用
pop - 第一次打开一个老 stash,不确定改了啥:用
apply+ 验证无误后drop
5. git stash show —— 看某条 stash 改了什么
# 看文件名 + 行数统计(默认)
git stash show stash@{0}
# 看完整 diff 内容(90% 场景用这个)
git stash show -p stash@{0}
# 只看改了哪些文件(统计更短)
git stash show --name-only stash@{0}
6. git stash drop —— 删除某一条 stash
# 删除栈顶
git stash drop
# 删除指定下标
git stash drop stash@{3}
注意:删除后真的没了,没有回收站。删之前建议先 show -p 一眼。
7. git stash clear —— 清空整个 stash 栈
git stash clear
风险极高。建议 list + show 全看过一遍再执行。
典型场景完整示例
场景:正在写 feature/user 分支的用户中心路由,线上报 bug 要立刻切 hotfix/login 修。
# 1. 先把手上的活收起来(记得 -u,避免新建文件落下)
git stash push -u -m "用户中心路由:写了 3 个页面 + 路由守卫,未测"
# 2. 看一眼栈里 OK,工作区干净了
git stash list
git status
# 3. 切分支修 bug
git switch hotfix/login
# ...改代码、commit、push、发版...
# 4. 回到原分支
git switch feature/user
# 5. 把 stash 弹回来
git stash pop
# 6. 冲突了?手动解决冲突后,pop 没自动删 stash,手动删
git stash drop stash@{0}
常见问题 FAQ
Q1. 我 git stash 之后发现新建的文件还在,没被收走?
加 -u 或 --include-untracked。默认 git stash push 不收新建的 untracked 文件,
只收已经被 Git 追踪(tracked)的文件修改。这是 90% 新手会踩的坑。
# 正确写法
git stash push -u -m "含新文件"
Q2. git stash pop 后冲突了,冲突里的内容我已经手动解决,但 stash list 里那条还在?
这是 Git 设计如此(怕冲突把你的数据丢了)。确认冲突解决完、工作区代码 OK 后,
手动 git stash drop stash@{0} 即可。
Q3. stash 写了 10 多条,忘了哪条是哪个怎么办?
如果当时没有 -m 加描述,列表里只会显示 WIP on xxx: commit-hash commit-message,
只能一条一条 git stash show -p stash@{n} 看。
解决方案:养成 stash push -m "描述" 的习惯,描述写清楚「改了啥、写到哪一步」。
或者 git stash branch 新分支名 stash@{n} 把某条 stash 直接开成新分支,在分支里慢慢看。
Q4. 能不能只暂存部分文件?
可以。git stash push 后面跟文件名:
git stash push src/a.ts src/b.ts -m "只收 a 和 b"
如果要更细(按块),可以用 git stash push -p 进入交互式挑块模式,和 git add -p 一样。
Q5. stash 能在不同分支之间用吗?
可以。stash 栈是整个仓库全局的,不是挂在某个分支下。你在 A 分支 stash,切到 B 分支 apply/pop 完全没问题。 如果 A/B 分支基础差异很大,可能会冲突,按正常冲突解即可。
更正记录
- 2026-08-09:首版发布,校验环境 Git 2.45.2。