4

svnmerge 有助于阻止来自特定分支的一些变更集。Mercurial 如何实现这一点?

4

1 回答 1

6

subversion 所谓的合并与 Mercurial 中的合并完全不同。svnmerge 或svn merge所做的操作在其他版本控制系统中通常被称为“樱桃采摘”。基本上它会创建一个新的提交,它是目标分支中原始变更集的副本。在 Mercurial 中,可以使用移植扩展来完成。

与常规合并相比,这种方法在 DVCS 中不太流行,因为它会创建多个头,这些头更难维护。以下是您将如何使用它以及结果输出的样子:

$ hg checkout -r 8
$ hg branch release
$ hg transplant 10
applying 8ba2867cf974
8ba2867cf974 transplanted to 1f5920f61c94

7---8---9---A [default]
     \
      B [release]

在这里,您的提交 A 修复了主干上的错误,您hg transplant将其发布,创建了一个新的提交 B,其中包含与 A 相同的更改,但具有不同的父级。

一种方法是不使用移植,只签入发布分支的修复。您将创建一个新的发布分支并在那里进行修复,然后将发布分支合并为默认分支。看起来像这样:

$ hg checkout -r 8
$ hg branch release
... fix fix fix ...
$ hg commit -m"Make fix A"
$ hg checkout -r 9
$ hg merge release
1 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg commit -m"Merged release branch"

7---8---9---B- [default]
     \     /
      A---- [release]

这里 B 是一个合并提交。它没有与之关联的“额外”更改(除非解决了冲突),并且具有将发布分支标记为在该点合并到默认值的特殊属性。只有一个实际的变更集可以修复这个错误——标记为“A”的那个——当然,这些变更本身也在默认分支中。

这种方法的优点是:

  • 只有一个头。这对开发人员来说不那么混乱,并且给人一种很好的封闭感
  • 你可以一目了然地看到 default 包含 release 中的所有错误修复
  • 你可以看到发布有重要的错误修复

通常,您会在适当的位置标记发布分支“v1.1”或其他任何内容,以便您知道该发布的来源。

这种方法的缺点是:

  • 版本太旧了,合并到默认会导致冲突
  • 您不想合并到默认版本中的更改与您确实想要的更改混合在一起

对于第一个问题,您无能为力 - 如果您必须维护一个非常旧的分支,那么无论如何您最终都会有不同的分支。无论如何,补丁可能非常不同。

第二个问题发生在例如,如果您对发布版本有一个“紧急”补丁来解决或解决错误,但需要在默认情况下进行更大的修复以解决潜在问题。在这种情况下,您必须合并发布,然后创建一个新的显式提交以“撤消”您不想要的提交。

这种做法实际上在某种程度上具有类似的优势svn merge。如果您有选择地将更改从主干合并到发布,您必须记住您合并的修订(假设您没有合并所有主干)。svn merge设置 svn:mergeinfo 属性,但是跟踪这些可能会导致问题,而且您必须仔细检查日志以说“哦,是的,我确实将该修复合并到发布中”。

If you svn-merge the whole release branch to trunk when you have a fix, there is no need to remember what revisions have been merged.

于 2009-07-09T19:02:34.037 回答