Recovery
reset 过头后怎么恢复
当 reset 把分支、暂存区或工作区挪得太远时,先分清是哪一层变了,再用 reflog、ORIG_HEAD 或救援分支恢复。
- 正在处理 Git 误操作的人
- 想提前建立保守恢复习惯的协作者
- 先停手,不继续乱试命令
- 能执行 `git reflog`、`git status`、`git log --graph`
- 还没保住旧位置就继续 reset / rebase
- 在没判断影响面时直接改共享历史
数据 / 性能事实
- no deletereset moves a pointer; the orphaned commits stay in the object database until gc prunes them出处: git-reset(1) official manual
关键引语
Because git reset only moves branch pointers and never deletes commits, the previous tip is still in the reflog and can be restored with git reset --hard <reflog-sha>.
引用与延伸阅读
- Git reset [官方]
- Git reflog [官方]
- Git Tools Reset Demystified [书籍]
学完这篇你会掌握什么
- 理解 reset 过头后怎么恢复 的核心作用和适用场景
- 掌握 reset 过头后怎么恢复 的基本用法和常用参数
- 当 reset 把分支、暂存区或工作区挪得太远时,先分清是哪一层变了,再用 reflog、ORIG_HEAD 或救援分支恢复。
- 理解 先判断你到底丢了什么 相关的概念
- 掌握 最稳的第一步 相关的操作
- 知道在什么场景下使用该命令,什么场景下避免使用
先想一个问题
你刚刚在 Git 里做了一个操作,结果发现不是你想要的效果——甚至可能弄丢了提交。这种情况不是第一次了,你想建立一套可靠的方法来应对各种误操作场景。
先判断你到底丢了什么
git reset 最容易让人慌,是因为它可能同时影响三层状态:
- 分支和
HEAD指向哪里 - 暂存区里是什么
- 工作区文件长什么样
恢复前先别急着再执行更多命令。先看清到底是哪一层被改了。
最稳的第一步
git status
git log --oneline --graph --decorate -n 20
git reflog
这三步的意义不同:
status看工作区和暂存区log看当前分支现在指向哪reflog看它之前指向过哪
很多时候,“丢了提交”其实只是分支名字被挪走了。
常见三种情况
1. 只是想撤回提交,但工作区改动还想保留
这通常更接近 --soft 或 --mixed 的撤回场景。
如果你 reset 得比预期更远,可以直接从 reflog 找到原位置,再建一个救援分支:
git reflog
git switch -c rescue/reset HEAD@{1}
先把旧位置接住,再决定是否把当前分支移动回去。
2. 分支指针被挪走了,但提交还在
这是最常见的“看起来没了,其实还在”。做法通常是:
git reflog
git branch rescue/reset <old-commit>
如果确认那个旧提交就是你要找回的位置,再决定是否:
- 继续从救援分支整理
- 或把原分支重置回去
3. reset --hard 连工作区也覆盖了
这是最危险的场景。
如果改动从未进入过提交、stash 或别的引用,Git 不一定能帮你找回工作区文件内容。
但如果这些内容之前至少进入过某个提交,通常仍然可以借助 reflog 找回旧提交。
ORIG_HEAD 什么时候有用
Git 在部分高风险操作后会更新 ORIG_HEAD,它经常能帮你迅速回到操作前的位置。
git show ORIG_HEAD
git switch -c rescue/orig-head ORIG_HEAD
但不要把它当成永久救命绳。它更像“最近一次大动作前的位置”,而不是完整历史。
推荐的恢复顺序
- 停止继续
reset - 运行
git reflog - 用旧位置新建
rescue/*分支 - 再决定是
reset回去、cherry-pick,还是从救援分支继续整理
一个判断原则
如果你还没完全确认旧位置是否正确,不要直接把原分支硬挪回去。
先建救援分支,是这类事故里最便宜也最稳的动作。
给你的练习
- 在一个测试仓库中练习该命令的基本用法,观察执行前后的状态变化
- 尝试该命令的不同参数选项,对比输出结果的差异
- 模拟一个需要使用该命令的实际场景,完整走一遍操作流程
延伸阅读
沿着同一主题继续深入: