Git合并内部构件

Git合并内部构件,git,github,merge,git-merge,Git,Github,Merge,Git Merge,这可能会成为一个很长的问题,所以请容忍我 我在这里遇到了一个关于git合并决策的令人难以置信的解释:。我试图建立在这个解释的基础上,看看这样描述git合并是否有漏洞。本质上,一行是否显示在合并文件中的决定可以通过真值表来描述: W:原始文件, A:艾丽斯分店, B:鲍勃的分行 基于此真值表,可以直接想到一种基于行的算法来构造D:通过查看a和B中的对应行,逐行构造D,并根据真值表进行决策 我的第一个问题是案例(0,0,1),根据我在上面发布的链接,它似乎表明,虽然这个案例实际上是一个冲突,但gi

这可能会成为一个很长的问题,所以请容忍我

我在这里遇到了一个关于git合并决策的令人难以置信的解释:。我试图建立在这个解释的基础上,看看这样描述git合并是否有漏洞。本质上,一行是否显示在合并文件中的决定可以通过真值表来描述:

W:原始文件, A:艾丽斯分店, B:鲍勃的分行

基于此真值表,可以直接想到一种基于行的算法来构造D:通过查看a和B中的对应行,逐行构造D,并根据真值表进行决策

我的第一个问题是案例(0,0,1),根据我在上面发布的链接,它似乎表明,虽然这个案例实际上是一个冲突,但git通常通过删除行来处理它。这个案子真的会导致冲突吗

我的第二个问题是关于删除案例-(0,1,1)和(1,0,1)。凭直觉,我觉得这些案件的处理方式可能会导致一个问题。假设W中有一个函数foo(),这个函数在任何代码段中都没有实际调用过。假设在分支A中,Alice最终决定删除foo()。然而,在分支B中,Bob最终决定使用foo(),并编写了另一个名为foo()的函数bar()。直观地说,根据真值表,合并后的文件似乎最终会删除foo()函数并添加bar(),Bob会疑惑为什么foo()不再工作了!这可能会让我想到,我为3路合并导出的真值表模型可能不完整,并且遗漏了一些东西

我的第一个问题是(0,0,1)

有些版本控制系统如DARCS认为,在两个分支中进行相同的更改(在您的情况下,删除)并合并它们会导致冲突。典型的例子是当你有两次

-#define NUMBER_OF_WHATEVER 42
+#define NUMBER_OF_WHATEVER 43
合并算法无法为您确定是希望合并产生43(因为这是两个版本都同意的值)还是44(因为42应该增加两次)

然而,将此案例视为冲突会导致许多虚假冲突。例如,如果一个cherry选择从主分支到维护分支的合并,然后将维护分支合并到主分支,那么由cherry选择修改的每一行都将导致冲突。冲突标记会很奇怪,因为它们会在冲突标记的两侧显示相同的内容,比如

<<<<<<< HEAD
Hello world
=======
Hello world
>>>>>>> 77976da35a11db4580b80ae27e8d65caf5208086
>77976DA35A11DB4580B80AE27E8D65CAF520806
<> P>因此,大多数版本控制系统,包括GIT,在合并的两个方面都引入相同的更改时,选择不考虑冲突。 我的第二个问题是关于删除案例-(0,1,1)和(1,0,1)

您所描述的是语义冲突。它们在理论上确实存在,您甚至可以找到合并是可编译的,但与合并的分支相比具有不同语义的情况。没有魔法,没有文本合并算法可以检测或解决语义冲突。你必须和他们一起生活,或者独自工作

在实践中,它们非常罕见。可能每天都有数百万人使用版本控制系统并与之生活在一起。大多数人可能从未想过这个问题会存在

然而,一个好的组织可以大大降低语义冲突的风险。如果您检查代码在合并后仍能编译,则可以避免约90%的语义冲突,并且如果您有一个自动测试套件,那么您必须找到一个语义冲突,该语义冲突会导致测试套件未涵盖的bug,从而使其成为问题

实际上,语义冲突并不特定于版本控制系统。另一个不使用合并的场景是

  • 我读了代码,看到一个函数
    f()
  • 我的同事删除函数
    f()
  • 在使用最新版本时,它不再有
    f()
    ,我仍然记得有一个函数
    f()
    ,我尝试使用它
简而言之,不要害怕语义冲突。

这里有一个方法供您自己测试不同的合并行为。它有大量的分支,可以进行各种更改以相互合并

请随意分叉或克隆它:

git clone https://github.com/NickVolynkin/GitMergeResearch.git
我很快就会发布我的结果


D是一个合并提交,对吗?嗨,Matthieu——感谢您的时间和巨大的响应。因此,总结您对第一个问题的回答——(0,0,1)在合并两个分支时永远不会导致冲突,而(1,1,0)可能会或可能不会导致冲突,这取决于是否将完全相同的行添加到分支的两侧(这通常不会发生)。简而言之,任何语法冲突(与您描述的语义冲突相反)都可以归结为(1,1,0)情况。我说的对吗?关于你对第二个问题的回答,与其删除案例(1,0,1)和(0,1,1)中缺失的行,为什么版本控制系统不选择将它们保留在。所以本质上,(1,0,1)和(0,1,1)的真值表的输出是1,而不是0。这难道不能避免我在一个分支中删除了调用函数而在另一个分支中没有删除的情况吗?因为根据你的建议,你不能删除一段代码。删除它,合并,它会回来。没人想要这个。嗨,尼克——谢谢你花时间制作这个存储库。在制作上面的真值表之前,我也在本地存储库上工作过。你有没有发现与上表不符的地方?