有两种类型在颠覆合并的:
- 三点合并
- 两点合并(又名重返合并)
假设您正在使用trunk,并且您需要完成一项特定功能。您创建一个功能A分支。当您使用该功能时,您需要将中继所做的工作纳入功能A,以便您可以跟上其他人的工作。 Subversion将使用三点合并。
Subversion将从分支发生的位置查看树干和分支特征A之间的区别。最近的共同祖先。然后它会考虑已完成的功能A上的所有更改(您不想触及的)以及中继线上完成的代码更改。
Subversion然后将合并主干上的更改而不覆盖分支上所做的更改。标准的合并过程,Subversion做得很好。
svn:mergeinfo
在哪里?您不想合并两次相同的更改,因此Subversion使用svn:mergeinfo
属性跟踪更改。如果Subversion看到版本5中主干的变化已经被合并,它不会重新发生这种变化。这是非常好的。
现在,您已完成了您的功能,并且希望将这些更改合并回主干。你做最后一个主干分支合并,提交这些更改,现在从Feature分支合并回主干。
这是一个问题。我们通过svn:mergeinfo
跟踪我们从干线合并到Feature分支中的内容。但是,由于我们尚未从Feature分支合并到主干,因此在那里没有svn:mergeinfo
。如果我们尝试从Feature分支进入正常的三点合并到主干,则主干将假定Feature分支中的所有更改都应合并回主干。但是,其中许多功能实际上是已合并的主干更改。
事实上,在这一点上,我们想要做一个两点合并。我们希望trunk和Feature分支在我们进行合并时完全匹配。毕竟,我们现在已经定期将树干合并到Feature分支中。我们想要做的就是将这些功能重新加入后备箱。因此,主干将与特征分支相同。
在Subversion 1.8之前,您必须通过运行svn merge --reintegration
来强制执行重新集成合并。现在,Subversion会查看合并历史记录,并确定何时应该进行重新合并合并。
现在这里是棘手的部分。仔细查看版本号。这些将会非常非常重要!
- 修订10:这是我最后变成树干,我需要将这些合并到功能分支。
- 修订11:我合并中继到功能分支。
svn:mergeinfo
将显示从版本1到版本10的所有主干都位于特征分支中。由于主干上的最后更改是版本10,因此这非常合理。
- 修订12:我将Feature Branch的版本11合并到主干中。这是一个重新整合合并。在此之后,Feature分支上的内容和Trunk中的内容应该完全一致。
现在,这里是踢球者!
现在,我想合并到我的功能分支(创建修订14)。现在,功能部件上的svn:mergeinfo
说什么?它表示从版本1到版本10的主干已经合并到Feature分支中。不过,主干版本12和版本13没有。因此,Subversion需要将版本12和版本13重新合并到Feature分支中。
但等一下!
版本12的主干是我的功能分支中的所有更改合并回主干!也就是说,版本12已经包含了我在Feature分支中所做的所有版本更改。如果我将版本12合并到我的Feature分支中,我会说所有这些在主干上修订版本12的变化(这些变化是在特征分支上进行的,并且合并到主干中)需要合并到特征分支上。但是,这些更改也是在Feature分支上进行的。你能说合并冲突吗?我知道你可以!
有处理这种双向的:
- 推荐的方法:一旦你重返社会的特性分支回主干,删除分支。锁定它。切勿再次使用它。不要碰!这并不像听起来那么糟糕。重新整合合并后,您的主干和该功能分支无论如何都会匹配。从trunk中删除和重新创建分支并不会那么糟糕。
- 工作的棘手方式:我们需要做的是让Subversion认为修订版#12(或重新整合合并更改)已经合并到我们的Feature分支中。我们可以与
svn:mergeinfo
财产争执。而且,我用它来做那件事。它说trunk:1-11
,我会手动将其更改为trunk:1-12
。
这很棘手,但方式太棘手,并且有风险,因为Subversion已经为您提供了一种操作svn:mergeinfo
而无需手动更改的方法。
它被称为记录只有合并。
$ svn co svn://branches/feature_a
$ cd feature_a
$ svn merge --record-only -c 12 svn://trunk
$ svn commit -m "Adding in the reintegration merge back into the feature branch."
这改变了功能分支上的svn:mergeinfo
而不影响文件的实际内容。没有真正的合并完成,但Subversion现在知道中继线的版本12已经在Feature分支中。一旦你这样做,你可以重用功能分支。
现在看看你的图表:当你合并分公司B插入到A分支,你合并所有的从B变成A,并svn:mergeinfo
追踪到。当您将分支B合并回分支A时,您已经拥有分支A中分支B的所有更改,并且您不希望将这些更改带回分支B.您应该使用重新集成合并:现在
$ cd $branch_a_working_dir
$ svn merge $REPO/branches/B
$ svn commit -m "Rev 7: All of my changes on Branch B are now in A"
$ vi d.txt
$ svn add d.txt
$ svn commit -m"Rev 8: I added d.txt"
$ cd $branch_b_working_dir
$ svn merge --reintegrate svn://branch/A # Note this is a REINTEGRATION merge!
$ svn commit -m"Rev 9: I've reintegrated Branch A into Branch B
,如果我们想继续使用分支用于进一步的修改:
$ cd $branch_a_working_dir
$ svn merge -c 9 --record-only $REPO/branches/b
$ svn commit -m"I've reactivated Branch A and can make further changes"
我希望这解释了一些关于如何svn:mergeinfo
的作品,为什么你要知道你是否正在使用正常的三点合并与两点重新合并合并,以及如何能够重新激活分支后r你已经完成了重新整合合并。
只要你牢记这一点,Subversion合并工作就会很好。
显示真实的输出,而不是图片 - 我看不到您的图纸中可能存在的问题 –
我添加了一个我认为与askers图形匹配的示例。有些地方不清楚。这些文件是否已经存在或是否是新的(我将它们制作成新的,如果发生冲突,其差异将会按照您获得的冲突类型而定)?合并究竟是如何完成的?他们是樱桃选择还是全分支合并。 –
BenReser说得没错。他们是新文件,我正在做一个完整的分支合并。 –