【发布时间】:2010-10-02 08:57:32
【问题描述】:
我听说许多分布式 VCS(git、mercurial 等)比 Subversion 等传统 VCS 更擅长合并。这是什么意思?他们做了哪些事情来让合并变得更好?这些事情可以在传统的 VCS 中完成吗?
额外问题:SVN 1.5 的合并跟踪是否完全符合竞争环境?
【问题讨论】:
标签: svn git version-control mercurial merge
我听说许多分布式 VCS(git、mercurial 等)比 Subversion 等传统 VCS 更擅长合并。这是什么意思?他们做了哪些事情来让合并变得更好?这些事情可以在传统的 VCS 中完成吗?
额外问题:SVN 1.5 的合并跟踪是否完全符合竞争环境?
【问题讨论】:
标签: svn git version-control mercurial merge
SVN 的合并能力不错,简单的合并场景运行良好 - 例如发布分支和主干,主干跟踪 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,这根本不会发生 - 他们意识到提交是否已经被合并,因为他们在合并路径上标识了每个提交。
【讨论】:
大多数答案似乎都是关于 Subversion,所以这里有一个关于 Git(和其他 DVCS)的答案。
在分布式版本控制系统中,当您将一个分支合并到另一个分支时,您会创建新的合并提交,它会记住您如何解决合并,并记住合并的所有父项。在 1.5 版之前的 Subversion 中根本就缺少这些信息;为此,您必须使用其他工具,例如 SVK 或 svnmerge。在进行重复合并时,此信息非常重要。
借助这些信息,分布式版本控制系统 (DVCS) 可以自动为任意两个分支找到共同祖先(或共同祖先),也称为合并基础。看看下面的 ASCII-art 修订图(我希望它没有被弄得太糟糕),
---O---*---*----M---*---*---1 \ / \ - -* - -A2如果我们想要将分支“2”合并到分支“1”,我们想要用来生成合并的共同祖先将是标记为“A”的版本(提交)。但是,如果版本控制系统没有记录有关合并父级的信息(“M”是相同分支的先前合并),它将无法找到提交“A”,它会找到提交“O”而是作为共同祖先(合并基础)...这将重复已经包含的更改并导致大的合并冲突。
分布式版本控制系统必须从一开始就做对,即他们必须使合并非常容易(无需标记/标记合并父级,并手动提供合并信息),因为获得其他人的方式将代码放入项目不是授予他/她提交访问权限,而是从他/她的存储库中提取:从另一个存储库获取提交并执行合并。
您可以在 Subversion 1.5 中找到有关合并的信息。在Subversion 1.5 Release Notes。注意问题:您需要不同 (!) 选项将分支合并到主干,而不是将主干合并到分支,也就是。并非所有分支都是平等的(在分布式版本控制系统中,它们[通常]在技术上是等效的)。
【讨论】:
1.5 中的合并跟踪比没有合并跟踪要好,但它仍然是一个非常手动的过程。我确实喜欢它记录哪些 rev 已合并和未合并的方式,但它远非完美。
Merge 在 1.5 中有一个不错的对话框。您可以选择要单独合并的修订版或整个分支。然后,您触发在本地发生的合并(并且永远持续),然后为您提供一堆文件供您阅读。您需要从逻辑上检查每个文件的行为是否正确(最好通过对文件进行单元测试),如果有冲突,则必须解决它们。一旦您感到高兴,您就可以提交您的更改,此时该分支被视为合并。
如果你是零碎的,SVN会记住你之前说的你已经合并了,允许你合并。我发现一些合并的过程和结果至少可以说很奇怪......
【讨论】:
这些版本控制系统可以做得更好,因为它们有更多的信息。
1.5 之前的 SVN 以及最新一代之前的大多数 VCS,实际上并不记得您在任何地方合并了两个提交。它记得这两个分支在第一次分支时共享一个共同的祖先,但它不知道任何可以用作共同点的最近合并。
我对 SVN 1.5 后一无所知,所以也许他们对此有所改进。
【讨论】:
轻率的回答:为什么有些编程语言在文本/数学方面比其他语言更好?
真正的答案:因为他们必须如此。分布式 VCS 进行大部分合并时,冲突代码的作者都无法手动调整合并,因为合并是由第三方完成的。因此,合并工具必须在大多数情况下正确处理。
在与 SVN 的合同中,如果你最终合并了一些你没有写过一侧或另一侧的东西,那么你就是在做一些时髦的事情(而且是错误的?)。
IIRC 大多数 VCS 可以根据您要求他们使用的任何内容进行合并,因此(理论上)没有什么可以阻止 SVN 使用 GIT/mercurial 合并引擎。 YMMV
【讨论】: