我可以配置 git 如何检测合并冲突吗

Can I configure how git detects merge conflicts

我有一个可以比较和合并二进制文件的工具。它还可以尝试自动合并所述二进制文件,如果没有人为干预无法决定更改,则中止。 是否可以配置 git 以使用我的工具来检测合并是否导致合并冲突?

例如,假设它可以处理 .png 文件。 如果我有两个分支 A 和 B,在分支 A 上更改了 [150,100] 处的像素,在分支 B 上更改了 [200, 50] 处的像素。如果我现在将分支 B 合并到分支 A,我的工具将检测到没有冲突的更改,并自动合并图像而不会引发冲突。

据我所知,如果您尝试合并两个 PNG 或其他二进制文件,您将受制于 Git 的合并冲突检测算法。该算法通过 text 文件中的更改来标记合并冲突,这些文件涉及彼此一定接近范围内的差异(例如,彼此几行内的更改)。

虽然您并非不可能在 Git 中使用二进制合并工具,但您可能必须自定义 build/fork 或 Git 才能实现。

不过,一般来说,您应该避免在 Git 中对二进制文件进行版本控制,因为它不能很好地处理二进制内容。

TL;DR:您需要一个 合并驱动程序 ,您为 .gitattributes 中的某些文件声明了它。 (驱动程序本身,您在 .git/config 中配置。参见 the gitattributes documentation。)

您无法配置 Git 决定 某些文件需要合并的方式。决策算法太简单了,因为它包括:

  1. 确定合并基础提交中的三个文件和两侧(左侧和右侧,或我们的和他们的)。

    也就是说,假设合并基地有一个名为path/to/abc.png的文件,双方也有一个名为path/to/abc.png的文件。 Git 假定所有三个名称都代表 相同的 基础文件。

    如果,比方说,右侧 (--theirs) 没有 path/to/abc.png,但是 different/path/to/xyz.png and 该文件似乎是新创建的(合并库中不存在)and [的内容=17=] 与基地的 abc.png 足够相似,Git 可能会选择将他们的 xyz.png 与基地的 abc.png 识别,但现在右侧有名称更改 以及潜在的内容差异。这个——重命名文件——是一个高级别更改。

    同样,如果一方完全删除文件,这也是一个高级别的更改。 (如果双方都删除文件,这里没有问题:合并结果只是"delete the file"。)一方或双方删除文件的决定是因为没有unmatched[=90] =] 文件(例如这个新创建的 xyz.png)看起来非常相似。

  2. 现在我们/Git 已经将这三个文件识别为 "the same",如果 以下任一情况为真,则需要进行非平凡的合并:

    • 左右两边都改了内容,变成了不同的内容。也就是说,文件左侧和右侧提交中的 blob 哈希不同 两者都不同于基本提交的 blob 哈希。请注意,这并不意味着存在 冲突! 它只是意味着需要合并。

    • 或者,至少一方改变了内容,另一方做了高水平改变,例如重命名或删除文件。这自动成为高级别冲突

如果此时检测到的冲突是高级别冲突,Git停止并寻求帮助。但是,如果合适,它可能首先继续在三个输入文件上调用合并驱动程序

撇开任何高级冲突或合并要求,Git 现在决定是否对三个输入文件调用低级合并驱动程序。如果(且仅当)发生这种情况:

  • 实际上有三个文件(none 三个文件丢失或删除),并且
  • 所有三个的 blob 哈希不同。

低级合并驱动程序是您通过 .gitattributes 文件配置的驱动程序。如果你没有通过.gitattributes配置一个,它要么是内置的文本文件合并驱动程序,要么是内置的二进制文件合并驱动程序。

内置的文本文件合并驱动程序尝试使用通常的 diff-and-stick-merge-conflict-markers-in 方法合并更改。如果存在低级文本合并驱动程序无法解决的冲突,Git 将停止并寻求帮助。

内置的二进制文件合并驱动程序刚刚宣布失败。 Git 会停下来寻求帮助。

如果您提供您自己的合并驱动程序,负责生成正确的合并结果and/or告诉Git 停下来寻求帮助。因此,如果您有一个知道如何合并 .png 文件的合并驱动程序,您可以将其设置为 *.png.

的低级合并驱动程序