解决Git合并冲突并中止合并的方法

解决Git合并冲突并中止合并的方法

技术背景

在使用Git进行版本控制时,合并操作可能会产生冲突。当出现合并冲突时,我们可能需要中止合并操作,恢复到合并前的状态。同时,也可以根据具体需求选择保留某些更改。

实现步骤

恢复到最后一个“有效”提交

如果 pull 操作不成功,HEAD 是分支上最后一个“有效”提交。可以使用以下命令恢复:

1
git reset --hard HEAD

使用旧版本的“theirs”合并策略(已移除)

旧版本的Git允许使用“theirs”合并策略:

1
git pull --strategy=theirs remote_branch

但该策略已被移除。

替代方法

可以使用以下命令:

1
2
git fetch origin
git reset --hard origin

不同Git版本的中止合并方法

  • Git版本 >= 1.6.1:可以使用 git reset --merge
  • Git版本 >= 1.7.4:可以使用 git merge --abort
1
git merge --abort

注意,git merge --abort 只有在 MERGE_HEAD 存在时才等同于 git reset --merge

处理未提交的更改

如果在合并前有不想提交的更改,可以在合并前使用 git stash 暂存更改,合并完成或中止后使用 git stash pop 恢复更改。

1
2
3
git stash
# 合并操作
git stash pop

保留特定更改

  • 保留当前分支的更改:
1
git checkout --ours file1 file2 ...
  • 保留其他分支的更改:
1
git checkout --theirs file1 file2 ...

查看冲突文件的不同版本

对于冲突中的未合并文件,Git在索引中提供了文件的公共基础、本地和远程版本。可以使用 git show 查看:

1
2
3
4
5
6
# 公共基础版本
git show :1:_widget.html.erb
# 本地版本
git show :2:_widget.html.erb
# 远程版本
git show :3:_widget.html.erb

解决冲突并使用远程版本

1
2
git show :3:_widget.html.erb > _widget.html.erb
git add _widget.html.erb

或者,Git版本 >= 1.6.1 时:

1
git checkout --theirs _widget.html.erb

强制切换分支

如果合并冲突过多,且 HEAD 已被多次提交更改,可以强制切换到稳定分支:

1
2
git checkout -f master
git checkout side-branch

恢复单个文件到合并前状态

1
git reset *currentBranchIntoWhichYouMerged* -- *fileToBeReset*

创建测试分支避免合并问题

可以在合并前创建一个单独的测试分支,尝试合并操作。如果失败,可以放弃测试分支,在主题分支上解决冲突。

1
2
3
4
5
6
7
8
9
10
# 切换到主题分支
git checkout topic-branch-1
# 创建测试分支
git checkout -b test
# 尝试合并主分支
git merge master
# 如果失败,放弃合并
git merge --abort
git checkout -
git branch -D test

核心代码

以下是解决合并冲突和中止合并的核心代码汇总:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 恢复到最后一个“有效”提交
git reset --hard HEAD

# 替代旧的“theirs”合并策略
git fetch origin
git reset --hard origin

# 不同版本Git的中止合并
git merge --abort
git reset --merge

# 处理未提交更改
git stash
git stash pop

# 保留特定更改
git checkout --ours file1 file2 ...
git checkout --theirs file1 file2 ...

# 查看冲突文件不同版本
git show :1:_widget.html.erb
git show :2:_widget.html.erb
git show :3:_widget.html.erb

# 解决冲突并使用远程版本
git show :3:_widget.html.erb > _widget.html.erb
git add _widget.html.erb
git checkout --theirs _widget.html.erb

# 强制切换分支
git checkout -f master
git checkout side-branch

# 恢复单个文件到合并前状态
git reset *currentBranchIntoWhichYouMerged* -- *fileToBeReset*

# 创建测试分支
git checkout topic-branch-1
git checkout -b test
git merge master
git merge --abort
git checkout -
git branch -D test

最佳实践

  • 在进行合并操作前,确保没有未提交的更改,可以使用 git stash 暂存更改。
  • 当遇到合并冲突时,先尝试使用 git merge --abortgit reset --merge 中止合并,再分析冲突原因。
  • 可以创建测试分支,在测试分支上尝试合并操作,避免影响主题分支和主分支。

常见问题

  • git merge --abortgit reset --merge 的区别git merge --abort 只有在 MERGE_HEAD 存在时才等同于 git reset --merge。当没有 MERGE_HEAD 时,git reset --merge 可以撤销失败的合并,而 git merge --abort 不一定能实现。
  • 合并冲突后出现 .git/index.lock 文件:删除该文件(可以先备份到其他位置),然后再执行 git reset --hard HEADgit reset --hard origin 等操作。

解决Git合并冲突并中止合并的方法
https://119291.xyz/posts/2025-05-09.git-merge-conflict-resolution-and-abortion/
作者
ww
发布于
2025年5月9日
许可协议