【问题标题】:svn merge source and target issuesvn合并源和目标问题
【发布时间】:2015-02-06 18:09:46
【问题描述】:

我正在使用 SVN 合并(两个不同的树)将主干合并到功能分支。

我选择源作为主干,目标作为特性分支,并从特性分支本地工作区执行它(金色,精确复制 SVN 中的内容)。

我在 featurebranch 中有一个新文件 file1.xml,它不在主干中。合并时出现树冲突,说合并尝试添加新文件,但它已经在本地。

我的问题是,当我的源是没有此文件的主干时,为什么合并甚至担心功能分支中的新文件。

我想在我签到之前确保合并正确发生。非常感谢任何帮助。

【问题讨论】:

    标签: svn version-control svn-merge


    【解决方案1】:

    使用“两棵不同的树”合并而不是简单的“正常”合并会使事情复杂化。

    您通过使用“两棵不同的树”告诉 SVN 是“进行所需的更改以获取主干并将其更改为我的分支,并将这些更改应用于我的工作副本”。这不是您想要的,因为您正在撤消主干上的任何更改,然后重做所有分支更改。

    相反的也不是你想要的,我想,相反的地方是“撤消我在分支上的所有更改,并在主干上进行所有更改,以使我的工作副本与主干匹配。”

    如果我理解,您真正想要的是“获取自分支以来在主干上发生的所有更改,并将它们应用于我的工作副本”。为此,您只需将主干合并到您的工作副本。您的分支的 URL 根本不会出现在合并命令中。这是SVN book 中记录的第一种合并形式。

    【讨论】:

      【解决方案2】:

      你没有向我们提供太多关于正在发生的事情的信息。最好在您的场景中提供更多详细信息以及您收到的确切错误消息。您是否进行了新的结帐?你用什么命令来做你的合并?你有什么版本的 Subversion 客户端和服务器?

      否则,我们无法确定您的问题。将主干合并到来自主干的功能分支通常应该没有任何问题。

      我的第一个问题是您是如何创建分支的。在 Subversion 中创建分支时,应在 URL 表单中使用 svn copy 创建它:

      $ svn copy --parent $REPO/trunk $REPO/branches/feature
      

      我已经看到人们通过svn mkdir 创建一个分支,然后在该分支上复制他们想要的文件,然后在该分支上添加所有这些文件。 Subversion 无法合并这些项目,因为它不知道它们的共享历史。对于 Subversion,它们包含完全不同的文件。它们可能具有相同的名称和相似的内容,但它们是不同的文件。合并是行不通的。

      • 那么,您是这样创建分支的吗?如果是这样,你做得很好。

      • 第二个问题:您是否将功能分支直接从主干分支?这不是必需的,但如果您要合并到的分支不在您要合并的分支之外,则合并会更干净。

      • 第三个问题:您的功能分支是干净的结帐吗? svn status --no-ignore 是否向您展示了什么?你做过svn update吗?确保您的工作副本是干净的可以为您节省很多麻烦。事实上,我建议开发人员尽可能重新结帐。

      • 您的服务器 Subversion 版本和您的客户端 Subversion 1.6 或更高版本。合并跟踪是在 1.5 版中添加的,但它有点成问题。客户端和服务器都应至少为 1.6 版。 (当前版本是1.8,1.9版本快要发布了,所以1.6版本比较老了)。

      如果所有这些都是真的,那么合并应该很简单。您检查了 feature 分支。然后,将 trunk 合并到功能分支中。

      $ svn co $REPO/branches/feature
      $ cd feature
      $ svn merge $REPO/trunk
      

      Subversion 合并通常是三方面的事情。您将 trunk 上的内容与功能分支上的内容进行比较, 这两个版本的最后一个共同祖先的样子。通过在分支发生之前查看原始文件,Subversion 可以知道更改发生在哪个分支上,以及是否应将其视为合并的一部分。

      在 Subversion 合并中事情变得有点棘手,因为还会检查目录更改。

      在你的场景中,我可以想象这样的事情:

      • 在最初的最后一个共同祖先目录中,该文件就在那里。
      • 在主干中,文件已被删除。
      • 它也已从功能分支中删除,但随后又重新加入。

      现在,Subversion 尝试合并。最后一个共同祖先有那个文件。 Subversion 查看主干,发现该文件已被删除。 Subversion 查看分支,发现文件已添加。

      所以,Subversion 看到了冲突。自最后一个共同祖先以来,它被添加到功能分支中,但它也被从主干中删除。它应该怎么做?它不能简单地删除文件,因为它是在功能分支中添加的。由于主干和功能分支都发生了变化,因此发生了冲突。

      如果您的工作副本中碰巧有一个不在 Subversion 中的文件,也会发生这种情况。 (如数据文件),并且在主干上删除了类似的文件。 Subversion 想删除文件,但不能。这就是为什么从干净签出您要合并的分支开始如此重要的原因。

      您也可能有其他原因。很难说。对功能分支进行干净的检查。确保 svn status -no-ignore 不返回任何内容。确保您的工作副本完全是最新的。在上面做一个svn up

      然后,如果您收到错误消息,请向我们提供完整的错误消息。检查你的行李箱,看看它长什么样。同时在您的功能分支工作副本上运行以下两个命令:

      $ svn mergeinfo --show-revs eligible $REPO/trunk
      $ svn mergeinfo --show-revs merged $REPO/trunk
      

      第一个将显示主干上符合合并条件的修订。第二个将显示之前合并的版本。

      然后,查看这些更改的日志,看看是否有任何问题。有时我会在主干和分支上看到错误修复。这是两个独立的版本,但修复了相同的问题,因此修复了此错误的主干修订不应合并到分支中。您可以通过svn merge --record-only -c $rev 将这些修订合并到您的功能分支中,这样 Subversion 就不会再次尝试合并它们。

      【讨论】:

        【解决方案3】:

        注意:此答案仅适用于您的分支不是直接从主干创建的情况。从主干分支时,请参阅@Ben的答案

        合并两个不同的树将被读取为差异并应用。如果您想将分支提升到与主干相同的级别,您需要获取分支和主干之间的差异并将其应用于分支(基本上是您的工作副本)。这意味着,源 = 你的分支和目标 = 主干。

        例子:

        svn merge https://svn/repo/branch https://svn/repo/trunk c:\svn\branch
        

        此命令将获取分支和主干之间的差异,并将差异应用于分支的工作副本。 (分支工作副本现在将与主干相同)

        如果您想将在主干中完成的更改应用到您的分支(这是一个毫无根据的合并),您需要指定要合并的修订范围。

        一个例子:

        svn merge -r 10:HEAD https://svn/repo/trunk c:\svn\branch
        

        这将获取主干修订版和修订版 10 之间的差异,并将其应用于分支。基本上应用这两个修订之间所做的更改。我怀疑这就是你想要做的。

        我建议阅读http://svnbook.red-bean.com/en/1.8/svn.branchmerge.advanced.html 并从命令行进行合并。 TortoiseSVN 合并对话框一团糟。

        【讨论】:

        • 感谢菲利普的回复。是的,我想将主干中所做的更改合并回分支。不过我很困惑,在这种情况下,分支如何成为源。
        • 您的术语令人困惑。 SVN 手册专门将 2 源合并中的两个 URL 都称为源。 “目标”始终是您的工作副本。我认为这种合并形式的目的是将两个分支之间的差异变成第三个分支,对吗?在这种情况下,更正确的合并应该是简单的 1-source 合并。
        • 确实应该是一源合并。 (我被问题中的两个不同的树评论分心,认为它必须是毫无根据的合并)我将更新我的答案以明确这一点。
        猜你喜欢
        • 2011-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-26
        • 1970-01-01
        相关资源
        最近更新 更多