我是git的新手,我明白什么是快进合并[如果两个分支是线性的只是将指针移动到分支]但是当它来到3路合并时它的位混乱,因为为什么3路合并需要共同的祖先来创建一个新的提交为什么不能采取两个分支[我想要合并到的分支(例如:master)和一些想要合并的分支(例如:immediatefix)]并比较它们并且只是进行合并。你为什么想要共同的祖先。为了我们需要共同的祖先,我们为什么要坚持...
答案 0 :(得分:2)
这很简单,归结为Git如何提交。与其他VCS不同,Git存储整个工作目录的完整快照。因此,当查看单个提交时,您只能看到提交内容的确切状态。
像Subversion这样的其他VCS通常存储差异。因此,修订存储为先前状态和当前状态之间的差异。因此,在合并时,您只需查看单个修订版本即可查看发生了什么,您可以将其应用于其他地方。
另一方面,Git并没有随时可用的差异。为了能够查看提交中发生的事情,需要将内容与父提交进行比较。只有这样它才能产生差异并将其应用于其他地方。因此,对于具有共同基础A
的两个分支B
和C
,Git所做的是查看A
和C
之间的差异,以及{{1 }和B
。然后它知道每个分支中到底发生了什么,并且可以尝试应用所有更改。这进一步带来了正在查看整个范围的更改的好处,因此如果您暂时更改某个分支中的某些内容但稍后将其取消,那么在合并时它将不会显示完全不同。这通常会减少冲突。
同样适用于rebase,除了它实际上是以它的名义。将C
重新定位到B
时,您基本上会重写A
范围内的所有提交,而不是C..B
作为父级。因此,Git将查看A
与分支上第一次提交之间的区别,并将其应用于C
。然后它将查看第一次提交和第二次提交之间的区别并应用它。这种情况一直持续到整个分支重新定位以使A
作为 base 。
如果A有完整快照并且B有完整快照我可以比较A和B并且我们可以合并它以便我们为什么需要共同基数C?
好吧,让我们试试这个例子吧。我们只需查看单个文件以使其更容易,但这将发生在存储库中的每个文件中。
假设这是分支A中的文件内容:
A
这是分支B中的内容:
alpha
beta
gamma
现在合并的版本会是什么样的?如果您不知道实际更改的提交,您无法安全地做出决定。例如,我们可以说,最初(在C中)的文件只有alpha
gamma
delta
和alpha
。因此,在分支中添加了gamma
,并添加了B beta
。这将导致:
delta
或者我们可以假设相反,说该文件最初包含了所有四行,因此在A alpha
beta
gamma
delta
中删除了并且在delta
中删除了
beta
或者我们可以说分支B实际上从未触及文件,因此应忽略其状态并保留A的内容。如果分支A从未触及文件,则反向适用。
正如您所看到的,拥有这些分支的基础,因此分支的实际差异有助于决定如何解决合并。毕竟,我们希望使用分支独立于其他分支(与其他独立开发线)开发内容,只需合并所有更改,而无需在合并期间完成所有工作。