1

我用乌龟svn。但总的来说,我对 svn 还是很陌生。不过,我对 git 有一些经验。

在文档中它说

重新整合分支

此方法涵盖了您已按照 Subversion 书中讨论的那样创建功能分支的情况。所有主干更改都已逐周移植到功能分支,现在功能已完成,您希望将其合并回主干。

据我了解:功能分支的正常工作流程是,创建一个功能分支,在其上进行开发,经常合并来自主干分支上的错误修复的修订范围。功能完成后,对主干更改进行最终合并,然后将分支重新集成到主干中。

所以我有一些问题:

  1. 这个工作流程是否正确
  2. 如果我在重新集成功能分支之前不合并来自主干分支的更改会发生什么
  3. 如果我从完全更新的功能分支到主干分支进行正常合并会发生什么
  4. 为什么这么复杂,svn 的本意是比 git 对用户更友好,但尤其是合并,你必须指定要合并到功能分支的修订,并且从不同的合并选项中进行选择似乎比等效的 git 功能要复杂得多(我必须在我的公司使用 svn,因为其他开发人员使用它,但他们没有分支),除非我做错了什么
4

2 回答 2

8

首先是关于合并如何工作以及适用于几乎所有版本控制系统的快速课程。

标准 Merge 是三路合并。在此,您将两个版本与两个版本的最后一个共同祖先进行比较。例如,我从主干分支。分支之前的主干上的版本是最后一个共同祖先

目的是能够查看一个上的更改与另一上的更改。(流可以是特定的分支或主干)。例如,如果我从主干合并到分支,我想确保不会用主干上的那些行覆盖我的特定分支更改。

与最后一个共同祖先的比较允许您仅查看自该分支点以来在主干上发生的更改。

当我从以前的合并中倒退时,这会出现问题。例如,我完成了我的功能分支,并希望所有功能更改都回到主干上。这是一个问题,因为我已将所有主干更改合并到分支上。这意味着我的分支的显示我对分支进行了更改,这些应该合并到主干中。但是,这些变化已经在主干上!要处理此问题,您可以强制进行双向合并。在这种情况下,您只是将两个单独流的头部相互比较,并将所有差异从一个流复制到另一个流。


现在 Subversion 如何处理合并:

首先,Subversion 喜欢cherry pick mergin。Subversion 允许您指定要合并的版本。例如,我有一个分支,发现了一个错误并在分支上修复了它。我现在可以合并包含我的错误修复的特定修订或修订集。当您在 Subversion 中挑选樱桃时,您正在执行三路合并,但您只考虑那些特定樱桃挑选版本中表示的更改,而不是主干或分支上的所有更改。

事实上,Subversion 几乎总是会进行cherry pick 合并,即使您没有指定cherry pick 修订版。svn:mergeinfoSubversion 跟踪通过该属性合并了哪些修订。假设我在修订版 100 处分支,现在我将主干更改合并到我的分支中。主干上的最后一个修订版现在是修订版 150。Subversion 认为您正在从修订版 100(但不包括版本 100)到修订版 150 的所有主干版本中进行挑选。下次我从我的主干合并到我的分支(假设我的主干上的最后一个更改现在是 175),Subversion 将在主干上挑选从(但不包括 150)到修订版 175 的更改。

请注意,当我为合并指定樱桃选择修订时,我可以在我的分支和我的主干之间来回切换而不会出现任何问题。如果我从我的功能分支合并到我的主干,我可以在我实现该功能的功能分支上指定修订,并跳过我的功能分支上的更改,这些更改是从主干合并的结果。

只有当我让 Subversion 处理樱桃采摘时,问题才会出现。当我从我的主干合并到我的分支时,Subversion 会跟踪我的主干在我的分支上的修订。但是,Subversion 无法知道我的功能分支上的哪些修订是我的主干合并的结果。

因此,当我将我的功能分支合并回主干时,Subversion 将考虑所有未合并的修订——包括那些作为主干到分支合并结果的修订,并尝试将所有这些修订合并回我的主干。

为了处理这个问题,Subversion 有一个特殊的合并,称为重新集成合并。我将我在主干上的最后一组更改合并到我的分支中,然后当我将我的分支合并到我的主干中时,我希望我的主干和分支是相同的。因此,Subversion 想要进行双向合并并使主干和分支匹配。

在旧版本的 Subversion 中,我必须手动指定我正在使用命令--reintegration上的参数进行这种双向合并。svn merge

Subversion 的合并跟踪也导致了重用功能分支的有趣问题。假设我做了最后一组从主干到分支的合并。主干上的最后一个修订版和 Subversion 中的最后一个修订版是修订版 100。当我将主干上的更改合并到我的分支上时,我现在在我的分支上创建了修订版 101。该svn:mergeinfo分支上的属性显示我已将所有更改从主干合并到修订版 100 仅我的分支。

现在,我进行重新集成合并,提交更改,并在我的主干上创建修订版 102。

现在,我在我的主干上做了更多的工作(比如说修订版 103),我想将这些更改合并到我的功能分支中。

我从主干合并到功能分支的最后一个版本是什么?查看svn:mergeinfo,我看到它是修订版 100。自从上次从主干合并到分支以来,主干上现在有两个新修订版尚未合并到我的功能分支中:修订版 102 和修订版 103。

因此,Subversion 会挑选并尝试将修订版 102 和修订版 103 中包含的更改合并到我的功能分支中。但是等等……修订版 102 是我所有的功能分支更改都被合并到主干上!我将把这些特性更改重新应用到我的特性分支上!

有两种方法可以解决这个问题: 方法一:一旦你进行了重新集成合并,你永远不应该再使用那个特性分支。删除它。把它锁在尼姑庵里。永远不要再说出它的名字。如果我再次需要那个特性分支,我应该从主干创建一个新的特性分支。

另一种方法是svn:mergeinfo修改功能分支,让 Subversion 知道主干上的修订版 102 已经合并到我的功能分支中。您可以使用以下--record-only参数执行此操作:

$ svn co $REPO/branches/feature/myproj
$ cd myproj
$ svn merge --record-only -r102 $REPO/trunk/myproj

如您所见,所有这些手动工作——知道何时使用该开关并了解在进行重新集成--reintegration合并时会发生什么——导致了混乱。因此,较新版本的 Subversion(我相信是从 1.8 版开始)现在尝试为您处理这个问题。

如果您使用 Subversion 1.8 作为客户端,则无需指定--reintegration参数。Subversion 将以编程方式确定您是在进行典型的三向合并还是重新集成合并,并采取相应的行动。

如果我尝试执行 Subversion 认为的重新集成合并,并且我还没有将所有主干修订合并到我的功能分支中,Subversion 会警告我并且不让我进行合并。如果我在重新集成合并后重用功能分支,Subversion 应该会检测到这一点并在重新集成后自动处理分支重用问题。(有时它并不能很好地工作。但是,Subversion 不会让您在重新集成合并后重用功能分支,但可能会给您一个错误,您可能必须手动进行--record-only合并。)


那么在 Subversion 中,你应该如何做你的工作流程呢?

与 Git 不同的是,每个 bug 和功能都应该在自己的分支上,您至少需要将该 bug 修复或功能合并到多个分支上,您几乎可以在主干(或任何您喜欢的分支)上完成所有工作。在大多数 Subversion 商店中,仅针对候选版本进行分支。也就是说,我即将发布一个版本,我为该版本分支。一些开发人员致力于发布,其他开发人员继续他们的主干工作。

如果在主干上发现错误,则可以在主干上对其进行修复,并且可以将修复了该错误的那个修订或一组修订合并到发布分支中。或者,如果您在功能分支上发现需要在主干上修复的错误,您可以在功能分支上修复该错误并将该修订或一组修订合并到主干上。

它简单、直接且易于实施。

这并不意味着您不能为某个功能分支。事实上,有时你必须这样做。想象一个在未来深入实施的功能。您不希望在主干上进行这些更改。在这种情况下,创建特性分支,并定期将主干更改合并到该特性分支上。请记住,当您将该功能合并回主干时可能会出现问题。只要你明白发生了什么。没问题。

而且,如果您想疯狂地为每个功能和错误创建大量分支,您也可以这样做。但是,我建议您使用 Subversion 1.8,它会为您做到这一点。

于 2014-04-02T16:36:18.690 回答
0
  1. 或多或少

  2. 从主干到功能分支的频繁合并的要点是它是零碎的:小且易于管理。当冲突出现时,可以通过您脑海中的新鲜变化来解决它们。如果您在重新集成之前不将更改从主干合并到功能分支,则不会发生任何“坏事”。只是你必须同时处理所有更改的合并,这可能会产生很多冲突,并且您甚至可能不记得导致冲突的代码部分,从而使您重新学习该代码并花费更多时间来解决冲突。如果您的主干和功能分支每天同步,那么每天只需多花 5 分钟来执行同步并清除冲突即可。如果你把它留到特性分支结束,你可能会花一两天时间一次性解决所有冲突。

  3. 请参阅Reintegrate a branch vs merge a range of revision在 SVN 中合并一系列修订与重新集成有什么区别?不使用 --reintegrate 与 svn 合并回主干的后果

  4. SVN 比 git 更加用户友好。它是集中式的,具有 TortoiseSVN 形式的出色 Windows GUI。最新版本的 TortoiseSVN 删除了“重新集成”选项,因为它会在您这样做时自动计算出来。当您选中要合并的修订时,它将将此信息存储在 SVN 中,因此下次您可以轻松直观地查看哪些修订已被签入,依此类推。

于 2014-04-02T13:58:24.167 回答