如何解决Git中的合并冲突?

有没有一种很好的方式来解释如何解决Git中的合并冲突?


试试: git mergetool

它会打开一个图形用户界面,逐步解决每个冲突,并且您可以选择如何合并。 有时候需要稍后手动编辑,但通常本身就足够了。 肯定比手工做整件事要好得多。

根据@JoshGlover评论:

除非安装一个命令,否则该命令不一定会打开一个GUI。 为我运行git mergetool导致vimdiff被使用。 您可以安装以下工具之一,而不是使用它: meldopendiffkdiff3tkdiffxxdifftortoisemergegvimdiffdiffuseecmergep4mergearaxisvimdiffemerge

以下是使用vimdiff解决合并冲突的示例过程。 基于这个链接

步骤1 :在终端中运行以下命令

git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false

这会将vimdiff设置为默认合并工具。

第二步 :在终端运行以下命令

git mergetool

第3步 :您将看到以下格式的vimdiff显示

  +----------------------+
  |       |      |       |
  |LOCAL  |BASE  |REMOTE |
  |       |      |       |
  +----------------------+
  |      MERGED          |
  |                      |
  +----------------------+

这4个观点是

LOCAL - 这是来自当前分支的文件

BASE - 共同的祖先,在两个变化之前如何查看文件

REMOTE - 将文件合并到您的分支中

合并 - 合并结果,这是保存在回购中的东西

您可以使用ctrl+w在这些视图中导航。 您可以使用ctrl+w然后按j直接进入MORGED视图。

更多关于vimdiff导航的信息在这里和这里

第4步 。 您可以通过以下方式编辑MERGED视图

如果你想从REMOTE获得更改

:diffg RE  

如果你想从BASE获得更改

:diffg BA  

如果你想从本地获得更改

:diffg LO 

第5步 。 保存,退出,提交和清理

:wqa保存并退出vi

git commit -m "message"

git clean删除由diff工具创建的额外文件(例如* .orig)。


从顶端看,这是一个可能的用例:

您将要进行一些更改,但哎呀,您不是最新的:

git fetch origin
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.

所以你得到最新的并且再试一次,但有冲突:

git add filename.c
git commit -m "made some wild and crazy changes"
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Auto-merging filename.c
CONFLICT (content): Merge conflict in filename.c
Automatic merge failed; fix conflicts and then commit the result.

所以你决定看看这些变化:

git mergetool

哦,我,我的上游改变了一些东西,但只是为了使用我的改变......不......他们的改变......

git checkout --ours filename.c
git checkout --theirs filename.c
git add filename.c
git commit -m "using theirs"

然后我们尝试最后一次

git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Already up-to-date.

当当!


我发现合并工具很少帮助我理解冲突或解决方案。 我通常更成功地在文本编辑器中查看冲突标记,并使用git log作为补充。

这里有一些提示:

提示一

我发现的最好的事情是使用“diff3”合并冲突风格:

git config merge.conflictstyle diff3

这会产生这样的冲突标记:

<<<<<<<
Changes made on the branch that is being merged into. In most cases,
this is the branch that I have currently checked out (i.e. HEAD).
|||||||
The common ancestor version.
=======
Changes made on the branch that is being merged in. This is often a 
feature/topic branch.
>>>>>>>

中段是共同祖先的样子。 这很有用,因为您可以将其与顶部和底部版本进行比较,以更好地了解每个分支上发生了哪些变化,从而更好地了解每次更改的目的。

如果冲突只有几行,这通常会使冲突非常明显。 (知道如何解决冲突是非常不同的,你需要知道其他人在做什么,如果你感到困惑,最好把这个人叫进你的房间,这样他们就可以看到你在看什么在。)

如果冲突时间更长,那么我会将这三部分中的每一部分分割成三个单独的文件,例如“我的”,“普通”和“他们的”。

然后我可以运行以下命令来查看导致冲突的两个差异块:

diff common mine
diff common theirs

这与使用合并工具不同,因为合并工具也将包含所有非冲突差异区段。 我发现这会让人分心。

提示二

有人已经提到了这一点,但理解每个差异背后的意图通常对理解冲突来自何处以及如何处理它非常有帮助。

git log --merge -p <name of file>

这显示了在共同祖先和正在合并的两个头之间触及该文件的所有提交。 (所以它不包括合并之前两个分支中已经存在的提交。)这可以帮助您忽略显然不是当前冲突中的因素的差异差异。

提示三

使用自动化工具验证您的更改。

如果您有自动化测试,请运行这些测试。 如果你有皮棉,那就运行一下。 如果它是一个可构建的项目,那么在提交之前构建它等等。在所有情况下,您都需要进行一些测试以确保您的更改不会破坏任何内容。 (哎呀,即使是没有冲突的合并也会破坏工作代码。)

提示四

未雨绸缪; 与同事沟通。

提前规划并意识到其他人正在处理的事情可以帮助防止合并冲突和/或提早解决它们 - 而细节仍然是新鲜事物。

例如,如果你知道你和另一个人正在进行不同的重构,这两个重构都会影响同一组文件,你应该提前互相交流,并且更好地了解你们每个人的变化类型是什么制造。 如果您连续进行计划更改而不是平行进行,则可能会节省大量时间和精力。

对于横跨大量代码的主要重构,您应该强烈考虑连续工作:当一个人执行完整的重构时,每个人都停止在该代码区域工作。

如果你不能连续工作(也许是由于时间压力),那么就预期的合并冲突进行沟通至少可以帮助你尽快解决问题,同时细节仍然是新鲜事物。 例如,如果同事在一周的时间内进行了一系列颠覆性的提交,那么您可以选择在该周内每天在该同事分支上合并/重新绑定一次或两次。 那样的话,如果你发现合并/重组冲突的冲突,你可以更快地解决它们,而不是等待几个星期才能把所有事情合并在一起。

提示五

如果您不确定是否合并,请不要强制合并。

合并会让人感觉压倒性的,特别是当有很多冲突文件和冲突标记覆盖数百行时。 通常,在估算软件项目时,我们没有足够的时间来处理开销项目,比如处理粗糙的合并,所以感觉像是花费数小时解决每个冲突的真正拖累。

从长远来看,提前规划并意识到其他人正在处理的是预测合并冲突并准备在较短时间内正确解决冲突的最佳工具。

链接地址: http://www.djcxy.com/p/97.html

上一篇: How to resolve merge conflicts in Git?

下一篇: How to disable text selection highlighting?