29

我听说许多分布式 VCS(git、mercurial 等)比 Subversion 等传统 VCS 更擅长合并。这是什么意思?他们做了哪些事情来让合并变得更好?这些事情可以在传统的 VCS 中完成吗?

额外的问题:SVN 1.5 的合并跟踪是否完全符合竞争环境?

4

5 回答 5

26

SVN 的合并能力不错,简单的合并场景也能正常工作——例如发布分支和主干,其中主干跟踪 RB 上的提交。

更复杂的场景会很快变得复杂。例如,让我们从一个稳定的分支 ( stable) 和trunk.

你想演示一个新特性,并且更喜欢基于它stable,嗯,比 更稳定trunk,但是你希望你的所有提交也被传播到trunk,而其他开发人员仍在修复stable和开发东西上trunk

因此,您创建了一个demo分支,合并图如下所示:

  • stable -> demo -> trunk(你)
  • stable -> trunk(其他开发者)

但是,当您将更改从stableintodemo合并,然后再合并demotrunk,而其他开发人员也一直在合并stable到时,会发生trunk什么?SVN 与stable两次合并到trunk.

有一些方法可以解决这个问题,但是对于 git/Bazaar/Mercurial,这根本不会发生 - 他们意识到提交是否已经被合并,因为他们在它所采用的合并路径中标识了每个提交。

于 2009-01-20T18:04:59.367 回答
19

大多数答案似乎是关于 Subversion 的,所以这里有一个关于 Git(和其他 DVCS)的答案。

在分布式版本控制系统中,当您将一个分支合并到另一个分支时,您会创建新的合并提交,它会记住您如何解决合并,并记住合并的所有父级。在 1.5 版之前的 Subversion 中根本就缺少这些信息;为此,您必须使用其他工具,例如 SVK 或 svnmerge。在进行重复合并时,此信息非常重要。

多亏了这些信息,分布式版本控制系统 (DVCS) 可以自动为任何两个分支找到共同祖先(或共同祖先),也称为合并基础。看看下面的 ASCII-art 修订图(我希望它没有被严重破坏),

---O---*---*----M---*---*---1
     \ /
       \ - -* - -A2

如果我们想将分支“2”合并到分​​支“1”,我们想要用来生成合并的共同祖先将是标记为“A”的版本(提交)。但是,如果版本控制系统没有记录有关合并父级的信息(“M”是相同分支的先前合并),它将无法找到提交“A”,它会找到提交“O”作为共同的祖先(合并基础)......这将重复已经包含的更改并导致大的合并冲突。

分布式版本控制系统必须从一开始就做对,即他们必须使合并非常容易(无需标记/标记合并父级,并手动提供合并信息),因为让其他人获取代码的方式into project 不是给他/她提交访问权限,而是从他/她的存储库中提取:从另一个存储库获取提交并执行合并。

您可以在 Subversion 1.5 中找到有关合并的信息。在Subversion 1.5 发行说明中。注意问题:您需要不同的(!)选项将分支合并到主干而不是将主干合并到分支,也就是。并非所有分支都是平等的(在分布式版本控制系统中,它们[通常]在技术上是等效的)。

于 2009-01-27T21:07:11.840 回答
4

1.5 中的合并跟踪比没有合并跟踪要好,但它仍然是一个非常手动的过程。我确实喜欢它记录哪些 rev 合并和未合并的方式,但它远非完美。

Merge 在 1.5 中有一个不错的对话框。您可以选择要单独合并的修订版或整个分支。然后,您触发在本地发生的合并(并且永远持续),然后为您提供一堆文件供您阅读。您需要从逻辑上检查每个文件的正确行为(最好通过对文件的单元测试运行),如果有冲突,则必须解决它们。一旦您感到高兴,您就可以提交您的更改,此时分支被认为是合并的。

如果你分片做,SVN会记住你之前说的你已经合并了,允许你合并。我发现一些合并的过程和结果至少可以说很奇怪......

于 2009-01-20T02:12:03.423 回答
3

这些版本控制系统可以做得更好,因为它们有更多的信息。

SVN pre-1.5,以及最新一代之前的大多数 VCS,实际上并不记得您在任何地方合并了两个提交。它记得这两个分支在第一次分支时共享一个共同的祖先,但它不知道任何可以用作共同点的最近合并。

我对 SVN post 1.5 一无所知,所以也许他们对此有所改进。

于 2009-01-20T04:34:25.960 回答
2

轻率的回答:为什么有些编程语言在文本/数学方面比其他语言更好?

真正的答案:因为他们必须是。分布式 VCS 进行大部分合并时,冲突代码的作者都无法手动调整合并,因为合并是由第三方完成的。结果,合并工具大多数情况下都必须正确处理。

与 SVN 签订合同,如果你最终合并了一些你没有写过一侧或另一侧的东西,那么你正在做一些时髦的事情(而且是错误的?)。

IIRC 大多数 VCS 可以根据您要求他们使用的任何内容进行合并,因此(理论上)没有什么可以阻止 SVN 使用 GIT/mercurial 合并引擎。YMMV

于 2009-01-20T02:03:26.047 回答