我听说许多分布式VCS(git,mercurial等)在合并方面比Subversion等传统方式更好.这是什么意思?他们做了什么样的事情才能让合并变得更好?这些事情可以在传统的VCS中完成吗?
奖金问题:SVN 1.5的合并跟踪水平是否适合公平竞争?
SVN的合并功能很不错,简单的合并方案工作正常 - 例如发布分支和主干,其中trunk跟踪RB上的提交.
更复杂的场景变得复杂得多.例如,让我们从一个稳定的分支(stable
)开始trunk
.
你想要演示一个新功能,并且更喜欢以它为基础stable
,更好,更稳定trunk
,但你希望所有的提交都能传播到其中trunk
,而其他的开发人员仍在修复stable
和开发内容在trunk
.
因此,您创建一个demo
分支,合并图如下所示:
stable -> demo -> trunk
(您)
stable -> trunk
(其他开发者)
但是,当你改变合并从发生的事情stable
到demo
,然后合并demo
到trunk
,而所有的时间其他开发商也被合并stable
到trunk
?SVN对stable
合并两次合并感到困惑trunk
.
有很多方法,但是使用git/Bazaar/Mercurial这根本不会发生 - 他们意识到提交是否已经合并,因为它们在合并路径中对每个提交进行ID.
大多数答案似乎都与Subversion有关,所以这里有一个关于Git(和其他DVCS)的答案.
在分布式版本控制系统,当您合并一个分支到另一个,创建新的合并提交,它会记住你如何解决合并,并记住合并的所有家长.在版本1.5之前的Subversion中缺少这些信息; 你必须使用其他工具,如SVK或svnmerge.重复合并时,此信息非常重要.
由于这些信息,分布式版本控制系统(DVCS)可以自动找到任何两个分支的共同祖先(或共同祖先),也称为合并基础.看一下以下版本的ASCII-art图表(我希望它没有太可怕的损坏),
---O---*---*----M---*---*---1 \ / \---*---A/--*----2
如果我们想将分支'2'合并到分支'1'中,我们想要用来生成合并的共同祖先将是标记为'A'的版本(提交).但是,如果版本控制系统没有记录有关合并父项的信息('M'是先前合并的相同分支),它将无法找到提交'A',并且它将找到提交'O'作为共同的祖先(合并基础)而不是...这将重复已经包含的更改并导致大的合并冲突.
分布式版本控制系统必须正确执行,即他们必须从一开始就非常容易地进行合并(无需标记/标记合并父项,并手动提供合并信息),因为获取其他人获取代码的方式进入项目不是为了给他/她提交访问权限,而是从他/她的存储库中提取:从其他存储库获取提交并执行合并.
您可以在Subversion 1.5中找到有关合并的信息.在Subversion 1.5发行说明中.需要注意的问题:您需要使用不同的(!)选项将分支合并到主干,而不是合并主干到分支,也就是说.并非所有分支都相同(在分布式版本控制系统中,它们[通常]在技术上是等效的).