什么时候真正需要重新整合选项?
Posted
技术标签:
【中文标题】什么时候真正需要重新整合选项?【英文标题】:When is the reintegrate option really necessary? 【发布时间】:2010-12-13 10:10:55 【问题描述】:如果您总是在合并之前同步功能分支。为什么你真的必须使用--reintegrate
选项?
Subversion 书说:
但是,当将分支合并回主干时,基础数学是完全不同的。您的功能分支现在是重复的主干更改和私有分支更改的混合体,因此没有简单的连续修订范围可供复制。通过指定 --reintegrate 选项,您要求 Subversion 只仔细复制那些对您的分支唯一的更改。 (事实上,它通过比较最新的主干树和最新的分支树来做到这一点:由此产生的差异正是你的分支变化!)
所以--reintegrate
选项只合并功能分支独有的更改。但是如果你总是在合并之前同步(这是一个推荐的做法,为了处理特性分支上的任何冲突),那么分支之间的唯一变化就是特性分支独有的变化,对吧?如果 Subversion 试图合并已经在目标分支上的代码,它什么也不做,对吧?
在a blog post,Mark Phippard 写道:
如果我们包含这些同步的修订,那么我们会将主干中已经存在的更改合并回来。这会产生不必要且令人困惑的冲突。
有没有一个例子说明放弃 reintegrate 会给我带来不必要的冲突?
【问题讨论】:
【参考方案1】:让我解释一下什么时候--reintegrate
是绝对必要的。
考虑以下用例。
-
您在 p1/trunk 下有项目 p1。该项目有一个文件
readme.txt
,其中有一行“line1”
创建一个新分支,p1/branches/br1
留在后备箱里。将“line2”行添加到readme.txt
并提交到主干
切换到p1/branches/br1
分支。更新到 HEAD。
从主干合并到此分支(以获取主干更改)。
readme.txt
中应该有 line1
和 line2
提交合并结果到p1/branches/br1
分支
切换到中继。更新到 HEAD。
从p1/branches/br1 to trunk.
合并
-
您将在
readme.txt
中看到line1
、line2
和line2
。所以,你有两次“line2”,这是不正确的。 SVN 没有显示任何冲突。因此,这是非常危险的,因为合并执行时没有错误,并且您认为一切都很好。
这里的解决方案是第 9 步合并应该使用--reintegrate
选项完成。 reintegrate 选项告诉 SVN 将 br1
与主干进行比较,并仅将 br1
更改应用于主干。在这种特殊情况下,我们没有对br1
进行任何更改。主干中的结果应该是两行“line1”和“line2”。
另一个有用的评论。在第 9 步之后,分支 p1/branches/br1
不应再用于开发。如果您想在分支中继续开发,请创建一个新分支,例如p1/branches/br2
。从主干到p1/branches/br1
的另一个合并会导致很多冲突。
【讨论】:
我刚刚使用 SVN 1.7.0 完成了这个测试,我没有看到这种情况发生。相反,我看到的是 SVN 会自动过滤掉相关分支中已经存在的变更集,而不管合并的方向(主干到分支或分支到主干)。 SVN 在这方面的行为是否以未反映在文档中的方式发生了变化? 我还用 Netbeans 7.3.1(应该使用 SVN 1.7)完成了你的测试,我的 SVN 服务器是 1.6.17,重复行没有任何问题。【参考方案2】:永远不需要使用--reintegrate
;这是一种方便。如果您最近从 trunk
到 feature-branch
的合并合并了自分支到修订版 rev
以来在 trunk
中发生的所有更改,那么您可以使用以下命令。
svn merge url://trunk@rev url://feature-branch .
请注意,此命令将在 trunk
的最新工作副本的根目录中运行,不会提交任何未完成的更改。
让我扩展我的答案,以更直接地回答“是否有一个示例说明放弃重新集成会给我带来不必要的冲突?”
本文的意思是“如果我们包含那些同步的修订,那么我们会将主干中已经存在的更改合并回来。这会产生不必要且令人困惑的冲突。”
包括同步的修订将如下所示:
svn merge -r N:HEAD url://feature-branch .
其中.
是主干的干净工作副本,N
是 feature-branch
从 trunk
创建的修订版。该合并命令合并了自分支以来提交给feature-branch
的所有更改,包括在创建feature-branch
之后从trunk
合并的那些更改。这意味着已经对trunk
进行的更改将包含在上面的合并中。您会告诉 Subversion 将更改应用到实际上源自 trunk
的 trunk
,这会导致冲突。
【讨论】:
嗯,这就是我不明白的。如果这些更改相同,为什么分支和主干中都存在的更改会导致冲突? @Tor,如果您在分支中对修改后的代码进行了任何更改,您会看到冲突。换句话说,这些变化可能不再相同。想象一下,你在主干上添加了 5 条线路,同步到分支,然后在分支上修改它们。然后合并将显示冲突:主干上有 5 条线路与分支上有 5 条不同的线路。但是如果你使用--reintegrate,它只会注意到分支上的差异并在没有提示的情况下合并它。 这是否意味着在没有重新整合的情况下合并时,说“svn merge -r 1:100 url://feature-branch”。将找到对 url://feature-branch 从 rev 1 到 rev 100 所做的所有更改,并将它们中的每一个应用于 .逐个。而在 reintegrate 时,SVN 只会比较 rev 100 和 rev 1 之间的差异,并将这些差异视为更改,然后应用于 . ?【参考方案3】:我认为 Mark 的意思是它避免比较两个已修改的文件,一个是从分支重新集成的文件及其在主干中的相应文件,当两者都已同步(而不仅仅是在各自的分支中本地更改)。
假设我们有trunk/a.c
和branches/dev/a.c
,trunk/a.c
在某个时间点进行了修改,并在稍后通过合并重新集成到分支中。正如您所指出的,在将所有东西放回后备箱之前这样做是一个很好的做法。
因此下一步将是合并回主干,其中a.c
在两侧“不同”,因为它们在两个位置都发生了变化。如果没有该选项,则会进行不必要的比较,而 --reintegrate
将使 SVN 看到更改不仅仅是本地的。
【讨论】:
是的,我可以理解“不必要的比较”。但不是文档所说的“不必要的冲突”。【参考方案4】:从来没有必要使用--reintegrate
——它只是一个别名。如果你有trunk
的工作副本,那么
svn merge --reintegrate url://feature-branch workingcopy
与
相同svn merge url://trunk url://feature-branch workingcopy
您可以使用您更喜欢的任何一种。
【讨论】:
嗯。我不是 100% 确定,但我认为你在这个问题上弄错了。至少 svnbook 给出了完全不同的画面。 svnbook.red-bean.com/nightly/en/… @Michael:你真的确定吗?在 SVN 文档中,很明显行为是不同的,您的意思是它会通过指定两个 URL 自动检测到这一点吗? 那是根据OP中指定的链接。 “新的 reintegrate 选项是 2-URL 合并的简写版本......换句话说,reintegrate 只是一种新语法加上一些安全检查。”抱歉,我没有使用此选项的第一手经验。 Reintegrating a Branch (1.6). 其中指出:但是,当将分支合并回主干时,基础数学是完全不同的。您的功能分支现在是重复的主干更改和私有分支更改的混合体,因此没有简单的连续修订范围可以复制。通过指定 --reintegrate 选项,您要求 Subversion 只仔细复制那些对您的分支唯一的更改。 (事实上,它通过比较最新的主干树和最新的分支树来做到这一点:由此产生的差异正是您的分支更改!)以上是关于什么时候真正需要重新整合选项?的主要内容,如果未能解决你的问题,请参考以下文章