我可以配置 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 决定 某些文件需要合并的方式。决策算法太简单了,因为它包括:
确定合并基础提交中的三个文件和两侧(左侧和右侧,或我们的和他们的)。
也就是说,假设合并基地有一个名为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
)看起来非常相似。
现在我们/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
.
的低级合并驱动程序
我有一个可以比较和合并二进制文件的工具。它还可以尝试自动合并所述二进制文件,如果没有人为干预无法决定更改,则中止。 是否可以配置 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 决定 某些文件需要合并的方式。决策算法太简单了,因为它包括:
确定合并基础提交中的三个文件和两侧(左侧和右侧,或我们的和他们的)。
也就是说,假设合并基地有一个名为
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
)看起来非常相似。现在我们/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
.