🏠 首页 攻略 Git Stash 实用技巧:临时切换分支不再手忙脚乱

Git Stash 实用技巧:临时切换分支不再手忙脚乱

Git Stash 不只是 git stash save 那么简单。本文从基础保存到高级技巧,涵盖 stash 命名、查看恢复、清除管理、与 branch 配合使用,让你在任何分支切换场景下都能游刃有余。

你是不是也经历过这个场景?

正在修一个 bug,做到一半老板说有个紧急需求要先上。

你打开终端,准备切分支,结果 git checkout 直接报错:

error: Your local changes to the following files would be overwritten by checkout.
Please commit your changes before switching branches.

这时候你要么 git commit --amend 把半成品提交上去,要么 git stash 暂存起来。

很多人只知道 git stash 这一招,但真正用好它的人不多。今天聊聊 Git Stash 的实用技巧。

基础操作:三板斧

1. 暂存当前改动

git stash save "修复用户列表页面的样式问题"

注意这里用了 save 而不是 pushgit stash save "message" 会给你的 stash 加个描述,方便后续查找。

2. 查看有哪些 stash

git stash list
stash@{0}: On main: 修复用户列表页面的样式问题
stash@{1}: On main: 临时修改数据库连接配置
stash@{2}: WIP on main: a3f8c21

3. 恢复暂存的内容

git stash pop

pop 会恢复 stash 内容并删除这条 stash 记录。如果你还想保留,用 apply

git stash apply stash@{0}
# 内容恢复了,但 stash 记录还在

进阶技巧

只暂存部分文件

默认情况下 git stash 会暂存所有 tracked 文件的改动。但有时候你只想暂存一部分。

# 交互式选择哪些改动要暂存
git stash push -p

执行后,Git 会把你的改动拆成一个个 hunk,逐个问你"这个要不要 stash"。对于一个大 PR 中间突然要切分支的情况,这招特别好用。

暂存未跟踪的文件

git stash 默认不管 untracked 文件(新创建的、还没 git add 过的)。想连它们一起暂存:

git stash push -u

或者更激进的,把所有东西(包括 .gitignore 里的)都暂存:

git stash push -all

给 stash 打标签

当 stash 列表很长的时候,靠序号找就很痛苦。你可以给 stash 打标签:

git stash store -m "紧急修复:支付接口超时问题" $(git stash list | grep "支付" | awk '{print $2}' | tr -d ':')

不过更实用的方式是直接在 push 时加描述:

git stash push -m "支付接口超时修复 - 临时保存"

然后用 git stash list 就能直接看到描述,不用猜。

从 stash 创建新分支

这是很多人不知道的技巧。stash 里的代码可以直接变成一个新分支:

git stash branch fix/payment-timeout stash@{0}

这相当于做了三件事:

  1. 基于 stash 所在的分支创建新分支
  2. 应用 stash 内容
  3. 删除对应的 stash 记录

当你想在一个干净的分支上继续 stash 里的改动时,这招比手动 checkout + apply 省事多了。

日常管理

清除已合并的 stash

git stash drop stash@{0}

清空所有 stash

git stash clear

⚠️ 这个操作不可逆,执行前确认没有要保留的内容。

只保留最近 N 条

Git 本身没有这个命令,但可以配合脚本实现:

# 保留最新的 3 条 stash,其余全部删除
git stash list | tail -n +4 | while read line; do
  hash=$(echo "$line" | awk '{print $2}' | tr -d ':')
  git stash drop "$hash"
done

实战场景

场景一:多人协作的紧急 hotfix

你在开发 feature/user-profile 分支,已经改了一半。突然线上出了个 bug,需要马上修。

# 1. 保存当前进度
git stash push -m "用户资料页 - 进行中"

# 2. 切到 main 分支
git checkout main

# 3. 创建 hotfix 分支
git checkout -b hotfix/payment-fix

# 4. 修完 bug 后
git add .
git commit -m "修复支付超时问题"
git push origin hotfix/payment-fix

# 5. 回到原来的分支继续干活
git checkout feature/user-profile
git stash apply "用户资料页 - 进行中"

场景二:在多个分支间来回切换

比如你在两个不同的功能分支上各做了一半,想同时保留两边的进度。

# 在 feature-a 上
git stash push -m "feature-a 进度"
git checkout feature-b

# 在 feature-b 上也 stash
git stash push -m "feature-b 进度"

# 现在 stash list 里有两条,互不影响
git stash list

两边都恢复:

git checkout feature-a
git stash apply "feature-a 进度"

git checkout feature-b
git stash apply "feature-b 进度"

场景三:stash 冲突了怎么办

有时候 stash 的内容跟目标分支有冲突,git stash pop 会停下来让你手动解决。

# 冲突后,正常解决文件内容
# 然后标记为已解决
git add <冲突文件>

# 完成 stash 恢复
git stash drop

如果不想解决冲突,直接放弃这次 stash:

git stash drop stash@{0}

常见误区

误区一:stash 可以替代 commit

不行。stash 存在 .git 内部,不会被推送到远程。如果不小心清掉了 stash,那些改动就彻底没了。重要的改动一定要 commit。

误区二:git stash 会暂存所有东西

不会。它只暂存 tracked 文件的改动。新建的文件、.gitignore 里的内容都不会被 stash。需要用 -u--all 参数。

误区三:stash 只能存一次

错了。你可以无限次 stash,它会形成一个栈。stash@{0} 是最新的,stash@{1} 是上一条,以此类推。

总结

Git Stash 是个被低估的功能。掌握这几个技巧,基本能覆盖 90% 的分支切换场景。

记住一个原则:stash 是临时手段,commit 才是正经事。

下次再遇到"改了一半要切分支"的情况,别再慌着 commit 半成品了。试试 stash,你会觉得世界清净很多。


你平时用 git stash 最多的是哪个场景?有没有什么独门小技巧?