Git中如何临时保存当前分支改动并切换到其他分支工作?

文章导读
在分支上改到一半,突然需要切到另一个分支处理紧急问题,这是很常见的操作。只要改动还没有到可以提交的程度,用 git stash 可以先把当前工作区的改动收起来,处理完再恢复。下面整理一下我对这个流程的理解和操作习惯。
📋 目录
  1. 什么时候适合用 stash
  2. 恢复时先确认条目再操作
  3. 多条 stash 并存时的风险边界
  4. 容易忽略的检查点
  5. 另一种方案:临时提交
A A

在分支上改到一半,突然需要切到另一个分支处理紧急问题,这是很常见的操作。只要改动还没有到可以提交的程度,用 git stash 可以先把当前工作区的改动收起来,处理完再恢复。下面整理一下我对这个流程的理解和操作习惯。

什么时候适合用 stash

当你在一个分支上有未提交的改动,但需要立即切换到另一个分支处理紧急任务时,git stash可以在不提交的情况下暂时保存这些改动。通常的做法是在当前分支执行git stash push -m 描述信息,然后检查git status确认工作区干净。这时可以放心切换分支。注意stash默认不会保存未跟踪的新文件,如果希望包含这些文件,需要加上-u参数。

这个做法的好处是切换分支时不会因为未提交改动而报错,也不会把半成品提交到历史里。不过执行前最好先确认你确实需要保存当前改动,如果改动只是临时的调试输出,直接丢弃可能更省事。

恢复时先确认条目再操作

切换到工作分支后,可以使用git stash pop将之前保存的改动恢复到当前工作区。pop会应用最新的stash并自动删除它,而apply则保留stash记录,适合需要多次应用或确认无误后再清理的情形。恢复后如果出现冲突,需要手动解决,解决完后再执行git stash drop删除记录。建议用git stash list查看所有保存的条目,每次恢复前先确认该条目确实是当前所需要的。

这里说的“最新”指的是stash@{0},也就是最后保存的条目。如果你在多个分支之间切换过多次,stash list里会有多条记录。先git stash list看看有多少条,再决定用pop还是apply。如果不确定某条内容,可以用下面命令检查差异。

Git中如何临时保存当前分支改动并切换到其他分支工作?
git stash show -p stash@{0}

多条 stash 并存时的风险边界

stash并非一个无限容量的保存机制。当多个stash条目同时存在时,很容易混淆哪条对应哪次改动。建议每次保存时使用-m参数添加描述,恢复前用git stash show -p stash@{0}查看该条目的具体差异,确认确实是需要的改动后再操作。如果误删了stash条目,git官方没有直接的撤销命令,此时也许能从reflog中找回,但过程繁琐且不一定成功。

所以保存时写清描述很重要,比如 git stash push -m "登录页校验逻辑" 就比默认的 WIP on develop 更容易辨认。另外,stash 条目保存在仓库的 .git 目录里,如果仓库被重新克隆或者清理,这些条目也就丢了,不能把 stash 当成长期存储用。

容易忽略的检查点

切换分支前忘记查看当前分支的未跟踪文件,这些文件不会随stash保存,在切换后仍停留在工作区,可能与其他分支的文件产生干扰。所以执行 stash 之前,先用 git status 看看未跟踪文件是不是你需要的。如果需要一起保存,加上 -u 参数;如果不想要,也要提前备份再删。

Git中如何临时保存当前分支改动并切换到其他分支工作?

git stash还会忽略子模块的改动,处理子模块时需要单独操作。比如子模块里有新的提交,stash 不会保存它,切换分支后子模块会指向原提交,容易造成困惑。

另一个常见坑是在pop时遇到冲突,此时工作区进入冲突状态,不要盲目使用git reset --hard,这会丢失stash中的原始改动。正确做法是使用git status查看冲突文件,逐个解决;如果确认stash不适用于当前分支,可以先用git diff手动记录需要的部分,再放弃本次应用。

另一种方案:临时提交

除了stash,也可以临时创建一个提交来保存进度。在分支上执行 git add -A && git commit -m wip,然后切换分支,处理完后回到该分支,再执行 git reset --soft HEAD~1 取消提交。这个操作会保留工作区和暂存区的改动,适合需要让 git 记录一个完整中间状态的场景。但要注意,临时提交会出现在提交历史里,如果分支是共享的,不要直接推送,避免干扰其他开发者的提交记录。

相比之下,stash 更隐蔽,不产生提交历史记录;临时提交更稳定,还能把改动带到其他分支(比如用 cherry-pick)。但多数临时保存需求用 stash 就够了。