我在Joel on Software上读到:
使用分布式版本控制,分布式部分实际上并不是最有趣的部分。
有趣的部分是这些系统从变化的角度思考,而不是从版本的角度思考。
以及在HgInit上:
通过查看SVN的存储库文件夹,我有印象Subversion将每个版本都维护为“更改集”。从我的了解来看,Hg同时使用“更改集”和“快照”,而Git纯粹使用“快照”来存储数据。当我们需要合并时,Subversion 试图查看两个版本 - 我修改的代码和你修改的代码 - 并尝试猜测如何将它们合并成一个大的混乱。它通常会失败,并产生许多“合并冲突”,这些冲突实际上并不是冲突,只是 Subversion 无法弄清楚我们做了什么的地方。
相比之下,在 Mercurial 中我们分别工作时,Mercurial 忙于保持一系列的变更集。因此,当我们想要合并我们的代码时,Mercurial 实际上拥有更多的信息:它知道我们每个人都做了什么更改,并且可以重新应用这些更改,而不仅仅是查看最终产品并尝试猜测如何将其组合在一起。
如果我的假设正确,那么必须存在其他使DVCS合并变得容易的方法。那些是什么?
*更新:*
- 我更关心技术层面,但非技术层面的回答也可以接受。
- 更正:
- Git的概念模型完全基于快照。这些快照可以存储为其他快照的差异,只是这些差异纯粹是为了存储优化。——Rafał Dowgird的comment
- 从非技术层面来看:
- 这仅仅是文化问题:如果合并很困难,分布式版本控制系统将根本无法工作,因此分布式版本控制系统的开发人员会花费大量时间和精力使合并变得容易。相反,集中式版本控制系统的用户习惯于糟糕的合并,因此开发人员没有动力让它工作。(当你的用户为烂东西付费时,为什么要做好东西呢?)
...
总之,分布式版本控制系统的整个目的就是拥有许多分散的存储库,并不断地在它们之间合并更改。没有良好的合并,分布式版本控制系统就毫无用处。然而,集中式版本控制系统可以在糟糕的合并下仍然存活,特别是如果供应商可以让其用户避免分支。——Jörg W Mittag的answer
- 这仅仅是文化问题:如果合并很困难,分布式版本控制系统将根本无法工作,因此分布式版本控制系统的开发人员会花费大量时间和精力使合并变得容易。相反,集中式版本控制系统的用户习惯于糟糕的合并,因此开发人员没有动力让它工作。(当你的用户为烂东西付费时,为什么要做好东西呢?)
- 从技术角度来看:
- 记录真正的历史DAG确实有所帮助!我认为主要区别在于CVCS并不总是将合并记录为具有多个父项的更改集,从而丢失了一些信息。——tonfa的comment
- 由于合并跟踪,以及更基本的事实,即每个修订版本都知道其父项。...当每个修订版本(每个提交),包括合并提交,都知道其父项时(对于合并提交,这意味着拥有/记住多个父项,即合并跟踪),您可以重构修订历史的图表(DAG = 直接无环图)。如果您知道修订图形,则可以找到要合并的提交的公共祖先。当您的分布式版本控制系统知道如何查找公共祖先时,您不需要将其作为参数提供,例如在CVS中。
.
请注意,两个(或多个)提交可能有多个公共祖先。Git使用所谓的“递归”合并策略,它合并合并基(公共祖先),直到您留下一个虚拟/有效的公共祖先(在某些简化中),然后可以进行简单的3路合并。——Jakub Narębski的answer