svn合并源和目标问题

时间:2015-02-06 18:09:47

标签: svn version-control svn-merge

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

我选择source作为trunk并将target作为featurebranch并从featurebranch本地工作区中选择(黄金,精确复制SVN中的内容)。

我在featurebranch中有一个新文件file1.xml,它不在trunk中。虽然合并我得到一个树冲突说合并试图添加新文件但它已经在本地。

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

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

3 个答案:

答案 0 :(得分:1)

使用“两个不同的树”合并而不是简单的“正常”合并,使事情变得复杂。

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

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

如果我理解,你真正想要的是“在我分支后的主干上进行所有更改,并将它们应用到我的工作副本”。为此,您只需将trunk与工作副本合并即可。您的分支的URL根本不会出现在merge命令中。这是SVN book中记录的第一种合并形式。

答案 1 :(得分:0)

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

将两个不同的树合并为diff并应用。如果你想将分支带到与trunk相同的级别,你想在分支和trunk之间进行差异并将其应用到分支(基本上是你的工作副本)。这意味着,source =你的分支和target = trunk。

示例:

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

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

如果要将trunk中完成的更改应用到分支(并且它是无基础合并),则需要指定要合并的修订范围。

一个例子:

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

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

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

答案 2 :(得分:0)

您没有向我们提供有关正在发生的事情的太多信息。在您的方案中添加更多详细信息以及您获得的 完全 错误消息会很不错。你做了新的结账吗?你用什么命令进行合并?你有什么版本的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已经很老了。)

如果所有这些都是真的,那么合并应该非常简单。您可以查看功能分支。然后,将 trunk 合并到功能分支中。

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

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

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

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

  • 在原始的最后一个共同祖先目录中,该文件存在。
  • 在trunk中,文件已被删除。
  • 它也已从功能分支中删除,但随后又重新添加。

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

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

如果您的工作副本中碰巧有一个不在Subversion中的文件,也会发生这种情况。 (像数据文件一样),并且在trunk上删除了类似的文件。 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不会尝试再次合并它们。