从保存、查看、恢复到冲突处理与常见问题
Git 实用教程
大家好,我是 lazy,一名大二科班学生
前言
在日常开发中,经常会遇到这样的情况:当前功能只写了一半,突然需要切换到其他分支修复线上问题;或者准备执行 git pull,却因为本地存在未提交修改而无法继续。此时直接提交一个“做到一半”的版本不够规范,直接丢弃修改又会造成代码丢失。Git 提供的 git stash 命令正是用来解决这类问题的。
git stash 可以把工作区和暂存区中的未提交修改临时保存起来,让当前工作目录恢复到较为干净的状态。完成临时任务后,再把保存的修改恢复回来继续开发。本文将从基础使用、常用参数、apply 与 pop 的区别、指定记录恢复、冲突处理以及常见问题等方面,完整讲清楚 git stash 的使用方法。
图 1 Git stash 的基本工作流程
一、git stash 是什么?
stash 可以理解为 Git 提供的“临时储物柜”。它不会把未完成代码正式写入当前分支的提交历史,而是把当前修改保存到本地的 stash 栈中。保存成功后,工作目录会回到接近当前 HEAD 提交的状态,因此可以安全切换分支、拉取远程代码或处理其他任务。
需要注意的是,stash 主要用于短期保存。长时间保留的重要工作,更适合创建独立分支并正常提交。stash 默认只存在于本地仓库,不会随着普通 git push 自动上传到远程仓库。
二、什么情况下适合使用 git stash?
最典型的场景是代码写到一半却必须临时切换任务。例如正在 feature/login 分支开发登录功能,突然需要回到 main 分支修复紧急问题。此时可以先 stash 当前修改,修复完成后再回到原分支恢复。
另一个常见场景是本地存在修改时需要执行 git pull。为了避免拉取过程覆盖或阻塞本地修改,可以先保存当前工作,拉取远程更新后再恢复。
此外,stash 还可以用于暂时移开无关修改、测试部分提交、只保存指定文件或将某组修改转移到另一个分支。
三、最基础的 stash 使用流程
开始前先查看当前仓库状态,确认有哪些文件被修改。
git status把当前已跟踪文件的修改和暂存内容临时保存。
git stashgit stash 与 git stash push 在基础场景下效果相同。保存完成后再次查看状态,通常可以看到工作区已经变干净。
git status此时可以切换分支或处理其他任务。完成后回到原分支,再恢复最近一次保存的修改。
git stash pop这就是最常见的完整流程:先保存、再切换、最后恢复。
四、推荐使用 git stash push 并添加说明
当 stash 记录较多时,如果所有记录都只有默认的 WIP 描述,很难快速判断每条记录保存了什么。建议使用 git stash push,并通过 -m 添加清晰说明。
git stash push -m "登录接口开发到一半"说明应简短描述当前任务,例如“修复支付回调前临时保存”“拉取主分支前保存本地修改”。这样以后查看列表时更容易找到正确记录。
旧写法 git stash save 目前仍可能可用,但官方文档已经将其标记为不推荐,新的教程和项目应优先使用 git stash push。
五、查看已有的 stash 记录
使用下面的命令可以查看当前仓库中所有 stash 记录。
git stash list输出通常类似下面这样。
stash@{0}: On feature/login: 登录接口开发到一半 stash@{1}: On main: 拉取远程代码前临时保存 stash@{2}: WIP on feature/order: a38f921 新增订单查询stash@{0} 表示最近一次保存,stash@{1} 表示倒数第二次,数字越大代表记录越早。每新增一条 stash,原来的编号可能向后移动,因此执行删除或恢复前最好先重新运行 git stash list。
六、查看 stash 中具体保存了什么
只查看最近一次 stash 的修改统计。
git stash show查看最近一次 stash 的完整代码差异。
git stash show -p查看指定 stash 的完整差异。
git stash show -p stash@{1}在 Windows PowerShell 中,如果 stash@{1} 被错误解析,可以给它加上引号。
git stash show -p "stash@{1}"恢复前先使用 show 检查内容,是避免选错记录的好习惯。
七、git stash apply 和 git stash pop 的区别
两者都会把 stash 中的修改恢复到当前工作区,但处理 stash 记录的方式不同。
git stash apply 只恢复修改,不删除原记录。它适合不确定恢复是否顺利、需要在多个分支重复应用,或者希望先保留备份的场景。
git stash applygit stash pop 会恢复修改,并在恢复成功后删除对应的 stash 记录。它适合确认要立即继续原工作的一般场景。
git stash pop如果 pop 过程中发生冲突,Git 通常不会删除该 stash 记录。解决冲突后应重新查看 stash list,再决定是否手动 drop。
图 2 apply 与 pop 的区别
八、恢复指定的 stash 记录
不指定记录时,apply 和 pop 默认处理 stash@{0}。需要恢复较早的记录时,应明确写出编号。
git stash apply stash@{2}使用 pop 恢复指定记录。
git stash pop stash@{2}在 PowerShell 中也可以加引号。
git stash apply "stash@{2}"恢复指定记录之前,建议先执行 git stash list 和 git stash show -p,确认编号和内容。
九、恢复暂存区原来的状态
普通 apply 或 pop 会恢复文件内容,但之前已经 git add 的文件不一定仍保持暂存状态。需要同时尝试恢复暂存区状态时,可以添加 --index。
git stash apply --index也可以对指定记录使用。
git stash apply --index stash@{1}如果当前索引状态与保存时差异较大,--index 可能发生冲突。此时应根据实际情况解决冲突,不能机械地反复执行命令。
十、删除 stash 记录
删除最近一条 stash。
git stash drop删除指定记录。
git stash drop stash@{1}删除全部 stash 记录。
git stash clearclear 的影响范围很大,执行后正常命令无法直接找回全部记录。操作前务必先运行 git stash list,确认其中没有需要保留的内容。对于重要工作,不要把 stash 当作唯一备份。
十一、默认为什么没有保存新文件?
默认执行 git stash 时,Git 通常只保存已跟踪文件的修改以及暂存区内容。新创建但从未 git add 的未跟踪文件不会自动进入 stash。
同时保存未跟踪文件,可以使用 -u 或 --include-untracked。
git stash push -u -m "包含新文件的临时修改"如果连 .gitignore 中明确忽略的文件也要一起保存,可以使用 -a 或 --all。
git stash push -a -m "包含忽略文件的完整临时保存"-a 可能把日志、构建产物、缓存和本地配置一并保存,体积可能很大,使用前应确认确实有必要。
十二、只保存未暂存的修改:--keep-index
有时已经把准备提交的修改加入暂存区,但工作区还有另一部分未完成修改。此时可以使用 --keep-index,把其他修改放入 stash,同时保留已经暂存的内容,方便测试并提交当前这一部分。
git stash push --keep-index -m "保存未暂存的其他修改"之后可以测试暂存区中的代码并完成提交,再恢复剩余工作。
git commit -m "完成第一部分功能" git stash pop执行前应通过 git status 明确区分“已暂存”和“未暂存”的文件,避免误解命令效果。
十三、只保存已暂存的修改:--staged
与 --keep-index 相反,--staged 用于只保存已经加入暂存区的修改,其他未暂存修改继续保留在工作区。
git stash push --staged -m "临时保存已暂存修改"这个功能适合把一组已经挑选好的改动暂时移开,继续完成当前工作,再到合适的分支恢复。
十四、交互式选择部分修改:--patch
一个文件中可能同时包含两类修改,但只想保存其中一部分。使用 --patch 后,Git 会逐段询问是否将当前代码片段放入 stash。
git stash push --patch常见选择包括 y 表示保存当前片段,n 表示保留当前片段,q 表示退出。使用前建议先运行 git diff 熟悉修改内容。
git diff该方式非常灵活,但不熟悉交互式选择时应谨慎操作。
十五、只 stash 指定文件或目录
不想保存全部修改时,可以在双横线后写出指定路径。
git stash push -m "只保存用户服务修改" -- src/main/java/com/example/UserService.java保存指定目录。
git stash push -m "只保存订单模块" -- src/main/java/com/example/order双横线用于明确后面的内容是文件路径,能够避免路径被误认为命令选项。
十六、从 stash 创建新分支
如果 stash 保存后,原分支已经发生大量变化,直接 apply 可能产生很多冲突。git stash branch 会从创建 stash 时所在的提交创建新分支,再把 stash 应用到新分支。
git stash branch feature/continue-login stash@{0}应用成功后,对应 stash 通常会被删除。这个方法适合保存时间较久、原分支变化较大,或者本来就希望把这组修改转移到独立分支的情况。
十七、stash 恢复发生冲突怎么办?
当当前分支和 stash 修改了同一文件的同一位置时,apply 或 pop 可能产生冲突。先查看冲突文件。
git status打开文件,处理 Git 标记的冲突区域,保留正确代码并删除冲突标记。完成后把文件加入暂存区,表示冲突已经解决。
git add <冲突文件>如果使用的是 git stash pop 且发生冲突,stash 记录一般仍会保留。解决后先重新查看列表。
git stash list确认已经不再需要该记录后再手动删除。
git stash drop stash@{0}不要在冲突尚未解决时直接清空 stash,否则可能失去最后的恢复依据。
图 3 stash 冲突处理流程
十八、常见实战场景
场景一:代码写到一半,临时切换到 main 修复问题。
git stash push -u -m "登录功能开发到一半" git switch main修复完成后回到原分支并恢复。
git switch feature/login git stash pop场景二:本地有修改,但需要先拉取远程代码。
git stash push -u -m "拉取远程代码前临时保存" git pull git stash pop场景三:误在错误分支开发,准备把修改转移到新分支。
git stash push -u -m "转移到正确分支" git switch -c feature/correct-branch git stash pop十九、常见问题与解决方法
1. 执行 stash 后提示 No local changes to save:说明当前没有可保存的已跟踪修改。先运行 git status;如果只有未跟踪文件,应使用 -u。
git status git stash push -u -m "保存未跟踪文件"2. pop 后 stash 为什么还在:通常是恢复过程中发生冲突,Git 为避免丢失记录而没有自动删除。解决冲突后手动 drop。
3. stash 能不能在另一个分支恢复:可以,但如果目标分支代码差异较大,可能出现冲突。风险较高时使用 git stash branch。
4. stash 会不会被推送到 GitHub 或 Gitee:普通 git push 不会上传本地 stash 列表。需要跨电脑或团队共享的工作,应创建分支并提交。
5. clear 或 drop 后还能恢复吗:有时底层对象尚未清理,仍可能通过高级方式寻找,但不保证成功。最可靠的做法是执行前确认记录,重要代码及时提交到分支。
6. stash 记录太多容易混乱:每次使用 -m 添加说明,恢复后及时 drop,不要把 stash 当作长期任务列表。
二十、git stash 与 git commit 应该怎么选?
stash 适合几分钟、几小时或短时间内的临时切换。它不会形成正常的分支提交历史,使用方便,但可追踪性和可共享性较弱。
commit 适合已经形成明确阶段成果、需要长期保存、回顾或团队共享的代码。即使功能尚未完成,也可以在独立功能分支中提交清晰的阶段性版本。
简单判断方法是:马上回来继续写,可以使用 stash;可能隔很久、代码很重要或需要发给别人,应创建分支并 commit。
二十一、常用命令速查表
保存当前已跟踪修改。
git stash保存并添加说明。
git stash push -m "说明"包含未跟踪文件。
git stash push -u -m "说明"查看记录。
git stash list查看完整差异。
git stash show -p stash@{0}恢复但保留记录。
git stash apply stash@{0}恢复并在成功后删除记录。
git stash pop stash@{0}删除指定记录。
git stash drop stash@{0}删除全部记录。
git stash clear从 stash 创建分支。
git stash branch feature/new-work stash@{0}总结
git stash 的核心用途是临时保存未提交修改,让工作区恢复到可以安全切换任务的状态。日常开发中最需要掌握的是 git stash push、git stash list、git stash show、git stash apply、git stash pop 和 git stash drop。
使用时应记住三个原则:第一,新文件需要 -u 才会被保存;第二,apply 会保留记录,pop 成功后会删除记录;第三,stash 只适合短期周转,重要代码应及时创建分支并提交。掌握这些命令后,遇到紧急切换分支、拉取代码受阻或错误分支开发时,就能更加安全地处理本地修改。
参考资料
- Git 官方文档:git-stash Documentation(打开官方页面)
- Pro Git 中文版:贮藏与清理(打开官方页面)