git,与工具合并,而不是与工具解决

时间:2019-11-25 08:56:20

标签: git git-merge mergetool

我来自水银,这件事我不知道如何与git一起使用。

在合并过程中,在我最喜欢的合并工具(kdiff3或meld)上并排显示了冲突文件的每个版本(基本,其他和本地)。我合并它们,保存结果,每个人都很高兴。

使用git,我git merge,如果发生冲突,我git mergetool ...我得到的文件充满了这种混乱的混乱局面:

first line
<<<<<<< HEAD
local line
=======
other line
>>>>>>> other-branch
last line

如何配置git,以便在发生冲突之前打开我最喜欢的合并工具??我想手动合并,而不是手动解决:)

1 个答案:

答案 0 :(得分:1)

(初步说明:我不使用任何这些工具。相反,我将merge.conflictStyle设置为diff3,这在工作树文件中使用了略有不同的标记格式。大多数时间,我可以很容易地直接在vim中解决它。如果太混乱了,我有时会使用git show直接提取三个输入,例如git show :1:path。但是每个人都不一样,所以请参见Git: How configure KDiff3 as merge tool and diff tool。)

  

如何配置git在冲突发生之前打开我喜欢的合并工具?

不能。好吧,如果您编写了自己的合并 strategy (相当于git merge-recursive),您可以这样做,但是多年以来,没人做这种事情,因为这太难了。幸运的是,您不需要:

  

我想手动合并,而不是手动解决:)

如果发生冲突,Git会尝试将其合并到工作树文件中。 1 这就是您在编辑器中看到的内容。但是Git将这三个输入文件留在了Git调用的地方,分别是 index staging area 和(现在很少是) cache 。这是同一事物的三个名称:临时区域指代您使用它的方式,而 cache 则指代它的各个内部方面和 index 是一种毫无意义的术语。在这种情况下,“索引”一词可能是最好的选择,我将在这里使用它。

当您运行git mergetool时,Git应该在所有三个输入文件上启动您选择的合并工具,再加上第四个(带有冲突标记的Git尝试合并)工作,树文件。然后,该工具可以向您显示这些各种输入中的一些或全部。然后,您可以使用工具本身以任何方式使用的工具,以手动进行解析,如果您愿意,完全忽略Git进行合并的尝试

请注意,--ours提供给合并工具的三个输入文件(合并--theirs的基本,左侧或本地,以及git mergetool的右侧或远程或-s)只是临时文件。它们将不会用作合并结果。当您的合并工具向Git指示完成合并时,用作合并结果的文件是主要的工作树文件:其中包含混乱的文件。因此,您的工具必​​须使用合并结果覆盖此文件。

与Mercurial不同,核心Git没有内置的合并工具(嗯,除了它自己的默认工具外,它始终可以运行,作为您使用$BASE选择的合并策略的一部分)。因此,您或为您设置Git发行版的某人必须告诉Git 如何运行任何特定的外部合并工具。每个Git 安装通常都会具有一些预配置的外部合并工具,其中可能包含或可能不包含您想要的一个。如果需要配置自己的外部合并工具,请参见Git on Windows: How do you set up a mergetool?(尽管标题如此,但在非Windows系统上,它的某些答案很好。请参见CB Bailey's answer in particular。)

您的合并工具必须处理的四个名称作为环境变量提供:$LOCAL命名合并基础文件(来自索引中的暂存槽#1),--ours命名{{1 }}文件(索引中的暂存槽#2),$REMOTE命名--theirs文件(暂存槽#3),而$MERGED是{{1} }期望您的合并工具在您的合并工具向git mergetool脚本发出成功或失败信号之前进行更新。 2


1 请记住,Git在您的工作树中存储了文件的可用副本,但实际上是通过(间接)存储在索引中的特殊Git格式文件来构建提交的。在发生冲突的合并期间,Git使用非零索引槽号将所有三个输入文件保留在索引中。 Git认为自己解决的文件会进入正常的零槽索引条目,从而消除了非零槽,因此此处三个输入文件不容易使用。 (在我看来,这是一个缺陷,但是Git并没有征求我的意见。从技术上讲,Git甚至不将文件的条目写入非零索引槽,只要它可以在处理文件时对其进行简单合并即可。这是可能是出于速度和/或懒惰。)

2 您的工具应通过其操作系统级别的退出代码来指示成功或失败。如果这样做,并且在将git mergetool设置为trustExitCode的情况下配置了此工具,true将知道是否自动git mergetool git add文件。如果将$MERGED配置为trustExitCode,则false将使用一些启发式方法来猜测是否认为该工具成功合并了文件。