为啥我在 Subversion 中遇到树冲突?

Posted

技术标签:

【中文标题】为啥我在 Subversion 中遇到树冲突?【英文标题】:Why am I getting tree conflicts in Subversion?为什么我在 Subversion 中遇到树冲突? 【发布时间】:2010-10-18 19:28:00 【问题描述】:

我的主干有一个功能分支,并且定期将我的主干中的更改合并到我的分支中,一切正常。今天我将分支合并回主干,在创建分支后添加到我的主干的任何文件都被标记为“树冲突”。以后有办法避免这种情况吗?

我认为这些标记没有正确标记。

【问题讨论】:

你能给出一个从空存储库开始重现这个问题的方法吗? 我今天会尝试找一些时间来创建一个新的 repo 并测试它并获得相同的结果并回发。谢谢。 【参考方案1】:

我通过阅读 Gary 提供的链接找到了解决方案(我建议按照这种方式进行操作)。

总结解决树冲突提交您的工作目录与您可以使用的 SVN 客户端 1.6.x:

svn resolve --accept working -R .

其中. 是冲突目录。

警告“提交您的工作目录”意味着您的沙箱结构将是您正在提交的结构,因此,例如,如果您从沙箱中删除了一些文件,它们将是也从存储库中删除。这仅适用于冲突目录。

通过这种方式,我们建议 SVN 解决冲突 (--resolve),接受沙箱内的工作副本 (--accept working),递归 (-R),从当前目录 (.) )。

在 TortoiseSVN 中,右键单击“已解决”,实际上解决了这个问题。

【讨论】:

通过这种方式,您建议 svn 解决冲突(--resolve),接受沙箱中的工作副本(--accept working),递归(-R),从当前开始目录 (.) HTH 在 TortoiseSvn 中,右键选择“已解决”,实际上解决了这个问题。 这不是盲目地只接受工作副本吗?我的意思是我觉得我不知道这些冲突存在哪里问题,但如果我只是解决并接受工作,它不仅会抹杀其他人的工作吗? 发生这种情况的一个原因可能是您svn rm'd 一个您认为不再需要的目录,但其他人添加了一个需要的新文件。当您更新工作副本时,您应该会遇到树冲突。如果您只是盲目地接受您的解决方案(删除目录),那么您将删除该人的文件。没有神奇的“做正确的事”按钮。您必须了解自己在做什么,为什么会与最新版本冲突,以及如何正确解决。 @TWiStErRob,我认为这种症状表明 SVN 作为版本控制工具所固有的问题。就个人而言,未来“避免”这个问题的方法是使用git。由于对于提问者来说这很可能不是一个实际的选择,因此按照这个答案描述的情况处理是最好的选择。【参考方案2】:

Subversion 1.6 添加了树冲突来覆盖目录级别的冲突。一个很好的例子是,当您在本地删除文件时,更新会尝试对该文件进行文本更改。另一个是当您对正在编辑的文件进行颠覆重命名时,因为这是一个添加/删除操作。

CollabNet 的 Subversion 博客在 Tree Conflicts 上有一篇很棒的文章。

【讨论】:

你给出的这些例子都与我的情况无关。也许我的描述不清楚?【参考方案3】:

根据我的经验,当我删除文件夹时,SVN 会产生树冲突。似乎没有理由。

我是唯一一个处理我的代码的人 -> 删除目录 -> 提交 -> 冲突!

我迫不及待想切换到Git。

我应该澄清一下 - 我使用 Subclipse。这大概就是问题所在!再次,我迫不及待地想要切换......

【讨论】:

SVN 命令行客户端出现同样的问题,所以不是 Eclipse。 我对 NetBeans 和 SVN 也有同样的问题。删除目录 -> 冲突。 同样的问题...非常非常烦人...必须REVERT、更新、删除和提交... 当我遇到树冲突时,我发现了 IntelliJ Idea 的一个绝妙技巧。我搁置了所有更改(这与创建更改的补丁然后回滚它们相同)。然后我执行 svn update 以从 Subversion 获取最新更改。之后我取消了我的更改(与应用补丁相同)和中提琴! 我在 Ubuntu 12.04.4 LTS 上使用 svn 客户端 1.7.9 似乎遇到了同样的问题。【参考方案4】:

我不知道这是否发生在你身上,但有时我选择了错误的目录来合并,即使所有文件看起来都很好,我也会收到这个错误。

例子:

合并 /svn/Project/branches/some-branch/Sources 到 /svn/Project/trunk ---> 树冲突

合并 /svn/Project/branches/some-branch 到 /svn/Project/trunk ---> 好的

这可能是一个愚蠢的错误,但并不总是很明显,因为您认为它更复杂。

【讨论】:

【参考方案5】:

这里发生的情况如下:您在主干上创建一个新文件,然后将其合并到您的分支中。在合并提交中,该文件也将在您的分支中创建。

当您将分支合并回主干时,SVN 会再次尝试做同样的事情:它看到在您的分支中创建了一个文件,并尝试在合并提交中在您的主干中创建它,但它已经存在!这会造成树冲突。

避免这种情况的方法是进行特殊的合并,即重新集成。您可以使用--reintegrate 开关实现此目的。

您可以在文档中阅读相关内容: http://svnbook.red-bean.com/en/1.7/svn.branchmerge.basicmerging.html#svn.branchemerge.basicmerging.reintegrate

但是,当将分支合并回主干时,底层 数学完全不同。您的功能分支现在是一个混搭 重复的主干更改和私有分支更改,所以 没有简单的连续修订范围可以复制。经过 指定 --reintegrate 选项,您要求 Subversion 小心地只复制您的分支独有的那些更改。 (并且在 事实上,它是通过将最新的树干树与最新的树干树进行比较来实现的 分支树:由此产生的差异正是您的分支更改!)

在重新整合一个分支后,强烈建议将其移除,否则无论何时在另一个方向合并时都会不断发生树冲突:从主干到分支。 (原因与之前描述的完全相同。)

也有办法解决这个问题,但我从未尝试过。你可以在这篇文章中阅读它:Subversion branch reintegration in v1.6

【讨论】:

投反对票,因为 --reintegrate 选项在 Subversion 1.8 中已被弃用。从 SVN 1.8 开始,这种合并是自动的! 赞成,因为很多人仍在使用颠覆 我认为将SVN版本信息添加到答案中。 这里是 1.8,如果没有这个解决方案,它将无法工作。 赞成,因为这回答了为什么会发生这种情况的问题。【参考方案6】:

这可能是由于没有完全使用相同版本的客户端造成的。

对同一存储库使用 1.5 版客户端和 1.6 版客户端可能会产生此类问题。 (我自己也被咬了。)

【讨论】:

【参考方案7】:

直到今天,至少从 3 个月前开始,我在尝试将分支合并回树干时经常遇到数百个树冲突(使用 TortoiseSVN 1.11)。顺便说一句,无论是否重新定位。 从 2004 年的 v1 开始,我一直在使用 TortoiseSVN,而且我一直在重新集成分支。我想最近一定发生了什么事吧?

所以今天我进行了这个简单的实验,我发现了造成这些疯狂冲突的原因:

    我从树干上分叉了@393; 我随机修改了几十个文件,也创建了新文件; 我答应了。现在@395(一位同事在 394 分叉出去做他自己的事情)。 然后我尝试将分支重新集成回主干,仅测试; 遵循 TortoiseSVN 在向导中的建议:“要合并所有修订(重新集成),请将该框留空”。为此,我右键单击主干文件夹,然后选择“TortoiseSVN > Merge, from /path/to/branch”,然后按照对话框中的建议将转速范围留空

讨论:(见附件)

所有修订...什么? 我几乎不知道客户端一定是指“所有版本的目标!(主干)”,因为在重新集成该分支的过程中,我看到提到“合并修订1-HEAD”!我的天啊。可怜的恶魔,你在这里摔死了。那个分支诞生于@393,看在上帝的份上,你看不到它的出生证明吗?

分辨率:

    与向导的建议相反,请指定一个范围,涵盖...分支生命周期的所有修订!因此,394-HEAD; 现在再次运行该合并测试,并获得一支雪茄。 ()。

道德: 我无法理解为什么他们仍然没有修复那个错误,因为它是一个,我很抱歉。 我应该花时间向他们报告。

【讨论】:

【参考方案8】:

如果您遇到没有意义的树冲突,因为您没有编辑/删除/来到文件附近的任何位置,那么合并命令也很有可能出错。

可能发生的情况是,您之前已经合并了当前合并中包含的大量更改。例如,在主干中,有人编辑了一个文件,然后重命名了它。如果在第一次合并中包含编辑,然后在第二次合并中包含编辑和重命名(本质上是删除),它也会给你一个树冲突。这样做的原因是之前合并的编辑会显示为您自己的,因此不会自动执行删除。

这至少会发生在 1.4 的存储库中,我不确定 1.5 中引入的合并跟踪是否有帮助。

【讨论】:

【参考方案9】:

我今天也遇到了这个问题,尽管我的特定问题可能与您的问题无关。检查文件列表后,我意识到我做了什么——我暂时在一个程序集中使用另一个程序集中的文件。我对其进行了很多更改,并且不想孤立 SVN 历史记录,因此在我的分支中,我将文件从另一个程序集的文件夹中移了过来。这不是 SVN 跟踪的,所以看起来文件被删除然后重新添加。这最终会导致树冲突。

我通过将文件移回、提交并然后合并我的分支来解决问题。然后我把文件移回来了。 :) 这似乎成功了。

【讨论】:

【参考方案10】:

我遇到了类似的问题。唯一对我有用的是删除冲突的子目录:

svn delete --force ./SUB_DIR_NAME

然后从工作副本中的另一个根目录再次复制它们:

svn copy ROOT_DIR_NAME/SUB_DIR_NAME

那就做吧

svn cleanup

svn add *

您可能会收到最后一个警告,但请忽略它们,最后

svn ci .

【讨论】:

【参考方案11】:

我遇到了同样的问题,并通过使用these instructions 重新进行合并来解决它。基本上,它使用 SVN 的“2-URL 合并”将trunk 更新为您分支的当前状态,而无需过多关注历史记录和树冲突。使我免于手动修复 114 个树冲突。

我不确定它是否像人们希望的那样保留了历史,但对我来说这是值得的。

【讨论】:

历史是我们使用 VCS 的原因......还是我错过了什么?【参考方案12】:

我有时会遇到的一个场景:

假设您有一个主干,您从中创建了一个发布分支。在对主干进行一些更改(特别是创建“some-dir”目录)之后,您创建了一个功能/修复分支,您稍后也希望将其合并到发布分支中(因为更改足够小并且功能/修复对于发布很重要) .

trunk -- ... -- create "some-dir" -- ...
     \                                  \-feature/fix branch
      \- release branch

如果您随后尝试将 feature/fix 分支直接合并到 release 分支中,您将遇到树冲突(即使该目录甚至在 feature/fix 分支中都不存在):

svn status
!     C some-dir
      >   local missing or deleted or moved away, incoming file edit upon merge

因此,您需要在创建功能/修复分支之前明确合并在主干上完成的提交,该分支在合并功能/修复分支之前创建了“some-dir”目录。

我经常忘记这一点,因为这在 git 中是不必要的。

【讨论】:

以上是关于为啥我在 Subversion 中遇到树冲突?的主要内容,如果未能解决你的问题,请参考以下文章

新的未修改分支上的树冲突

在 Subversion 中跨分支合并并不是添加所有新文件。为啥不?

在 Subversion 中合并分支时的冲突预防

为啥我在一个环境中的 sbt 中出现冲突的交叉版本,而在另一个环境中却没有?

Subversion 存储库布局,为啥? [复制]

svn冲突问题详解 SVN版本冲突解决详解