本地 commit 丢失后基本可找回:优先用 git reflog 查找操作记录,再用 git fsck --lost-found 扫描孤立提交;恢复时应先建分支保底、验证内容完整性,再谨慎合并或推送。

本地 commit 丢了,但没被 git gc 清掉,基本都能找回来——关键不是“能不能”,而是“从哪找”和“怎么确认找对了”。
用 git reflog 找最后一次 HEAD 指向的提交
这是最快、最常用的方式,适用于刚误删分支、git reset --hard 错了、或切错分支后丢提交的情况。Git 默认保留 reflog 30 天,只要没手动清理过 .git/logs/,记录就在。
操作要点:
- 运行
git reflog,输出类似abc1234 HEAD@{0}: reset: moving to HEAD~1或def5678 branch-name@{2}: checkout: moving from main to branch-name - 重点看带
@{n}的条目,尤其是你记得操作时间、分支名或关键词(如 “checkout”、“reset”、“commit”)的那一行 - 用
git show abc1234确认内容:是否含你丢的文件?作者/时间是否匹配?父提交是否连得上? - 别直接
git reset --hard,先git branch recovered-branch abc1234新建分支保底,再决定怎么合并
用 git fsck --lost-found 扫描 dangling commit
当 reflog 被清空、或你压根没注意过操作历史,就得靠对象数据库本身了。Git 不会立刻删掉孤立提交(dangling commit),它们还躺在 .git/objects 里,只是没人引用。
操作要点:
-
git fsck --lost-found输出里只关注dangling commit行,忽略tree和blob(除非你明确在找单个文件) - 每个
dangling commit哈希都值得查:git log --oneline -n 3 <hash></hash>看最近几条提交,git show <hash> --stat</hash>看改了哪些文件 - 如果目标提交是某个功能的起始点,它可能没有父提交(
git show <hash></hash>输出里无parent字段),这种要优先核对 - 恢复时别只建分支,用
git cherry-pick <hash></hash>往现有分支补提交更安全,避免引入意外的祖先链
确认恢复的是完整提交,不是半截状态
很多人找回哈希后直接 git reset --hard,结果发现文件少几个、或者某次冲突解决被覆盖了——这是因为游离提交(detached HEAD)下做的提交,本身不自动归属任何分支,而 fsck 找到的也可能是中间状态。
验证建议:
- 用
git log --all --oneline --graph --simplify-by-decoration看所有引用关系,确认新分支是否真正“接上”了原分支路径 - 针对关键文件,跑一次
git log --all --oneline -p -- <file-path></file-path>,比对修改行号、上下文,防止 cherry-pick 时漏掉部分 hunk - 如果原分支有 merge 提交,注意
git fsck找到的 dangling commit 很可能只是其中一个 parent,得用git show <hash></hash>查Merge:行来还原完整拓扑
reflog 是第一道防线,fsck 是兜底手段;但真正容易被忽略的是:恢复后别急着推送,先 git diff <original-branch>..recovered-branch</original-branch> 对比净变更,尤其当原分支后续还有其他人提交时——强行 push -f 可能覆盖别人的工作。











