关于svn:为什么在Mercurial中分支和合并比在Subversion中更容易?

关于svn:为什么在Mercurial中分支和合并比在Subversion中更容易?

Why is branching and merging easier in Mercurial than in Subversion?

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

我的问题源于以下事实:Mercurial可以采用类似于Subversions / CVS中央存储库的工作方式,并且一切都会正常进行。 您可以在同一个分支上进行多次合并,并且不需要无休止的纸屑,包括提交号和标签名。

我知道最新版本的Subversion具有跟踪合并到分支的能力,因此您不会遇到相同程度的麻烦,但是这对他们来说是一个巨大而重大的发展,并且仍然无法满足开发团队的所有要求 喜欢做。

所有工作方式都必须有根本的区别。


In Subversion (and CVS), the repository is first and foremost. In git
and mercurial there is not really the concept of a repository in the
same way; here changes are the central theme.

+1

CVS / SVN的麻烦来自于以下事实:
记住改变的父母。在Git和Mercurial中,
一个提交不仅可以有多个孩子,还可以有多个孩子
父母!

使用图形工具之一gitkhg
view
可以很容易地观察到这一点。在下面的示例中,分支#2是从分支#1分支到的
提交A,并已合并一次(在M,与提交B合并):

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

请注意,A和B有两个孩子,而M有两个父母。这些
关系记录在存储库中。假设的维护者
现在,分支#2希望合并分支#1的最新更改,他们可以
发出以下命令:

1
$ git merge branch-1

该工具将自动知道基数为B,因为它
记录在提交M中,即提交#2-的先端,并且
它必须合并发生的一切
B和C之间。CVS不会记录此信息,SVN之前也不会记录此信息。
版本1.5。在这些系统中,图形
看起来像:

1
2
3
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
潜在的重要错误修复。因此,为什么不将信息记录在提交中,因为
在合并时就知道了!

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


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


Hg不受任何已经提供的答案的影响,提供了卓越的合并功能,因为它在合并更改时使用更多信息(hginit.com):

For example, if I change a function a
little bit, and then move it somewhere
else, Subversion doesn’t really
remember those steps, so when it comes
time to merge, it might think that a
new function just showed up out of the
blue. Whereas Mercurial will remember
those things separately: function
changed, function moved, which means
that if you also changed that function
a little bit, it is much more likely
that Mercurial will successfully merge
our changes.

当然,记住最后合并的内容(此处提供的大多数答案都解决了这一点)也是一个巨大的胜利。

但是,由于Subversion 1.5+会以Subversion属性的形式存储其他合并信息,因此这两个改进都值得怀疑:该信息可用,没有明显的理由说明Subversion合并不能像Hg或Git那样成功地实现合并。不过,我不知道是否可以,但是听起来确实像是Subversion开发人员正在解决这个问题。


我想这可能部分是因为Subversion具有中央服务器的想法以及绝对的修订时间线。 Mercurial确实是分布式的,没有对绝对时间线的引用。这确实允许Mercurial项目形成更复杂的分支层次结构,以按子项目添加功能和测试周期,但是团队现在需要更加积极地保持合并的顶部,以保持最新状态,因为他们不能仅仅点击update并完成更新。 。


在Subversion(和CVS)中,存储库是最重要的。在git和mercurial中,实际上并没有以相同的方式定义存储库的概念。这里的变化是中心主题。

我也没有考虑过如何实现,但是我的印象(基于痛苦的经验和大量的阅读)是,这种差异使得在非基于存储库的系统中合并和分支变得如此容易。


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

如果Mercurial可以简化合并的配置,那么我可以说那将使Subversion的合并变得100%容易。


推荐阅读