Undo a Git merge that hasn't been pushed yet

Undo a Git merge that hasn’t been pushed yet

技术背景

在使用 Git 进行版本控制时,合并(merge)操作是常见的工作流程之一。然而,有时会因为各种原因(如错误的分支合并、合并后发现冲突难以解决等)需要撤销尚未推送到远程仓库的合并操作。了解如何撤销这类合并操作,对于高效的代码管理至关重要。同时,理解 Git 中的 HEAD 概念是掌握撤销合并操作的基础,HEAD 是指向当前分支最新提交的引用。

实现步骤

1. 使用 git reflog 查找合并前的提交

1
git reflog

通过该命令可以查看 HEAD 的引用日志,从中找到合并前的提交哈希值(commit_sha)。然后使用以下命令重置:

1
git reset --hard commit_sha

2. 使用 git reset --hard HEAD~1 回退一个提交

1
git reset --hard HEAD~1

此命令会将 HEAD 回退一个提交,撤销最近的合并操作。但要注意,任何已修改但未提交或未暂存的文件将被重置为未修改状态。

3. 使用 git reset --hard ORIG_HEAD 恢复

1
git reset --hard ORIG_HEAD

ORIG_HEAD 指向合并操作发生前的提交,使用该命令可以直接回到合并前的状态,并且可能会保留你的修改。

4. 使用 git reset --merge ORIG_HEAD 更安全地恢复

1
git reset --merge ORIG_HEAD

该命令不会不必要地重置文件,它会重置索引并更新工作树中与指定提交不同的文件,但会保留索引和工作树之间不同的文件(即未添加的更改)。

5. 合并冲突时使用 git merge --abort

如果在合并过程中出现冲突,且尚未提交合并结果,可以使用以下命令中止合并:

1
git merge --abort

该命令会尝试重建合并前的状态。

核心代码

撤销未提交的合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 使用 reflog 查找合并前提交并重置
git reflog
git reset --hard commit_sha

# 回退一个提交
git reset --hard HEAD~1

# 使用 ORIG_HEAD 恢复
git reset --hard ORIG_HEAD

# 更安全地使用 ORIG_HEAD 恢复
git reset --merge ORIG_HEAD

# 合并冲突时中止合并
git merge --abort

其他相关操作

1
2
3
4
5
# 重置到远程分支
git reset --hard origin/<branch-name>

# 撤销已推送的合并
git revert -m 1 commit_hash

最佳实践

  • 使用 git reflog 辅助操作:在不确定合并前的提交位置时,git reflog 是一个非常有用的工具,它可以记录 HEAD 的所有变更历史,帮助你准确找到合并前的提交。
  • 使用 --merge 选项:当需要撤销合并并保留未提交的更改时,优先使用 git reset --merge ORIG_HEAD 命令,避免不必要的文件重置。
  • 处理合并冲突:在合并过程中遇到冲突时,及时使用 git merge --abort 中止合并,避免问题进一步复杂化。

常见问题

1. 未提交的更改丢失

使用 git reset --hard 命令会丢弃所有未提交的更改。为了避免这种情况,可以在执行重置操作前使用 git stash 暂存更改,重置完成后再使用 git stash pop 恢复更改。

1
2
3
git stash
git reset --hard commit_sha
git stash pop

2. git merge --abort 无法使用

git merge --abort 仅在合并产生冲突且 MERGE_HEAD 存在时有效。当合并失败且没有 MERGE_HEAD 时,可以使用 git reset --merge 来撤销合并。

3. 本地分支与远程分支分歧

在使用 git reset --hard 回退提交后,可能会导致本地分支与远程分支出现分歧。此时可以使用 git pull 命令将远程分支的更新拉取到本地,使本地分支与远程分支保持一致。

1
2
git reset --hard HEAD^
git pull

Undo a Git merge that hasn't been pushed yet
https://119291.xyz/posts/2025-05-08.undo-a-git-merge-that-hasnt-been-pushed-yet/
作者
ww
发布于
2025年5月8日
许可协议