Git School · FluxGit

用reflog恢复git reset --hard后的提交

FluxGit ·

这些代码块对应不同情况,不是一个完整脚本。请选择适合仓库的情况,并替换分支名、路径和VERIFIED_COMMIT。中止命令只适用于对应的正在进行的操作,不要执行两种备选方案。

简短答案

运行git reset --hard后,在reflog中查找之前的提交,核对内容,再创建恢复分支。前提是该提交对象仍然存在。

示例与前提

这套流程恢复已经提交的工作。只存在于工作目录、从未提交的编辑不会保存在reflog中。

修改前检查状态

先停止新的reset、rebase和分支切换。在移动引用之前,读取git reflog并通过git show检查内容。

git status --short
git reflog --date=iso
git show VERIFIED_COMMIT

保留引用或独立检出

在VERIFIED_COMMIT上创建rescue/lost-work,为找到的提交保留一个引用,不改变当前分支,也不覆盖工作文件。

git branch rescue/lost-work VERIFIED_COMMIT
git log -5 --oneline rescue/lost-work

第一种操作

检查恢复分支的历史和补丁。可以在另一个checkout中查看,或明确选择需要合并的修改。

有意选择另一种结果

直接reset到恢复的提交会再次改变分支、索引和文件。先保存当前修改,并建立恢复引用。

限制与例外

HEAD@{1}只是reflog中的位置,不保证就是正确提交。ORIG_HEAD可能保存之前的分支顶端,但其他操作可以覆盖它。

冲突与清理

reflog过期和对象清理遵循不同的可配置策略。即使旧记录还在,也无法重建已经删除的提交对象。

验证结果

核对恢复分支的提交、文件和历史。在整合修改之前运行相关测试。

git show --stat rescue/lost-work
git status --short

常见问题

git revert创建反向提交,不会把分支移回reset之前。对于仅暂存的内容,git fsck有时能找到blob,但不保证文件名和目录结构。

在FluxGit中审查操作

FluxGit的Safety Timeline汇集reflog移动和恢复点。功能开启且检测到本地修改时,受保护的reset路径可以保存安全stash;教程中的普通终端reset没有使用这层保护。

Git官方文档

Git School · 1:50

撤销 git reset --hard:找回丢失的提交

执行 git reset --hard 后,只要提交对象仍被保留,就可以通过本地 reflog 恢复已提交的更改。reflog 过期或对象被清理后,无法保证恢复。

撤销 git reset --hard:找回丢失的提交
旁白为英语。YouTube提供11种语言的手动字幕。此文字稿为简体中文。

在YouTube观看 — 在新标签页打开

在测试仓库中录制。

阅读旁白文字稿
  1. 00:03 你执行了 git reset --hard,最后一次提交不见了。这样的失误每个人都可能犯一次。下面介绍找回它的方法和原理。
  2. 00:12 首先,完成一项改动并提交:让支付调用重试两次。
  3. 00:19 然后,在终端中执行 git reset --hard HEAD~1。
  4. 00:24 FluxGit 立即检测到了变化。分支退回到之前的位置,那次提交已不在该分支上。
  5. 00:31 为什么它没有丢失?分支只是指向提交的标签。reset 把标签移回之前的位置,但提交仍在仓库中,Git 的日记 reflog 也仍然记录着它。在这个提交上创建一个分支,就能找回它。
  6. 00:47 FluxGit 中的 Recover lost work 用通俗的语言解释操作,并带你找到正确的位置。
  7. 00:59 Safety Timeline 用一句话显示这次 reset。从 reset 之前的时刻创建一个分支。
  8. 01:06 你的提交回来了,位于它自己的分支上。
  9. 01:10 未提交的改动不在 reflog 中。启用恢复点并检测到本地改动时,FluxGit 可以在 hard reset 前保存一个安全 stash。本例在终端中直接执行普通 Git reset,绕过了这项保护。
  10. 01:26 在终端中也一样:运行 git reflog,找到 reset 之前的那一行,然后在对应的提交上创建一个分支。
  11. 01:34 总结:reset 移动标签,reflog 记住标签原来的位置。创建分支来保留提交。下一课:恢复已删除的分支。

相关操作

下载FluxGit