如何在Git仓库中解决合并冲突?

5350

我该如何解决Git仓库中的合并冲突?


40
以下博客文章似乎提供了一个很好的例子,可以帮助你处理Git中的合并冲突,并将你引导到正确的方向。 [处理和避免Git中的冲突] (http://weblog.masukomi.org/2008/07/12/handling-and-avoiding-conflicts-in-git) - mwilliams
4
你可以配置一个合并工具(kdiff3 http://jebaird.com/2013/07/08/setting-up-kdiff3-as-the-default-merge-tool-for-git-on-windows.html),然后使用git mergetool。当你在大型开发团队中工作时,你总会遇到合并冲突。 - Grady G Cooper
不要忘记,您可以通过定期合并下游来减轻大多数合并冲突! - Ant P
3
也请参考 http://www.git-tower.com/learn/git/ebook/command-line/tools-services/diff-merge-tools。 - Pacerier
Github.com有一种很好的可视化问题的方式。确保你看到这个答案。(它也有从站点上编辑和解决的方法,但那只是一个方便。) - mfaani
显示剩余3条评论
36个回答

15

合并冲突可能会在不同的情况下发生:

  • 运行git fetch,然后运行git merge
  • 运行git fetch,然后运行git rebase
  • 运行git pull(实际上等于上述条件之一)
  • 运行git stash pop
  • 应用git补丁时(将提交导出为文件以便传输,例如通过电子邮件)

您需要安装与Git兼容的合并工具来解决冲突。我个人使用KDiff3,我发现它很好用。您可以在此处下载其Windows版本:

https://sourceforge.net/projects/kdiff3/files/

顺便说一句,如果您安装了Git扩展程序,则在其安装向导中有一个选项可以安装Kdiff3。

然后设置Git配置以使用KDiff3作为其合并工具:

$ git config --global --add merge.tool kdiff3
$ git config --global --add mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add mergetool.kdiff3.trustExitCode false

$ git config --global --add diff.guitool kdiff3
$ git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add difftool.kdiff3.trustExitCode false

(记得将路径替换为KDiff3 EXE文件的实际路径。)

然后,每当您遇到合并冲突时,只需运行此命令:

$ git mergetool

然后它会打开Kdiff3,首先尝试自动解决合并冲突。大多数冲突会自动解决,但您需要手动修复其余部分。

以下是Kdiff3的外观:

Enter image description here

完成后,保存文件,程序将继续下一个存在冲突的文件,您需要重复以上步骤直到所有冲突都被解决。

检查是否已成功合并所有内容,只需再次运行mergetool命令即可,您应该会得到这个结果:

$ git mergetool
No files need merging

我的答案应该提示用户关于((git mergetool))这样的内容。讲述IDE相关的技巧是不相关的。 - F.Tamy

14

我知道什么是合并冲突,但当我看到git diff的输出时,起初它对我来说像是一堆无意义的东西:

git diff
++<<<<<<< HEAD
 + display full last name boolean in star table
++=======
+ users viewer.id/star.id, and conversation uses user.id
+
++>>>>>>> feat/rspec-tests-for-cancancan

但是这里是帮助我的方法:

  • 两个箭头之间的所有内容都在一个文件中,用=======分隔的所有内容都在另一个文件中

  • 所以你要做的就是打开有合并冲突的文件,从任一分支中删除或使它们相同,然后merge将立即成功。问题解决了!


14

我一直遵循以下步骤以避免冲突:

  • git checkout master (来到主分支)
  • git pull (更新您的主分支以获取最新的代码)
  • git checkout -b mybranch(检出一个新分支并在该分支上开始工作,以使您的主分支始终保持在主干之上。)
  • git add . git commit git push(在您的本地分支上进行更改后)
  • git checkout master (返回到您的主分支)

现在,您可以执行相同的操作并维护任意多的本地分支,并通过只需在必要时对您的分支进行git checkout 来同时工作。


13

Visual Studio Code 的 GitLens

你可以尝试使用 GitLens 插件,主要功能包括:

1. 简单解决冲突

我已经非常喜欢这个功能了:

这里输入图片描述

2. 当前行代码责任注释

这里输入图片描述

3. 左侧行代码责任注释

这里输入图片描述

4. 状态栏代码责任注释

这里输入图片描述

此外还有许多其他功能。您可以在此处查看它们。


1
我使用过的最好的工具之一,我仍然在所有项目中使用它! - jaques-sam

8
这篇答案是为那些像我一样喜欢在编辑器内完成所有操作的Vim用户添加一个替代方案。

简而言之

Enter image description here


Tpope开发了一个名为fugitive的Vim插件。安装后,您可以运行:Gstatus来检查具有冲突的文件,以及:Gdiff来打开三方合并的Git。

进入三方合并后,fugitive将让您以以下方式获取要合并的任何分支的更改:

  • :diffget //2,从原始(HEAD)分支获取更改:
  • :diffget //3,从合并分支获取更改:

完成文件合并后,在合并缓冲区中键入:Gwrite

Vimcasts发布了一段很好的视频详细解释这些步骤。


在链接视频中,“target”、“local copy”和“merge”是否与“local”、“base”和“remote”(按顺序)相同? - PowerPlay
1
远程 -> 目标;本地 -> 本地副本;基础(无);合并 -> 您想要合并的分支(作为特性分支)。 - Vicente Bolea

7

我在使用Microsoft的Visual Studio Code解决冲突。它非常简单易用。我将项目保持在工作区中,它可以检测并突出显示冲突。此外,它还提供了图形用户界面选项,以从HEAD或incoming中选择要保留的更改。

Enter image description here


1
“接受所有更改”功能似乎是其他提到的工具中缺少的东西,而我经常使用它。 - bohrax

6
git fetch <br>
git checkout **your branch**<br>
git rebase master<br>

在这一步中,您将尝试使用您喜欢的IDE来解决冲突。
您可以按照此链接中的说明来修复文件中的冲突。
git add<br>
git rebase --continue<br>
git commit --amend<br>
git push origin HEAD:refs/drafts/master  (push like a drafts)<br>

现在一切都很好,你会在Gerrit中找到你的提交。

4

如果您还没有使用过Visual Studio Code进行编辑,请尝试一下。

当您尝试合并(并进入合并冲突)时,Visual Studio Code会自动检测到合并冲突。

它可以通过显示对原始文件所做的更改以及您是否应该接受“incoming”或“current change”(即合并前的原始文件)来帮助您。

它帮助了我,也可以为您工作!

PS:只有在您已经将Git与您的代码和Visual Studio Code配置好后,它才能正常工作。


3

如果你正在使用 IntelliJ IDEA 作为集成开发环境,那么可以通过以下方式将父分支合并到你的分支中:

git checkout <localbranch>
git merge origin/<remotebranch>

它会显示所有的冲突,如下:

A_MBPro:test anu$ git merge origin/ 自动合并 src/test/java/com/.../TestClass.java 冲突 (内容):在 src/test/java/com/.../TestClass.java 中合并冲突

现在请注意,在IntelliJ IDEA中,TestClass.java文件显示为红色。

git status也会显示:

Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified:   src/test/java/com/.../TestClass.java

打开IntelliJ IDEA中的文件。它将具有不同的部分:

  <<<<<<< HEAD
    public void testMethod() {
    }
    =======
    public void testMethod() { ...
    }
    >>>>>>> origin/<remotebranch>

这里的HEAD表示你在本地分支上所做的更改,而origin/<remotebranch>则代表来自远程分支的更改。在这里保留你需要的内容并删除不需要的内容。之后,按照正常步骤进行操作即可。

   git add TestClass.java
   git commit -m "commit message"
   git push

3

对于那些使用Visual Studio(例如我所用的Visual Studio 2015)的人:

  1. 关闭Visual Studio中的项目。特别是在大型项目中,使用UI进行合并时,Visual Studio往往会出现问题。

  2. 在命令提示符中进行合并。

    git checkout target_branch

    git merge source_branch

  3. 然后在Visual Studio中打开项目,转到团队资源管理器→分支。现在有一条消息显示为合并待处理,冲突文件列在消息正下方。

  4. 单击冲突文件,将会有合并比较采取源采取目标选项。Visual Studio中的合并工具非常容易使用。


我正在一个非常大的项目中使用VS Code 2017,并且不需要关闭该项目。它处理得非常好 :) - protoEvangelion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接