解决 Git 合并冲突
在复杂的开发项目中,合并冲突往往难以避免。本指南将探讨如何应对合并冲突,以及它们何时会发生。
合并冲突何时发生?
如果您在当前分支和要合并到的分支上都修改了同一个文件,就会发生 Git 合并冲突。在这种情况下,Git 无法确定应该使用哪个分支,因此会抛出合并冲突错误。
假设分支 A 和 Bfile.md中对代码进行了更改。当我们检出更改后的代码并尝试将其合并到分支 B 时,会遇到以下错误:mainmy-branchmainmy-branchmain
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。如果现在遇到合并冲突,我们需要解决它们。
如何通过 Git 图形界面解决合并冲突
如果您使用的是像 Visual Studio Code 这样的现代代码编辑器,合并冲突会显示在图形用户界面 (GUI) 中,您可以在其中接受传入的更改或接受当前分支上的更改。这提供了一种非常简便的解决冲突的方法。在 Visual Studio Code 中,冲突文件会通过如下所示的 GUI 界面显示。您有多种选择:
- “接受当前更改”——这将使用您当前分支的内容。
- “接受传入的更改”——这将使用您正在合并的分支中的内容。
- “接受两项更改”——这将使两项更改相互兼容,一项位于另一项之下。
- “比较更改”——这将打开一个额外的屏幕,用于并排比较更改。
检查完所有冲突后,就可以像往常一样添加文件并提交了:
git add -A
git commit -m "My commit message"
如何通过终端解决 Git 中的合并冲突
在某些情况下,您可能没有图形用户界面来解决合并冲突。您可以使用一些命令来解决这些问题。
首先,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
这将使我们回到非合并状态,以便我们可以在两个分支中手动解决合并冲突,然后再尝试合并。
通过接受传入或当前的更改来解决
解决特定文件合并冲突的另一种简便方法是使用 ` --theirsand`--ours选项git checkout。我们的合并冲突发生在 `.` 文件上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`and`和 `or` 之间的文本;如果您想接受新合并,则删除 `and` 和`or`=======之间的文本。=======>>>>>>>
添加并提交您的更改
解决合并冲突后,不要忘记在当前分支上添加并提交更改,以便更改能够保存:
git add -A
git commit -m "Merge message"
结论
我们的代码编辑器中配备了强大的工具来解决合并冲突。尽管如此,有时环境的限制意味着我们必须自行解决 Git 合并错误——或者我们可能更喜欢在终端中完成这项工作。某些特殊情况也可能导致我们必须在终端中完成这项工作。
总之,合并冲突是 Git 开发过程中不可避免的一部分,可以通过从冲突文件中移除不再需要的内容来轻松解决。我们也可以使用 `git commit`git checkout --theirs或 ` git checkout --oursgit commit -l` 来更快地解决问题。
