Git stash 暂存
你一定遇到过这种场景:正在 feature 分支热火朝天写代码,改了一半还没法 commit,突然同事喊"main 上有个线上 bug,赶紧修一下!"。你想切到 main 去修,但 Git 不让你走——工作区有未提交的改动,切分支会覆盖它们。这时候 git stash 就是救星:它能把改动临时"藏起来",让工作区变干净,等你忙完回来再"取出来"。
1. stash 基本用法
stash(暂存)就像一个临时抽屉:把当前工作区的改动整个塞进去,工作区瞬间干净;等你忙完,再从抽屉里拿回来继续。它是一个栈结构(后进先出),可以连续藏多次。
# 场景:你正在 feature 分支改代码改到一半,
# 突然 main 有个紧急 bug 要修,但又不想 commit 半成品
# 1. 把当前改动"藏起来"(工作区变干净)
git stash
# 等价于 git stash push
# 输出: Saved working directory and index state WIP on feature: ...
# 2. 现在工作区干净了,可以切分支去修 bug
git switch main
git switch -c hotfix/login-crash
# ... 修 bug、commit、合并 ...
# 3. 回到 feature 分支,把刚才藏的改动"取回来"
git switch feature
git stash pop
# 工作区又恢复到改到一半的状态,继续干活
# stash 是个栈(后进先出),可以连续藏多次
git stash list
# stash@{0}: WIP on feature: a1b2c3d ...
# stash@{1}: WIP on main: e4f5g6h ...2. 管理多个 stash
如果你频繁用 stash,可能会有好几个暂存堆在栈里。几个管理命令:
# 查看所有暂存
git stash list
# stash@{0}: WIP on feature: ...
# stash@{1}: WIP on main: ...
# 看某个暂存改了什么(不取出)
git stash show stash@{0}
git stash show -p stash@{0} # 完整 diff
# 取出暂存(两种方式)
git stash pop # 取出最近的(stash@{0})并删除它
git stash apply stash@{1} # 取出指定的但不删除(保留备份)
# 删除暂存
git stash drop stash@{0} # 删除指定的
git stash clear # 清空所有暂存(慎用!不可恢复)
# 取出时如果有冲突,pop 会失败但 stash 还在(安全)
# 解决冲突后 git stash drop 手动删除pop 和 apply 的区别:pop 取出后删除这个 stash(用完即走),apply 取出后保留 stash(适合"我想看看但不确定要不要")。新手建议用 apply,确认无误后再 drop,更安全。
3. 进阶用法
默认 git stash 只藏"已追踪文件的改动",不藏新文件(untracked)。一些精细控制:
# 只暂存已追踪文件的部分改动
git stash push -p
# 交互式选择"哪几块改动"要藏起来
# 暂存时带个 message,方便以后认出来
git stash push -m "登录页 WIP:表单做了一半"
git stash list
# stash@{0}: On feature: 登录页 WIP:表单做了一半
# 连未追踪的新文件也一起藏(默认不藏 untracked)
git stash -u
# 或
git stash --include-untracked
# 连 .gitignore 忽略的文件也藏
git stash -a
# 从某个暂存创建新分支(适合 stash 改动太老、和当前代码冲突)
git stash branch new-branch stash@{0}
# 会基于 stash 创建时的提交建分支,并取出改动给 stash 加 message 是好习惯——三天后你绝对不记得 stash@{0} 是什么,但"登录页 WIP:表单做了一半"一眼就懂。
4. 典型场景
# 典型场景:在错误的分支上改了代码
#
# 你以为自己在 feature 分支,其实在 main 上改了一大堆
# 这时不能直接 switch(feature 没这些改动)
#
git stash # 先藏起来
git switch feature # 切到正确的分支
git stash pop # 取出来,改动现在在 feature 上了
# ---
# 典型场景:多个紧急任务穿插
#
# 正在开发 A 功能 → 紧急修 B bug → 又被叫去查 C
git stash push -m "A 功能 WIP" # 藏 A
git switch -c hotfix/B ...
# 修完 B
git switch -c feature/C ...
# 查完 C
git switch feature/A
git stash list # 看哪个是 A
git stash pop stash@{1} # 取出 A 继续5. stash 的注意事项
- stash 不是永久存储:它存在本地
.git里,换电脑、删仓库就没了。别拿它当"待办清单"长期存放。 - 太久不取容易冲突:藏了一周,期间代码大改,取出时可能满屏冲突。尽快取出来。
- 优先 commit:如果改动够完整,直接
commit到一个临时分支更稳(stash 万一丢了找不回,commit 有 reflog 兜底)。 - 不要藏密钥:虽然 stash 在本地,但养成不把敏感信息随手藏的习惯。
6. stash vs commit 怎么选
- 用 stash:改动是"半成品、很快回来继续"、需要临时切走几分钟。比如修个紧急 bug、拉一下同事代码。
- 用 commit:改动是"一个完整的小步骤",哪怕 message 写"wip",commit 进临时分支也比 stash 可靠(有历史、能 reflog 找回)。
经验法则:超过半天不回来,就别用 stash,直接建个 wip 分支 commit 进去更安全。
← 上一篇 Git rebase 变基
下一篇 Git tag 标签 →