科技 · 实用指南
Git stash pop 失败?清理前先核对已恢复的内容
同名文件可能阻止未跟踪文件恢复,但受跟踪文件的修改已经应用。先保全两个版本,确认准确的 stash,再比较恢复结果,最后决定是否删除。

Git 恢复 stash 时出错,并不能证明工作区毫无变化。眼下应先保全现状,弄清失败操作已经做了什么。在比较之前,把本地文件和 stash 中的同名文件视为两个独立版本。
1. 再次尝试前保留证据
保存完整错误、命令、Git 版本、分支、stash 列表及当前状态。查看 git status --short --untracked-files=all --ignored,以及未暂存和已暂存的差异。被忽略文件也要列出:普通状态看似干净,不代表没有被忽略的同名文件。改动路径前,独立保存有价值的本地文件和完整 Git 数据。普通克隆或导出的差异不会自动保全所有 stash 与未跟踪文件。
我们在使用 Git 2.51.1 的独立模拟仓库中,用 -u 保存一份受跟踪文件修改和一个未跟踪文件,然后在同一路径创建不同的本地内容。pop 返回代码 1:受跟踪文件修改已应用,本地同名文件未变,原 stash 仍在。这说明恢复可能只完成一部分,并不说明你的仓库发生了同样情况,也不是对所有版本的保证。
2. 确认 stash 并逐一分类冲突
从 git stash list 选择目标条目,使用 git rev-parse --verify,配合选中的 stash 引用及 ^{commit} 后缀,记录完整对象 ID。代入实际选择,不要默认最新条目就是目标。对记录的 ID 使用 git stash show --include-untracked --patch 检查;版本支持时还可用 --only-untracked --name-only。保留原条目,后续操作可能改变它的序号。
逐一对照错误路径、当前索引和文件:它现在是未跟踪、被忽略,还是本分支已跟踪的文件?创建 stash 时是否保存了它?路径的分类可能已改变。Atlassian 说明,保存的未跟踪内容在 stash 结构中单独存放,并非每个 stash 都有这一部分。确认实际保存的内容之前,不要直接套用第三父提交命令或覆盖方案。
3. 在受控位置恢复并比较
确认已经独立保全后,把有价值的本地同名文件移到恢复路径以外、标记清楚的位置,不要直接删除。再次应用 stash 前,要处理此前已应用的受跟踪文件修改;仅移动同名文件不会撤销这种部分恢复。如果工作区状态不确定,可在包含相关完整 Git 对象且检出状态干净的独立仓库副本中恢复,保留原仓库不动。
git stash branch 可从 stash 原始基点恢复工作,适用于当前分支已经推进的情况。遵循本机文档,在准备好的副本中使用不同的恢复分支。检出状态不干净时,操作可能受阻。以 stash@{n} 名称恢复成功后,条目可能被删除,因此事先保留原仓库和准确身份。将恢复的文件与保存的本地副本、此前已应用的受跟踪文件差异逐一比较,再明确取舍。
4. 单独核实删除条件
确认所需的受跟踪、未跟踪及被忽略内容;如果暂存状态重要,也要核对。运行预期构建或测试,记录各保留版本的位置及最终采用的差异。成功应用不代表最初保存了所有想要的文件。apply 会保留 stash;条目还在,并不意味着什么都没有恢复。
恢复验证通过后,只删除已确认当前名称与记录对象 ID 相符的条目。不要先执行大范围 git clean -xfd 或强制检出,它们可能抹掉比较所需内容。限定范围的 clean 预演只展示候选项,不会备份。找不到必要版本,或无法解释部分恢复结果时,继续保留证据与 stash,不应认定恢复完成。
