为什么Mercurial中的分支和合并比Subversion更容易?

时间:2008-09-04 15:16:37

标签: svn git version-control mercurial

在Subversion或CVS中处理多个合并到分支上只是必须经历的事情之一。在Mercurial(以及可能是任何其他分布式系统)中跟踪分支和合并非常容易,但我不知道为什么。还有其他人知道吗?

我的问题源于这样一个事实:使用Mercurial你可以采用类似于Subversions / CVSs中央存储库的工作实践,一切都会正常工作。您可以在同一分支上进行多次合并,并且不需要使用提交编号和标记名称的无数废纸。

我知道最新版本的Subversion能够跟踪合并到分支机构,所以你不会得到相同程度的麻烦,但这是一个巨大而重大的发展,但它仍然没有做到开发团队希望这样做。

它的运作方式必然存在根本区别。

6 个答案:

答案 0 :(得分:115)

  

在Subversion(和CVS)中,存储库是首要的。在git   而mercurial并没有真正的存储库概念   同样的方式;这里的变化是中心主题。

1

CVS / SVN的麻烦来自这些系统的事实 记住变化的父母身份。在Git和Mercurial, 提交不仅可以有多个子节点,它也可以有多个子节点 父母!

使用其中一个图形工具gitkhg view可以很容易地观察到这种情况。在以下示例中,分支#2从#1分叉 提交A,并且已经合并一次(在M,与提交B合并):

o---A---o---B---o---C         (branch #1)
     \       \
      o---o---M---X---?       (branch #2)

注意A和B有两个孩子,而M有两个父母。这些 在存储库中记录关系。让我们说维护者 分支#2现在想要合并分支#1的最新变化,他们可以 发出如下命令:

$ git merge branch-1

该工具会自动知道 base 是B - 因为它 记录在提交M,#2的尖端的祖先 - 和 它必须合并发生的任何事情 在B和C之间.CVS不会记录此信息,SVN也不会记录此信息 版本1.5。在这些系统中,图表 看起来像是:

o---A---o---B---o---C         (branch #1)
     \    
      o---o---M---X---?       (branch #2)

其中M只是A和B之间发生的一切巨大的“压扁”提交, 应用于M之上。请注意,在完成契约后,无痕迹 M的所在地<(可能在人类可读的评论中除外) 源于,而且多少提交被折叠在一起 - 制作 历史更加难以捉摸。

更糟糕的是,执行第二次合并变成了一场噩梦:人们必须弄明白 第一次合并时合并基础是什么(一个 知道 首先是合并!),然后 将该信息提供给该工具,以便它不会尝试重放A..B 在密切合作中,所有这一切都很困难,但是 在分布式环境中根本不可能。

(相关)问题是没有办法回答这个问题:“X 含有B?“其中B是a 可能很重要的bug修复。那么,为什么不在提交中记录该信息,因为 在合并时它是已知的

P.-S。 - 我没有SVN 1.5+合并录制功能的经验,但工作流程似乎更多 设计比分布式系统。如果情况确实如此,那可能是因为 - 如上所述 在上面的评论中 - 重点放在存储库组织而不是变更本身。

答案 1 :(得分:12)

因为Subversion(至少1.4版及更低版本)无法跟踪已合并的内容。对于Subversion,合并与任何提交基本相同,而在其他版本控制(如Git)上,已经合并的内容会被记住。

答案 2 :(得分:7)

由于已经提供的任何答案都未触及,Hg提供了卓越的合并功能,因为它在合并更改时使用了更多信息(hginit.com):

  

例如,如果我改变了一个函数a   一点点,然后把它移到某个地方   否则,Subversion并不是真的   记住那些步骤,所以当它到来时   合并的时候,可能会认为是   新功能刚出现了   蓝色。而Mercurial会记住   那些东西分开:功能   改变,功能移动,这意味着   如果你也改变了这个功能   一点点,它更有可能   Mercurial将成功合并   我们的变化。

当然,记住最后合并的内容(这里提供的大多数答案所解决的问题)也是一个巨大的胜利。

然而,这两个改进都是有问题的,因为subversion 1.5+以subversion属性的形式存储了额外的合并信息:可用的信息,没有明显的理由说明subversion合并无法像Hg或Git那样成功实现合并。我不知道它是否确实如此,但它肯定听起来像颠覆开发者正在解决这个问题。

答案 3 :(得分:4)

我想这可能部分是因为Subversion有一个中央服务器的概念以及绝对的修订时间线。 Mercurial是真正的分布式,没有绝对时间线的参考。这确实允许Mercurial项目形成更复杂的分支层次结构,以便通过子项目添加功能和测试周期,但是团队现在需要更加积极地保持合并以保持最新状态,因为他们不能只是点击更新并完成它

答案 4 :(得分:3)

在Subversion(和CVS)中,存储库是首要的。在git和mercurial中,并没有以相同的方式存储库的概念;这里更改是中心主题。

我对你的实现方式并没有多想,但我的印象(基于痛苦的经验和大量的阅读)是这种差异使得在基于非存储库的系统中合并和分支变得更加容易。< / p>

答案 5 :(得分:1)

我只有Subversion的经验,但我可以告诉你,TortoiseSVN中的合并屏幕非常复杂。幸运的是,它们包括一个干运行按钮,以便您可以看到您是否正确行事。复杂性在于您要合并到哪里的配置。一旦你为合并设置了合并,合并通常会很好。然后,您需要解决所有冲突,然后将合并的工作副本提交到存储库。

如果Mercurial可以使合并的配置更容易,那么我可以说这将使合并比Subversion更容易100%。