3 回答
TA贡献1898条经验 获得超8个赞
Git不会阻止合并中的冲突,但是即使它们不共享任何父祖先,也可以协调历史记录。
(通过嫁接文件(.git/info/grafts),它是提交的列表,每行一个提交,后跟其父级,您可以出于“和解”的目的进行修改。)
如此强大。
但是要真正了解“如何考虑合并”,您可以从Linus自己开始,然后意识到这个问题与“算法”并没有太大关系:
莱纳斯(Linus):我个人来说,我想拥有一种非常可重复且非巧妙的东西。我了解或告诉我它做不到的事情。
坦率地说,合并单个文件的历史记录而不考虑其他所有文件的历史记录会使我“很烦”。
合并的重要部分不是如何处理冲突(如果冲突很有趣,则无论如何都要由人来验证),而是应该将历史融合在一起,以便为将来的合并奠定新的坚实基础。
换句话说,重要的部分是琐碎的部分:给父母命名,并跟踪他们的关系。不是冲突。
似乎有99%的SCM人似乎认为解决方案是对内容合并更加聪明。这完全错了重点。
因此Wincent Colaiuta补充说(我的重点是):
不需要花哨的元数据,重命名跟踪等。
您唯一需要存储的是每次更改前后的树状态。
什么文件被重命名?哪些被复制?哪些被删除?添加了哪些行?哪些被删除?其中哪些行进行了更改?哪些文本是从一个文件复制到另一个文件的?
您不必关心这些问题中的任何一个,当然也不必保留特殊的跟踪数据来帮助您回答它们:对树的所有更改(添加,删除,重命名,编辑等)都是隐式的编码在树的两种状态之间的增量中 ; 你只跟踪什么内容。
绝对可以(并且应该)推断一切。
Git打破了常规,因为它只考虑内容而不是文件。
它不跟踪重命名,而是跟踪内容。它是在整个树级别上执行的。
这与大多数版本控制系统完全不同。
尝试存储每个文件的历史记录不会麻烦。而是将历史记录存储在树级别。
执行差异时,您要比较的是两棵树,而不是两个文件。
另一个根本上明智的设计决策是Git如何合并。
合并算法很聪明,但不要试图太聪明。明确的决定是自动做出的,但是如果有疑问,则由用户决定。
这是应该的方式。您不希望机器为您做出这些决定。您永远不会想要它。
这是Git合并方法的基本见解:虽然其他所有版本控制系统都在试图变得更智能,但Git却自称为“愚蠢的内容管理器”,并且这样做更好。
TA贡献1895条经验 获得超7个赞
上面的答案都是正确的,但我认为它们对我来说错过了git轻松合并的中心点。SVN合并要求您保持跟踪并记住已合并的内容,这是一个巨大的PITA。从他们的文档:
svn merge -r 23:30 file:///tmp/repos/trunk/vendors
现在这不是杀手er,但是如果您忘记了它是23-30包含式还是23-30包含式,或者您是否已经合并了其中一些提交,就变得无所适从,必须找出答案以避免重复或丢失提交。如果您分支了,上帝会帮助您。
有了git,它只是git merge,而这一切都是无缝进行的,即使您选择了几次提交或完成了许多梦幻般的git-land事情。
- 3 回答
- 0 关注
- 579 浏览
添加回答
举报