什么是 Git 中的合并冲突?如何处理合并冲突?


在现实世界中,当我们合并分支时,经常会遇到冲突。冲突发生的原因如下:

  • 当同一行代码在两个分支中以不同的方式更改时。

  • 在一个分支中更改了给定的文件,但在另一个分支中删除了该文件。

  • 在两个不同的分支中两次添加了相同的文件,但文件的内容不同。

在这些情况下,git 将停止合并过程,因为它无法确定如何合并更改。在这种情况下,我们需要手动干预并指示如何继续合并过程。

下图显示了两个分支masterfeature。文件hello.txt最初包含一行 Hello。初始提交后,由于它们具有单独的提交,分支已分叉。每次提交都修改了文件中同一行。

当我们尝试将更改从 feature 分支合并到 master 分支时,我们会遇到合并冲突错误,如第二个图所示。很明显,git 将无法确定要保留哪个提交,因为第二行在每个提交中都不同。因此,它将提示我们确认是否只想保留 master 分支的更改,或只想保留 feature 分支的更改,或保留 feature 和 master 分支的更改。

示例

让我们来看一下这个操作来理解合并冲突。

步骤 1 - 创建一个包含初始提交和hello.txt文件的仓库。

$ git init
Initialized empty Git repository in E:/tut_repo/.git/

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ echo hello>hello.txt

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git add .

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git commit -m 'hello.txt'
[master (root-commit) b6a745d] hello.txt
1 file changed, 1 insertion(+)
create mode 100644 hello.txt

步骤 2 - 创建一个新的分支 feature。切换到 feature 分支并通过编辑hello.txt文件中的第二行来创建一个新的提交。

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git branch feature

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git switch feature
Switched to branch 'feature'

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (feature)
$ echo hello feature >> hello.txt

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (feature)
$ git add .

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (feature)
$ git commit -m 'hello feature'
[feature a004fa4] hello feature
1 file changed, 1 insertion(+)

步骤 3 - 现在切换到 master 分支并通过向 hello.txt 添加新行来执行新的提交。

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (feature)
$ git switch master
Switched to branch 'master'

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ cat hello.txt
hello

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ echo hello master>>hello.txt

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git add .

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git commit -m 'hello master'
[master 6478b3e] hello master
1 file changed, 1 insertion(+)

步骤 4 - 我们现在将尝试将更改从 feature 分支合并到 master 分支。

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git merge feature
Auto-merging hello.txt
CONFLICT (content): Merge conflict in hello.txt
Automatic merge failed; fix conflicts and then commit the result.

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master|MERGING)

输出显示该分支现在处于合并的中间状态,因为由于冲突导致自动合并失败。我们需要手动干预才能完成合并过程。

步骤 5 - 检查文件hello.txt的内容

$ cat hello.txt
hello
<<<<<<< HEAD
hello master
=======
hello feature
>>>>>>> feature

从文件内容可以看出,第一行没有改变。第二行将来自这两个分支。输出屏幕显示一个用“=======”表示的分隔符。分隔符的第一半包含分隔符“<<<<<< HEAD”,这意味着内容来自当前分支(HEAD 指向 master)。分隔符的后一半包含分隔符“>>>>>> feature”,这意味着内容来自第二个分支 - feature。现在我们需要决定是保留前半部分还是后半部分,或者保留两部分的更改。

步骤 6 - 我们决定保留两部分的更改,因此我们手动修改文件,只保留内容并删除分隔符“=======”和分隔符“<<<<<< HEAD”和“>>>>>> feature”。

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master|MERGING)
$ cat hello.txt
hello
hello master
hello feature

步骤 7 - 现在提交更改并显示历史记录。

$ git add .

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master|MERGING)
$ git commit -m 'merge commit'
[master 1183ce0] merge commit

$ dell@DESKTOP-N961NR5 MINGW64 /e/tut_repo (master)
$ git log --oneline --all --graph
* 1183ce0 (HEAD -> master) merge commit
|\
| * a004fa4 (feature) hello feature
* | 6478b3e hello master
|/
* b6a745d hello.txt

更新于:2021年4月30日

816 次浏览

启动您的 职业生涯

完成课程获得认证

开始学习
广告