Git stash pop 冲突后提示 The stash entry is kept
Git stash pop 发生冲突时会保留原条目。完成文件处理和暂存后,核对工作区、索引及 stash 内容,再决定是否单独 drop;再次 pop 不能代替继续操作。
执行 git stash pop 后,部分文件发生冲突,终端最后留下这一行:
The stash entry is kept in case you need it again.
即使已经编辑完冲突文件,这条 stash 仍在列表里。此时不要为了“继续”而再执行一次 pop:第一次操作已经尝试恢复修改,发生冲突后保留了原条目。接下来应完成当前文件的冲突处理,核对恢复内容;确认不再需要这份备份时,再单独删除对应条目。
本文处理的是 Git 普通工作仓库中,stash 已经开始应用并产生内容冲突的情况。若日志先报本地修改会被覆盖、未跟踪文件无法恢复,或者权限错误,应先处理对应失败,不能仅凭最后这行提示认定内容已经全部回到工作区。冲突时保留条目属于 pop 的正常行为。
保留的是备份,工作区仍可能已经改变
git stash pop 会尝试应用条目,并在成功后从 stash 列表移除它。遇到冲突时,自动删除这一步不会完成。git stash apply 则即使应用成功也保留条目。
这意味着“条目还在”和“没有恢复任何修改”不是同一回事。没有冲突的文件可能已经合并,冲突文件需要人工决定最终内容。Git 保留 stash,是让保存时的内容仍可供核对或重新恢复;它并不替你判断现在的解决结果是否正确。
在仓库根目录查看状态和条目:
git status --untracked-files=all
git stash list
关注状态中的未合并路径,例如 both modified、both added,以及暂存区、未暂存修改和未跟踪文件。不要只盯着编辑器里是否还显示冲突标记。
下文假设失败的 pop 对应当前最新条目 stash@{0}。如果当时指定了其他条目,请换成实际编号;期间新增或删除过 stash,也必须重新核对分支名、说明和内容。条目编号会随列表变化,旧截图里的 stash@{0} 不一定还是原来的那一份。引号用于保护带花括号的引用表达式。
解决当前冲突,不存在 stash 的 continue 步骤
先保留一份当前工作区中重要文件的副本,特别是 pop 之前已有的修改和这次手工解决的结果。原 stash 只保存创建它时纳入的内容,不能替代之后新增工作的备份。
逐个打开未合并文件,结合当前分支与暂存内容决定最终结果。文本冲突不能只删除标记而留下互相矛盾的两段代码;二进制文件、删除与修改冲突也可能没有可直接编辑的文本标记。
文件处理好后,按实际路径暂存。下面的路径是占位示例,应替换成已解决的文件;不要直接把整个目录加入暂存区:
git add -- path/to/resolved-file
如果最终决定删除该文件,应先确认工作区中的删除是你要的结果,再用同一个路径暂存该删除。git add 记录的是执行时的内容;暂存后又修改文件,需要重新检查并暂存最终版本。
Git stash 没有 --continue 子命令。冲突文件完成处理、索引中的未合并状态清除后,可以继续普通开发流程。无需用 git merge --continue 或 git rebase --continue 来结束这次 stash 应用;再次运行 pop 会尝试再应用一遍保存的修改。
stash 恢复的工作不要求立刻成为一个提交。可以继续编辑,也可以在检查完成后按项目流程提交;是否提交与是否保留 stash 是两个独立决定。
无未合并路径,只说明 Git 层面的冲突已处理
完成暂存后运行:
git diff --name-only --diff-filter=U
git diff --cached --check
git diff --check
git diff --cached
git diff
git status --untracked-files=all
第一条没有输出,表示当前没有列出的未合并路径。两条 --check 分别检查暂存和未暂存差异中的冲突标记及空白问题;它们不会验证业务逻辑。即使这些检查都通过,也还需要阅读差异,并运行项目已有的相关测试。
同时看 git diff --cached 与 git diff,是为了覆盖暂存区和工作区两部分。只看后一条可能漏掉刚用 add 标记为已解决的内容。未跟踪文件还要结合 status 单独查看,不能因差异列表没有它们就认定不需要保留。
再对照原 stash 的修改:
git stash show -p 'stash@{0}'
这份补丁以创建 stash 时的基础提交为参照;当前分支已经变化时,不应要求恢复后的差异与它逐行一致。要确认的是原来需要保留的修改是否仍在、冲突处是否按预期合并,以及没有冲突的文件有没有遗漏。
如果当初还保存了未跟踪文件,普通 show 的显示范围可能不足。应把这部分也纳入核对,具体查看方式见stash show 看不到未跟踪文件。尚未确认文件是否齐全时,保留条目即可,不要急着清理。
若 pop 时要求了 --index,还需检查原来已暂存与未暂存的划分。该选项尝试恢复索引状态,但冲突本身也要占用索引,不能假定原先的暂存布局已经完整恢复。
确认内容已有可靠保存后,再删除一条 stash
只有确认恢复内容完整、冲突结果正确,并且需要保留的工作已有提交或独立备份,才考虑清理原条目。再看一次列表与内容,确认目标仍是示例中的最新条目后,单独执行:
git stash list
git stash show -p 'stash@{0}'
核对无误再删除:
git stash drop 'stash@{0}'
drop 删除的是指定 stash 条目,不会替你提交或撤销当前工作区的修改。删除后再次查看列表,确认移除的是目标条目;其他条目的编号可能随之变化。不要用 git stash clear 代替,它会移除全部条目。
如果解决结果不满意,先保留当前文件、差异和原 stash,再根据 pop 前的备份恢复相应文件。不要把硬重置或清理未跟踪文件当作通用“取消 pop”:它们可能一并丢掉 pop 前已有的工作。stash 应用没有与 rebase 相同的整套继续、取消流程,保留原条目也不等于保存了操作前工作区的全部状态。
误删 stash 后,正常的 stash 列表无法直接找回它;即使底层对象暂时仍存在,也不能保证长期可恢复。对尚未核实的条目,延后删除比事后找回更可靠。


