执行git stash push后修改丢失是什么原因?如何恢复丢失的改动?
问题原因
该问题不是git stash丢了内容,核心是两类常见的操作时序和默认规则问题:
- Jupyter Notebook、VSCode这类编辑器存在磁盘写入缓存,你点击保存按钮后,改动不一定会立刻完整刷入磁盘,执行
git stash push时git读取到的仍是旧版本文件内容,因此stash本身存储的就不是你预期的最新改动。 git stash默认不会暂存未被git追踪的新增文件,如果你改动涉及未执行过git add的新文件,这部分内容不会被存入stash。
恢复方案
按照恢复成功率从高到低排序:
- 从编辑器备份恢复
- Jupyter自带检查点自动备份:打开对应笔记本,依次点击「文件」-「恢复检查点」,可选择最近的自动备份版本,绝大多数情况下你的两小时改动会存在检查点中。
- VSCode本地历史恢复:右键项目中的
notebook.ipynb文件,选择「本地历史记录」,可看到所有近期修改快照,直接恢复到执行stash前的版本即可。
- 找回被删除的stash内容
你贴出的git stash pop输出中已经给出了被丢弃的stash的commit哈希:a9044f83c9bf2ef48182c8fbe0715dbabaa2f4fd,git默认不会立刻清理掉被drop的stash对象,执行以下命令即可恢复该stash的内容:
执行后可核对文件内容,如果确实是你需要的版本,可以重新提交或者重新stash。git stash apply a9044f83c9bf2ef48182c8fbe0715dbabaa2f4fd - 从git悬空对象恢复
如果上述操作都没有找到内容,执行以下命令扫描git未关联的悬空commit对象,可能会找到你未存储的改动:
扫描结果中所有dangling commit对应的哈希都可以用git fsck --lost-foundgit show <哈希>查看内容,确认是需要的版本后用git cherry-pick <哈希>即可恢复。
规避建议
- 执行任何git暂存、切换分支操作前,先运行
git status确认git识别到的改动范围和你预期完全一致,再执行后续操作。 - 需要暂存未追踪的新文件时,给stash命令加
-u参数:git stash push -u -m "备注内容"。 - 执行
git stash pop后先核对文件内容符合预期再执行commit操作,避免把错误版本提交到分支。 - 处理Jupyter这类不易做增量对比的文件时,建议每30分钟左右做一次小commit,或者手动导出备份副本,不要攒数小时的改动再做版本操作。
内容的提问来源于stack exchange,提问作者philosofool
相关产品推荐
相关产品推荐

