误用 git reset –hard 后还能找回提交吗?

5 人参与

先说个让人松口气的结论:如果那次 git reset --hard 之前你确实提交过,提交大概率还能捞回来;但如果被 reset 掉的是没有提交的改动,那基本就没什么指望了。这两种情况的差别特别大,我见过太多人混在一起慌。

误用 git reset --hard 后还能找回提交吗?

能捞回来的,是提交

Git 其实比你想象中更念旧。git reset --hard 只是把当前分支的指向往后挪了,那些提交对象本身并没有被立刻删掉,它们只是暂时“没人引用”。Git 会记录 HEAD 和分支的移动历史,一般靠 git reflog 就能翻出来。

我一般的做法是:先停下来,别乱敲命令,git reflog 看一眼最近的操作记录,找到 reset 之前那条记录,记下它对应的提交号;然后确认一下当前工作区有没有需要保留的东西,必要时先备份;最后用 git reset --hard <那个提交号> 把分支指回去。如果想更稳一点,也可以先建个临时分支指向那个提交,确认内容没问题再决定怎么合并。

这里有个容易犯的错:看到 reflog 里一堆记录,急着执行 reset,结果又把刚改的东西盖掉了。reset --hard 是真的硬,它同时覆盖暂存区和工作区,不会问你一句“确定吗”。所以第二次动手前,备份这件事不能省。

捞不回来的,是没提交的东西

这一点得说清楚:git reflog 记录的是引用移动,不是文件内容。你写了一半没 git add 的代码,或者只存在于暂存区、工作区的修改,被 reset --hard 覆盖之后,Git 里没有任何副本可找。编辑器本地历史、系统备份也许能救一部分,但那属于运气,不属于 Git 的能力。

所以真正的分界线不是“我有没有用错命令”,而是“这些东西有没有进过提交”。进去了,就有痕迹可循;没进去,Git 也帮不了你。

我现在养成的习惯很土但管用:做任何带 --hard 的操作前,先 git status 扫一眼,看看有没有还没提交的脏东西;如果只是想丢掉工作区里那部分乱改的内容、又不想动暂存区,那就别用 reset --hard,git restore 之类的定向操作足够,范围小,误伤也小。真出了事,先别继续敲命令,先看 reflog,再动手。

参与讨论

5 条评论
  • 长须公

    git restore 确实比 reset –hard 温和多了

  • 河马胖胖

    reflog 的记录会不会过期?

  • 幽灵灯影

    所以说勤提交才是好习惯

  • 小无声

    没提交的那部分真救不回来,血泪教训

  • 荷花初绽

    上次误删就是靠 reflog 捞回来的

❯
个人中心
购物车
优惠劵
有新私信 私信列表
搜索