【问题标题】: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 会给我带来不必要的冲突?

【问题讨论】:

    标签: svn merge branch svn-reintegrate


    【解决方案1】:

    让我解释一下什么时候--reintegrate 是绝对必要的。

    考虑以下用例。

    1. 您在 p1/trunk 下有项目 p1。该项目有一个文件readme.txt,其中有一行“line1”
    2. 创建一个新分支,p1/branches/br1
    3. 留在后备箱里。将“line2”行添加到readme.txt 并提交到主干
    4. 切换到p1/branches/br1 分支。更新到 HEAD。
    5. 从主干合并到此分支(以获取主干更改)。
    6. readme.txt 中应该有 line1line2
    7. 提交合并结果到p1/branches/br1分支
    8. 切换到中继。更新到 HEAD。
    9. p1/branches/br1 to trunk.合并
      1. 您将在readme.txt 中看到line1line2line2。所以,你有两次“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;这是一种方便。如果您最近从 trunkfeature-branch 的合并合并了自分支到修订版 rev 以来在 trunk 中发生的所有更改,那么您可以使用以下命令。

    svn merge url://trunk@rev url://feature-branch .
    

    请注意,此命令将在 trunk 的最新工作副本的根目录中运行,不会提交任何未完成的更改。

    让我扩展我的答案,以更直接地回答“是否有一个示例说明放弃重新集成会给我带来不必要的冲突?”

    本文的意思是“如果我们包含那些同步的修订,那么我们会将主干中已经存在的更改合并回来。这会产生不必要且令人困惑的冲突。”

    包括同步的修订将如下所示:

    svn merge -r N:HEAD url://feature-branch .
    

    其中. 是主干的干净工作副本,Nfeature-branchtrunk 创建的修订版。该合并命令合并了自分支以来提交给feature-branch 的所有更改,包括在创建feature-branch 之后从trunk 合并的那些更改。这意味着已经对trunk 进行的更改将包含在上面的合并中。您会告诉 Subversion 将更改应用到实际上源自 trunktrunk,这会导致冲突。

    【讨论】:

    • 嗯,这就是我不明白的。如果这些更改相同,为什么分支和主干中都存在的更改会导致冲突?
    • @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.cbranches/dev/a.ctrunk/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 只是一种新语法加上一些安全检查。”抱歉,我没有使用此选项的第一手经验。
    • 其中指出:但是,当将分支合并回主干时,基础数学是完全不同的。您的功能分支现在是重复的主干更改和私有分支更改的混合体,因此没有简单的连续修订范围可以复制。通过指定 --reintegrate 选项,您要求 Subversion 只仔细复制那些对您的分支唯一的更改。 (事实上​​,它通过比较最新的主干树和最新的分支树来做到这一点:由此产生的差异正是您的分支更改!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 2012-09-16
    相关资源
    最近更新 更多