高墙之外❤️

git stash 教程:从临时保存到冲突恢复

更新于 2026-10-25 · passwall.shop

简答:先运行 git status 确认改动,再用 git stash push -m 保存未完成工作;切换分支后用 git stash list 找到记录,优先用 git stash apply 恢复并保留备份,确认无误后再 drop。未跟踪文件要加 -u,忽略文件要加 -a。

定义:git stash 是 Git 用来暂时保存工作区和暂存区未提交修改、让当前目录恢复干净状态,并在之后重新应用这些修改的命令。

先记住这条最快操作路径

如果你只是想暂时收起当前修改、切换分支处理其他工作,可以按下面顺序执行。官方文档说明,git stash 不带参数时等价于创建一次新的 stash,推荐使用带说明的 git stash push,便于之后识别。

git status
git stash push -m "暂存当前未完成工作"
git status
git switch 目标分支

# 查看已有 stash
git stash list

# 恢复最近一条,并保留 stash 记录
git stash apply stash@{0}

# 确认代码恢复无误后,再删除记录
git stash drop stash@{0}

官方 Git 教程将 stash 描述为一个保存未完成修改的栈;它适合临时切换分支,不等同于正式提交,也不会随着普通 git push 自动上传到远程仓库。可参考Git 官方《贮藏与清理》。

常用命令速查
目的命令结果
创建临时保存git stash push -m "说明"保存修改并清理工作区
查看记录git stash list按最近创建顺序列出 stash
查看差异git stash show -p stash@{0}查看指定 stash 的补丁内容
恢复但保留记录git stash apply stash@{0}应用修改,不删除 stash
恢复并尝试删除git stash pop stash@{0}应用修改后尝试删除 stash
删除一条git stash drop stash@{0}删除指定 stash
清空全部git stash clear删除所有 stash,操作前需确认

git stash 会保存哪些修改

默认情况下,stash 主要保存已跟踪文件的工作区修改和暂存修改。新建但尚未被 Git 跟踪的文件不会默认进入 stash;被忽略的文件也不会默认进入。需要根据文件状态选择参数。

文件状态与参数对照
文件状态默认是否保存需要的命令
已跟踪但未暂存的修改是git stash push
已暂存的修改是,但恢复时不一定自动回到暂存区恢复时加 --index
未跟踪文件否git stash push -u
被忽略文件否git stash push -a
只保存部分改动按交互选择git stash push -p
只保存某个文件只处理指定路径git stash push -- path/to/file

-u 是 --include-untracked 的缩写,-a 是 --all 的缩写。官方文档明确区分了未跟踪文件与被忽略文件,因此不要只看到工作区变干净,就默认认为所有文件都已经保存。

如果担心遗漏,先运行:

git status --short
git stash show --stat stash@{0}

需要更细地查看内容时,可以使用:

git stash show -p stash@{0}
git stash show -u -p stash@{0}

命令格式和选项可在Git 官方 git-stash 文档中核对。

apply、pop、drop 到底有什么区别

最容易出错的地方是把 apply 和 pop 当成同一个命令。它们都会尝试恢复 stash,但处理 stash 记录的方式不同。

apply、pop、drop 对照
命令是否恢复修改是否删除 stash适合场景
apply是否第一次恢复、跨分支恢复或担心冲突
pop是通常在应用成功后删除确认目标分支和工作区适合直接恢复
drop否是确认内容已恢复或不再需要
clear否删除全部确认所有临时记录都不再需要

稳妥流程是先用 apply,检查 git status 和差异,确认结果正确后再执行 drop。使用 pop 时,如果应用过程发生冲突,Git 不一定会删除对应 stash,因此应重新运行 git stash list 核对记录,不要仅凭终端输出猜测。

如果原来的暂存状态也需要恢复,使用:

git stash apply --index stash@{0}

官方教程说明,普通恢复会重新应用文件修改,但原先处于暂存区的内容不一定自动重新暂存;--index 用于尝试恢复这一状态。

切换分支、指定文件与部分改动的实战

场景一:临时切换分支

当前分支有半成品修改,但需要去处理紧急任务时:

git status
git stash push -u -m "保存当前开发中的修改"
git switch hotfix
# 处理紧急任务并完成提交
git switch 原分支
git stash list
git stash apply stash@{0}

加入 -u 是为了把未跟踪文件也纳入保存范围。如果你明确不需要保存新文件,则可以省略该参数。

场景二:只保存某个文件

当工作区同时改了多个文件,但只想暂时收起其中一个,可以在命令末尾使用路径参数:

git stash push -m "暂存配置文件" -- config/app.yml

路径参数前的 -- 用于区分选项和文件路径。不同 Shell 对特殊字符的处理可能不同,文件名含空格时建议使用引号。

场景三:只保存部分代码块

如果同一个文件里既有想保留的修改,也有不想暂存的修改,可以使用交互模式:

git stash push -p -m "只暂存已完成代码块"

终端会逐段询问是否保存。常见选择包括保存当前代码块、不保存、退出、查看帮助等;第一次使用时应逐段确认,避免把未完成部分一起收起。

场景四:只保存已暂存内容

如果已经用 git add 标记了部分内容,只想把这些内容放进 stash,可以使用:

git stash push --staged -m "暂存已确认的修改"

官方命令参考将 --staged 定义为只保存当前已经暂存的修改;如果同时使用 --patch,应以交互选择逻辑为准。

恢复时冲突怎么处理

stash 可以应用到创建它时以外的分支。如果目标分支的同一文件已经发生变化,应用时可能出现合并冲突。这不代表 stash 立即丢失,但需要按普通 Git 冲突流程处理。

  1. 先查看冲突文件:git status。
  2. 打开冲突文件,处理 <<<<<<<<、=======、>>>>>>> 标记。
  3. 确认内容后执行 git add 文件名,表示该文件冲突已解决。
  4. 再次运行 git diff --check 和测试命令。
  5. 如果使用的是 apply,确认无误后再决定是否 git stash drop。
git stash apply stash@{0}
git status
# 手动编辑冲突文件
git add path/to/conflicted-file
git diff --check
git stash list

如果恢复目标不明确,或者原分支已经变化很多,可以考虑从 stash 创建新分支:

git stash branch recover-work stash@{0}

该方式会尝试基于创建 stash 时的提交建立新分支,再应用对应修改,适合想把旧工作单独拿出来继续处理的情况。官方教程也将 git stash branch 列为恢复复杂 stash 的方式。

什么时候不该使用 git stash

git stash 适合短时间、临时性的工作切换,但不适合拿来长期保存重要成果。stash 默认保存在本地仓库的引用中,不能替代正式提交、远程备份或团队协作记录。

临时保存方式选择
情况更适合的方式理由
只离开几分钟处理其他分支git stash快速清理工作区,稍后恢复
工作已形成可解释的阶段成果临时提交有提交记录,便于比较和回退
需要长期独立开发新建分支让工作有明确边界
需要同时维护多个工作目录git worktree减少频繁收起和恢复修改
需要团队成员接手正式提交并推送stash 不会自动进入远程协作流程

如果修改已经重要到不能依赖本地临时记录,优先创建正式提交或分支。使用 git stash clear 前也要先执行 git stash list 与 git stash show -p,因为清空后不适合再把它当作常规恢复手段。

一套不容易丢代码的检查清单

  1. 保存前运行 git status --short,记录已修改、已暂存和未跟踪文件。
  2. 需要保存新文件时使用 -u,需要包含忽略文件时才使用 -a。
  3. 创建 stash 时使用 -m 写清楚任务和文件范围。
  4. 恢复前先运行 git stash list,不要默认最近一条就是目标记录。
  5. 第一次恢复优先使用 apply,确认无误后再删除。
  6. 恢复后运行 git status、git diff 或测试命令。
  7. 发生冲突时先保留 stash 记录,处理并验证完成后再决定是否删除。
  8. 重要修改不要长期停留在 stash 中,及时转为提交、分支或其他可追踪记录。

这套流程的核心不是记住所有参数,而是始终做到“保存前确认范围、恢复后检查结果、删除前再次核对”。

常见问题

git stash 和 git commit 有什么区别?

git stash 是本地临时保存,用于快速清理工作区并稍后恢复;git commit 是正式记录,会进入项目历史。需要长期保留、分享或回退时,应优先使用提交或分支。

为什么 git stash 后新建文件还在?

因为未跟踪文件默认不会进入 stash。先用 git status 确认状态,再执行 git stash push -u;如果文件被忽略,需要使用 -a,并检查是否真的需要保存这些文件。

git stash pop 冲突后,stash 还在吗?

不能只凭命令习惯判断。冲突时先运行 git stash list 核对对应记录,再处理冲突;确认记录仍在后,不要重复执行 pop,避免再次尝试应用同一批修改。

如何恢复指定的 git stash?

先运行 git stash list,找到目标编号,例如 stash@{2},再执行 git stash apply stash@{2}。如果希望恢复原来的暂存状态,可以尝试加上 --index。

git stash apply 后如何撤销恢复的修改?

如果这些修改尚未与其他工作混合,可以先查看 git diff,再根据文件状态使用 git restore 或手动编辑。不要在没有确认范围时直接执行清理命令;重要内容应先复制或建立临时提交。

git stash clear 能恢复吗?

clear 会删除全部 stash 记录,不应当作为普通清理操作。执行前先用 git stash list 和 git stash show -p 核对;若已清空,恢复难度取决于本地对象是否仍可通过 Git 的历史对象和引用日志找到,不能保证一定恢复。

git stash save 还能不能用?

部分 Git 版本仍支持旧写法,但官方教程建议迁移到 git stash push,因为 push 支持路径限定等更明确的能力。新教程和新脚本优先使用 push。

参考资料

  1. Git 官方 git-stash 命令文档
  2. Git 官方《贮藏与清理》
  3. Git 官方《Git 是什么?》