git reset --hard、误删分支、rebase 改乱了历史……这些操作看起来像是把提交“弄丢了”,但多数情况下提交对象仍在仓库里,只是没有分支或标签指向它。本文介绍用 reflog 找回它们的方法,以及哪些情况无法恢复。
reflog 记录本地仓库中 HEAD 和各分支引用的每一次移动,包括 commit、checkout、reset、rebase、merge 等。它只存在于本地,不会随 push 同步,默认保留一段时间(未被引用的条目默认约 30 天,可达条目约 90 天,由 gc.reflogExpire 等配置决定)。
git reflog
# 或查看某个分支
git reflog show feature/login输出中每行形如 abc1234 HEAD@{3}: reset: moving to HEAD~2,HEAD@{n} 就是可以回到的位置。
假如执行了 git reset --hard HEAD~3,最近 3 个提交从分支上消失了:
git reflog # 找到 reset 之前的那一条,例如 HEAD@{1}
git reset --hard HEAD@{1} # 回到 reset 前的状态更稳妥的做法是先建分支保存,再决定怎么处理:
git branch rescue HEAD@{1}git branch -D feature/x 删除后,分支上独有的提交没有任何引用,但对象还在:
git reflog # 找到删除前该分支最后一次提交的哈希
git branch feature/x <哈希> # 重新创建同名分支如果不确定哪个哈希是对的,可以逐个 git show <哈希> 查看提交内容。
rebase 之前的分支末端会记录在 reflog 里,也可以使用 ORIG_HEAD:
git reset --hard ORIG_HEAD注意:ORIG_HEAD 会被后续的危险操作覆盖,所以出问题后应立刻使用,或者先查 reflog 确认。
git stash drop 或 git stash clear 之后,可以用 fsck 找悬空提交:
git fsck --no-reflog | grep 'dangling commit'
git show <哈希>
git stash apply <哈希>git add、也没有提交的内容,被 reset --hard 或 checkout -- . 覆盖后,Git 里没有记录,通常无法找回。已经 git add 过的文件,可能还留有 blob 对象,可以尝试 git fsck --lost-found。git gc 后,对象会被真正删除。git branch backup-$(date +%F)。git reset --keep 或 git stash 代替 --hard,必要时先 git status 确认。git push --force-with-lease,避免覆盖他人的提交。想做的事 | 命令 |
|---|---|
查看操作历史 |
|
回到某次操作之前 |
|
找回已删分支 |
|
撤销刚才的 rebase/merge |
|
找回悬空提交 |
|
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。