- 正在处理 reset、rebase、删分支事故的人
Command Reference
git reflog
查看引用移动历史,是 reset、rebase、误删分支等恢复场景里最常用的自救命令之一。
- 知道 reflog 记录的是引用位置变化
- 愿意先查位置再动分支
- 把 reflog 当永久保险箱
- 看到旧位置后直接覆盖原分支而不先建救援分支
git reflog 记录的是引用移动历史,而不是普通提交历史。很多恢复操作首先要看的不是 git log,而是 reflog。
为什么它特别重要
当你做了这些操作后:
reset --hardrebasepull- 删除或改写分支
旧提交未必立刻消失,但你可能失去了“当前分支名”。这时 reflog 常常还能告诉你原来在哪里。
常见写法
git reflog
git reflog show HEAD
git reset --hard HEAD@{1}
git checkout -b rescue HEAD@{2}
实战思路
- 先用
git reflog找到误操作前的位置 - 再决定是新建救援分支,还是直接 reset 回去
位置历史
HEAD@{3}HEAD@{2}HEAD@{1}当前 HEAD
恢复动作
rescue/recover
和 git log 的区别
git log看的是提交图git reflog看的是引用曾经指向过哪里
所以 reflog 更像“位置历史”,不是“协作历史”。
风险提示
reflog 不是永久保险箱。随着时间推移和垃圾回收,过旧且不可达的对象可能被清理。所以出问题后越早处理越稳。
这条命令在流程里解决什么问题
git reflog 是一个纯只读的诊断工具,不修改任何提交或引用。它记录的是引用曾经指向过哪些位置,是恢复误操作后最重要的自救工具。它不会重塑历史,但能帮你找到历史被改之前的位置。
典型用例
- 执行
reset --hard后后悔了,用git reflog找到 reset 前的位置。 - 误删分支后,用 reflog 找到旧提交,重新建分支接住它。
- rebase 后发现历史不对,用 reflog 回到 rebase 前的状态。
- 用
HEAD@{N}语法直接引用 reflog 中的旧位置,比如HEAD@{1}表示上一个 HEAD 位置。
图例理解
引用名称(HEAD 或分支名)
引用移动时间线旧位置 hash操作描述
reflog 是纯只读操作,不会影响仓库历史。它是本地记录,不会被 push/fetch 同步。
特殊情况与边界
- reflog 是本地记录,不会被 push 或 fetch 同步到远端。每个人的 reflog 是独立的。
- reflog 条目有保质期:默认 unreachable 的引用保留 30 天,reachable 的保留 90 天。
git gc会清理过期条目。 git reflog expire --expire=now --all可以强制清理,但这是不可逆的。git reflog delete可以删除特定条目,但通常不需要手动管理。- 恢复操作的最佳实践:先用
git checkout -b rescue/...接住旧位置,再决定是否 reset。
跟着做一遍
这组练习的重点不是把仓库弄乱,而是体验“位置变了但对象可能还在”的恢复思路。
git switch -c lab/reflog-demo # 做两次提交 # 然后执行一次 git reset --hard HEAD~1跟着做
- 运行 `git reflog`,找到 reset 前的 HEAD 位置。
- 先用 `git checkout -b rescue/reflog HEAD@{1}` 把旧位置接住。
- 再用 `git log --oneline --graph --decorate --all` 对照现状。
- 你会看到 HEAD 的移动记录仍然保留在 reflog 里。
- 旧提交常常并没有立刻消失,只是当前分支不再指向它。
- 先建救援分支通常比直接 hard reset 更稳。
- 如果还没确认旧位置,就不要连续多次 reset 或 rebase。
- 不要把 reflog 当永久保险箱,出问题后越早接住旧位置越稳。
- 如果恢复动作会影响共享分支,先判断影响面再改引用。