如何撤销已经完成的 git rebase
rebase 完成后想撤销:git reflog 找到 rebase 前的分支顶端(通常是 rebase 动作记录上方的条目),git reset --hard <哈希> 恢复。rebase 不改写对象只新建提交,原历史在 reflog 窗口期内都可找回。
git reflog 是你唯一的后悔药,而且非常好用:rebase 前的分支顶端提交被 reflog 完整记录,找到它,git reset --hard <哈希> 即可把分支拨回 rebase 之前的状态。
恢复步骤
git reflog
# 找到 rebase 开始前的状态,形如:
# a1b2c3d HEAD@{5}: rebase (start): checkout main ← rebase 开始
# ...
# 9f8e7d6 HEAD@{10}: commit: rebase 前最后的提交 ← 要回到这里
git reset --hard 9f8e7d6
辨认技巧:reflog 里 rebase (start) 记录更早的条目(默认倒序输出时通常在 start 条目下方;必须再核对提交内容)就是 rebase 前的 HEAD。
还在 rebase 进行中?
那更简单,不用 reflog:
git rebase --abort # 中止并回到开始前
已经推送了 rebase 结果?
- 本地撤销后远程还是 rebase 后的历史:如果之前强推过,远程同样需要
--force-with-lease覆盖回去; - 有协作者已经拉取了 rebase 后的历史:通知他们重置本地,或者干脆接受现状。
常见问题(FAQ)
Q:reflog 记录会保留多久?
记录保留和对象清理由不同配置控制,应尽快恢复,不要把默认值当作保证窗口。
Q:reset --hard 会丢工作区改动吗?
会。执行前 git stash -u 把工作区收起来。
Q:能只撤销 rebase 里的某个操作吗(比如某个 squash)?
没有细粒度的"撤销单步"——reflog 恢复到 rebase 前,然后重新做一次正确的 rebase。