合并冲突通常是处理复杂开发项目的一部分。在本指南中,我们将了解如何处理它们,以及它们何时发生。
什么时候发生合并冲突?#
如果您对您所在的分支上的同一个文件进行了更改,那么 Git 中的合并冲突将会发生,并且您尝试合并到的那个文件。在这种情况下,Git 不知道应该使用哪一个——所以它会抛出一个合并冲突错误。
考虑file.md
在main
分支和my-branch
. 当我们 checkoutmain
并尝试 merge my-branch
intomain
时,会遇到以下错误:
git merge my-branch Auto-merging file.md CONFLICT (content): Merge conflict in file.md Automatic merge failed; fix conflicts and then commit the result.
Git 不知道在这里做什么,所以尝试解决它是我们的工作。
稳定当前分支#
有时,当我们尝试合并文件时,合并会完全失败:
error: Your local changes to the following files would be overwritten by merge: file.md Please commit your changes or stash them before you merge.
发生这种情况是因为我们在当前分支上有未提交的更改。在合并之前,我们需要关闭当前分支上的所有更改。为此,您可以运行git stash
(我在这里更详细地介绍了 git stash),或者您可以简单地在此分支上提交您的更改以使其稳定:
git add -A git commit -m "My commit message"
现在我们的分支已经稳定了,我们可以尝试运行git merge my-branch
(my-branch
你的分支在哪里)将我们的分支合并回main
. 如果我们现在遇到合并冲突,我们需要解决它们。
如何通过 GUI 解决 git 中的合并冲突#
如果您使用的是现代代码编辑器(如 Visual Studio Code),则合并冲突将出现在 GUI 中,您可以在其中接受传入的更改或接受分支上的当前更改。这提供了一种非常简单的方法来解决您的冲突。在 Visual Studio Code 中,这通过如下所示的 GUI 在冲突文件中表示。您有多种选择:
- “接受当前更改” – 这将使用您当前分支的内容。
- “Accept Incoming Changes” – 这将使用您正在合并的分支中的内容。
- “Accept Both Changes” – 这将保持两者,一个在另一个之下。
- “比较更改” – 这将打开一个额外的屏幕来并排比较更改。
查看所有冲突后,您可以添加文件并正常提交它们:
git add -A git commit -m "My commit message"
如何通过终端解决 git 中的合并冲突
在某些情况下,您可能没有用于解决合并冲突的 GUI。您可以使用许多命令。
首先,git status
会告诉你受影响的文件:
git status On branch my-branch You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: file.md no changes added to commit (use "git add" and/or "git commit -a")
正如我们所看到的,只有file.md
受到影响。接下来,我们可以git diff
用来查看这个分支和我们要合并的分支之间的区别:
++<<<<<<< HEAD +Some a +Some b +Some conflict c +Some conflict d +Some e ++======= + Some conflict 1 + Some b + Some conflict c + Some conflict 2 -Some f ++Some f ++>>>>>>> main
在这里,++<<<<<<<
之前和之后的所有内容都++=======
代表当前分支的更改,而++=======
之前和之后的所有内容都++>>>>>>> main
代表您要合并的分支。
我们还可以通过运行查看冲突的提交git log --merge
在合并冲突期间中止合并
有时你意识到你在这个合并冲突上有点太深了——在这种情况下,你可以通过运行git merge --abort
.
git merge --abort
这将使我们回到非合并状态,因此我们可以在两个分支中手动解决合并冲突,然后再尝试再次合并。
通过接受传入或当前更改来解决
解决某些文件合并冲突的另一种简单方法--theirs
是--ours
在git checkout
. 我们的合并冲突是 on file.md
。如果我想接受file.md
来自我试图合并的分支的所有传入更改,我可以写:
git checkout --theirs file.md
这会检查file.md
“他们的”代码版本。如果我想在当前分支中使用该版本,我会使用--ours
. 两者都--ours
需要--theirs
一个文件作为参数 – 所以这必须在一个文件一个文件的基础上完成。
容易,对吧?这对于合并整个文件来说很好,但是如果我们在一个文件中有多个合并冲突怎么办?
通过编辑文件本身来解决
请记住,当您创建 git 合并冲突时,我们最终得到的内容在我们运行时看起来像这样git diff
?
++<<<<<<< HEAD +Some a +Some b +Some conflict c +Some conflict d +Some e ++======= + Some conflict 1 + Some b + Some conflict c + Some conflict 2 -Some f ++Some f ++>>>>>>> main
该内容也存在于发生冲突的文件中(当然没有+
and -
)。如果您想在没有 GUI 帮助的情况下解决合并冲突,最简单的方法是转到有问题的文件,然后简单地删除您不想接受的部分。这只是意味着删除和之间的文本<<<<<<< HEAD
,=======
如果你想接受当前,或者之间的文本=======
,>>>>>>>
如果你想接受传入。
添加和提交您的更改
解决合并冲突后,不要忘记在当前分支上添加并提交更改,以便它们保持保存:
git add -A git commit -m "Merge message"
结论#
我们的代码编辑器中有强大的工具来解决合并冲突。话虽如此,有时环境中的限制意味着我们必须解决自己的 git 合并错误 – 或者我们可能更喜欢从终端完成这项工作。一些特定的边缘情况也可能意味着我们必须从终端完成这项工作。
无论如何,合并冲突是 git 开发的一部分,只需从存在冲突的文件中删除我们不再需要的内容即可解决它们。我们还可以使用git checkout --theirs
或git checkout --ours
更快地解决问题。