Git合并:将冲突作为单独的文件获取,以与外部工具合并

时间:2018-12-06 13:32:27

标签: git

当我拉动时,我遇到了冲突,但是像往常一样,在冲突文件中将冲突标记为内联。

我想将“ mine”和“ theirs”作为两个/三个单独的文件(.MINE,.THEIRS),以便可以使用特殊工具对此文件类型执行合并。

git有可能吗?

2 个答案:

答案 0 :(得分:2)

是的。当合并因冲突而停止时,索引将包含所有三个 输入文件(不仅是ourstheirs,而且还包含 base 版本)合并基础提交)。

您一直在查看的工作树文件并不是Git真正关心的东西。 Git将在合并索引中的三个输入(这是Git 在这里关心的事情)时尽力而为地写到工作树上,然后您将负责监督合并的工作正确合并结果,然后将其塞回到索引中。如果您能做到这一点,而工作树中只剩下一团糟的Git,那就太好了。如果不是...:

索引通常每个文件只有一个副本。那个副本进入“插槽0”,最初,它与您检出的提交匹配。

有文件的工作树副本供您使用,但是Git并没有真正使用它,除非您运行git add file。然后,Git将文件的工作树副本复制到索引副本的顶部,以便索引副本再次与工作树副本匹配(并且可能不再与当前提交的副本匹配)。

在合并过程中,零插槽副本在插槽2(--ours)中结束。来自合并基础的同一文件的副本进入插槽1。来自另一提交(即您要合并的提交)的同一文件的副本进入插槽3(--theirs)。 Git尝试合并所有三个副本,如果Git单独成功,则Git会将合并的版本放在插槽0中(并将其复制到工作树中)并清空合并插槽。如果Git失败,它将使合并插槽被占用,插槽零为空。

因此,如果Git留下的工作树混乱不够好,则可以仅提取所有三个索引副本。手动执行此操作的方法是使用git checkout-index,但通常更容易(如果比较笨拙)的方法是使用git mergetool

The git mergetool command本质上是一个大型Shell脚本,它在每个尚未合并的文件的所有三个副本上运行git checkout-index,然后在这三个副本上运行您选择的任何命令。该命令应将正确的合并文件写入第四个文件:

  

...的    配置的命令行将在$BASE设置为名称的情况下被调用    包含合并通用基础的临时文件    可用$LOCAL设置为包含以下内容的临时文件的名称    当前分支上文件的内容; $REMOTE设置为    包含文件内容的临时文件的名称    合并,并且$MERGED设置为合并到的文件的名称    工具应写入合并解析的结果。

同样,所有这些临时文件都是由git mergetool使用git checkout-index从索引中提取出来的。工具完成后,脚本将使用git add文件上的$MERGED删除插槽1-3条目并写入零插槽条目。

短语如果可用出现在上方,是因为在某些特殊情况下,由于一个文件丢失而发生了合并冲突。例如,当没有newfile.ext合并基础版本,但同时--ours--theirs时,发生添加/添加冲突 em> do 有一个newfile.ext,并且两个文件不匹配。在这里,基地将丢失; $LOCAL$REMOTE都将存在。当基本提交中有file.ext,您(--ours)或他们(--theirs)已更改 时,发生修改/删除冲突。文件,而您中的另一个人删除了文件。在这里,$BASE将存在,但是$LOCAL$REMOTE中将仅存在一个。

由于git mergetoolshell script,所以您可以复制和修改它-您需要几个相邻的文件;从这里进行探索,它们应该很明显-如果您想通过标志和工具配置尚不支持的某种方式来更改其操作。

答案 1 :(得分:1)

设置一个mergetool,当您运行git mergetool时Git将打开。 Git提供了4个带有路径的变量,您可以将其提供给将打开工具的命令。来自man git-mergetool

  

使用此工具调用git mergetool时(通过-t--tool选项或merge.tool配置变量),将使用{{ 1}}设置为包含合并通用库的临时文件的名称(如果有); $BASE设置为包含当前分支上文件内容的临时文件的名称; $LOCAL设置为包含要合并文件内容的临时文件的名称,而$REMOTE设置为合并工具应向其中写入合并解析结果的文件的名称。

例如,它看起来像:

$MERGED