重新整合分支而不合并主干更改

1 svn tortoisesvn merge feature-branch

我用乌龟svn.但总的来说,我对svn还是比较新的.我有一些git的经验.

在文件中说

重新整合分支

这个方法涵盖了Subversion书中讨论的功能分支的情况.所有主干更改都已逐周移植到功能分支,现在功能已完成,您希望将其合并回主干.

据我所知:功能分支的正常工作流程是,要创建一个功能分支,在其上进行开发,经常在主干分支上的错误修正的修订范围内合并.功能完成后,最后合并主干更改,然后将分支重新集成到主干中.

所以我有一些问题:

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

Dav*_* W. 8

首先,快速学习合并如何工作,适用于几乎所有版本控制系统.

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

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

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

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


现在Subversion如何处理合并:

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

事实上,即使你没有指定樱桃挑选版本,Subversion几乎总是会选择合并.Subversion跟踪通过svn:mergeinfo属性合并的修订版本.假设我在修订版100中分支,现在我将我的主干更改合并到我的分支中.trunk的最后一个版本现在是版本150.Subversion认为你正在从版本100(但不包括版本100)到版本150上的所有版本的樱桃选择.下次我从我的主干到我的合并分支(假设我的主干上的最后一次更改现在是175),Subversion将挑选主干上的更改(但不包括150)到版本175.

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

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

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

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

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

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

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

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

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

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

有两种方法可以解决这个问题:方法一:进行重新整合合并后,再也不应该使用该功能分支了.删除它.把它锁在一个尼姑庵里.再也不说出它的名字了.如果我再次需要该功能分支,我应该从trunk创建一个新的功能分支.

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

$ svn co $REPO/branches/feature/myproj
$ cd myproj
$ svn merge --record-only -r102 $REPO/trunk/myproj
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,所有这些手动工作 - 知道何时使用该--reintegration开关并了解当您进行重新整合合并时会发生什么- 引起了混乱.因此,较新版本的Subversion(我相信自1.8版本以来)现在尝试为您处理此问题.

如果您使用Subversion 1.8作为客户端,则永远不必指定--reintegration参数.Subversion将以编程方式确定您是在进行典型的三向合并还是重新整合合并并相应地采取行动.

如果我试图做Subversion认为重新整合合并,并且我尚未将我的所有主干修订合并到我的功能分支中,Subversion将警告我,不要让我进行合并.如果我在进行重新集成合并后重用功能分支,Subversion就会检测到这一点,并在重新集成后自动处理分支重用的问题.(有时它不会很有用.但是,Subversion不会让你在重新整合合并后重用功能分支,但可能会给你一个错误,你可能不得不手动进行--record-only合并.)


那么在Subversion中,您应该如何进行工作流程?

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

如果在主干上发现了一个错误,它可以在主干上修复,修复该bug的修订版或修订版可以合并到发布分支上.或者,如果您发现需要在主干上修复功能分支上的错误,您可以在功能分支上修复该错误,并将该修订版或修订集合并到主干上.

它简单,直接,易于实施.

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

并且,如果你想疯狂地为每个功能和bug创建大量的分支,你也可以这样做.但是,我建议你使用Subversion 1.8,它会为你做到这一点.