2017-08-17 109 views
0

由于回购与主和特性分支并通过C5如下承诺C0合并时git分支是压扁还是重播?

C0 <-- C1 <-- C2 <------ ??? master 
     \    /
     C3 <-- C4 <-- C5  feature 

当我合并,是什么在???点发生什么呢?

我能得到一个承诺C6,即作为一个合并的“南瓜”承诺:

C0 <-- C1 <-- C2 <------ C6 master 
     \    /
     C3 <-- C4 <-- C5  feature 

或者“重播”,即C6 <-- C3' <-- C4' <-- C5'(与',因为这些提交现在还包含C2 ):

C0 <-- C1 <-- C2 <------ C6 <-- C3' <-- C4' <-- C5' master 
     \    /
     C3 <-- C4 <-- C5        feature 

是它在GitHub上相同合并来自同一回购的分支箱标拉请求时?

+4

您试过吗? –

+0

此外,“南瓜”是历史的崩溃,因为你没有摆脱历史,你没有压扁。提交只不过是此时存储库看起来像什么的快照,合并是通过集成两组更改并形成新快照来创建此类提交的一种方式。 –

+0

两者都不会发生。你从C5到C1和C2到C1有所不同。 – ckruczek

回答

2

你得到的既不是压缩也不是提交的重放。

要获得壁球,您可以使用--squash选项至merge。然后你会得到

C0 <-- C1 <-- C2 <-- C3C4C5 master 
     \     
     C3 <-- C4 <-- C5  feature 

其中C3C4C5是一个家长,其差异从C2C1(不包括冲突)等于C5小号DIFF单个提交。

重播来自分支的更改,您可以执行重新绑定操作。这可能产生

C0 <-- C1 <-- C2 <-- C3' <-- C4' <-- C5' master featurE_ref 
     \     
     C3 <-- C4 <-- C5  feature_ref_used_to_be_here 

(或一些变化,具体取决于你做什么)。在这种情况下提交C3'不同形式C2正是因为C3不同形式C1

但在合并的情况下,你没有得到任何的那些。你得到

C0 <-- C1 <-- C2 <------ M  master 
     \    /
     C3 <-- C4 <-- C5  feature 

“M”是一个单一的提交,但不像从挤压变形C3C4C5M有两个家长。它的TREE(内容)与C2不同,与C5TREE不同于C1的方式相同,所以它的类似到南瓜。但它通常被解释为没有引入变化(除了合并冲突或邪恶合并的情况);而是表示在此时将C5及其祖先的更改引入master。因此默认git log不显示M的修补程序,但确实包含提交C3,C4C5

1

你既不直接也不直接。

Git中所有合并的第一个工作是这样的:

  1. 找到两个头的共同祖先,你的情况,这是C1
  2. 合并两个头中的“找到差异条款在这些和共同的祖先之间,把它放在一起,无论我无法做到这一点确定性,我问用户'
  3. 当我完成时,我创建一个新的提交,合并提交,其中有C2C5作为共同父母

合并时,您可以将性交壁球(git merge --squash)。这是在this解释优秀的答案。

2

假如你使用的命令git merge没有--squash选项,什么情况是,Git会创建一个C6犯,被称为merge commit,这是一个像合并其内容后,您的跟踪文件的快照。默认策略是递归,它通过考虑C5C1之间以及C2C1之间的变化进行合并。

由于这是合并提交,所以它的父代将是C5C2

您的困惑可能来自您并未考虑提交的事实:它们只是指向文件树状态的指针。他们不存储差异(为了简单起见,我们跳过由gc完成的压缩),他们存储状态。所以Git会合并你的文件,保存它们,对它们进行散列并创建一个散列(表示一个树对象),它允许我们重建这个状态,这就是你的提交所指向的内容。 Git From The Inside Out在解释整个过程方面做得非常出色。另一方面,如果您使用git merge --squash,Git也会在合并后创建一个具有状态的提交,但是结果提交将像正常提交一样,没有两个父项。有关更多信息,请参阅Git: To squash or not to squash?

最后,这个“重放”过程由rebase完成,但不是按照您所描述的方式完成。请阅读Merging vs. Rebasing,了解mergerebase的不同之处。