为什么我在Subversion中遇到了树冲突?

361

我在我的代码分支上开发功能,并定期将主干的更改合并到我的分支中,一切都很顺利。今天,当我尝试将分支合并回主干时,自从创建我的分支后添加到主干的任何文件都被标记为“树冲突”。是否有办法避免这种情况发生?

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


你能提供一个从空仓库开始复现此问题的步骤吗? - Wim Coenen
我会尽力今天找时间创建一个新的仓库,测试并获得相同的结果,并回复您。谢谢。 - Greg
12个回答

403

我通过Gary提供的链接找到了解决方案(并建议按照此方式进行)。

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

svn resolve --accept working -R .

其中.是冲突的目录。

警告: “提交你的工作副本”意味着你要提交的是你的沙盒结构,因此如果你在沙盒中删除了某些文件,则它们也将从存储库中被删除。这仅适用于有冲突的目录。

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

在TortoiseSVN中,在右键单击后选择“已解决”,实际上可以解决此问题。


33
这样,你建议svn解决冲突(--resolve),接受你沙盒中的工作副本(--accept working),递归地操作(-R),从当前目录开始(.)。希望能有所帮助。 - gicappa
23
在TortoiseSVN中,右键选择“已解决(Resolved)”实际上解决了此问题。 - understack
42
这是否盲目地接受了工作副本?我的意思是,我觉得我无法确定这些冲突存在哪些问题,但如果我只解决并接受工作副本,那么它不会抹掉其他人的工作吗? - Parris
10
这种情况的一个原因可能是您使用 svn rm 命令删除了一个您认为不再需要的目录,但其他人添加了一个新文件,这个文件是必需的。当您更新工作副本时,会出现树冲突。如果您盲目地接受自己的解决方案(删除目录),那么您将删除该文件。没有魔法“做正确事情”的按钮。您必须理解自己正在做什么,为什么会与最新版本发生冲突,以及如何正确解决它。 - bambams
5
我认为这个症状表明SVN作为版本控制工具存在问题。个人而言,未来避免这个问题的方法是使用git。但鉴于询问者很可能无法采用这种实用选项,那么按照这个答案所描述的方式来处理情况是最好的选择。 - Jess Telford
显示剩余15条评论

61

Subversion 1.6增加了树冲突(Tree Conflicts)来处理目录级别的冲突。一个很好的例子是当你本地删除一个文件,然后更新尝试将该文件的文本更改下载下来时。另一个例子是当你正在编辑的文件被重命名为子版本控制中的Add/Delete操作。

CollabNet的Subversion博客有一篇关于树冲突的精彩文章。


9
您提供的这些例子与我的情况无关。也许我的描述不够清楚? - Greg

34

根据我的经验,每当我删除一个文件夹时,SVN都会创建一个树形冲突。似乎没有任何原因。

只有我在编写代码 -> 删除目录 -> 提交 -> 冲突!

我迫不及待地想要转移到Git

我应该澄清一下 - 我使用的是Subclipse。那可能就是问题所在了!再次强调,我迫不及待地想要转移……


2
同样的问题出现在 SVN 命令行客户端中,所以不是 Eclipse 的问题。 - dolmen
3
我在使用NetBeans和SVN时遇到了同样的问题。删除目录后出现冲突。 - Gruber
2
我也遇到了同样的问题...真的很烦人...必须回滚、更新、删除和提交... - marcolopes
2
当我遇到树冲突时,我在IntelliJ Idea中发现了一个很棒的技巧。我将所有更改存储(这与创建更改补丁然后回滚它们相同)。然后我执行svn更新以从Subversion获取最新更改。之后,我取消存储我的更改(相当于应用补丁),然后就完成了! - ehrhardt
1
我似乎在使用Ubuntu 12.04.4 LTS上的svn客户端1.7.9连接Assembla仓库时遇到了相同的问题。 - siliconrockstar
显示剩余2条评论

29

我不知道这是否发生在你身上,但有时我选择错误的目录进行合并,即使所有文件看起来完全正常,也会遇到以下错误:

例如:

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

将 /svn/Project/branches/some-branch 合并到 /svn/Project/trunk ---> OK

这可能是一个愚蠢的错误,但并非总是显而易见,因为你认为它更加复杂。


对于查看此内容的人,如果您在某个分支源代码上右键单击以检查您的更改,然后尝试在主文件夹中合并到主干,您将会看到这一情况。要解决这个问题,请转到主干文件夹中的源代码文件夹,并进行合并。 - Kell

19
这里发生的情况是:您在主干上创建了一个新文件,然后将其合并到分支中。在合并提交中,该文件也会在分支中被创建。
当您将分支合并回主干时,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

1
因为Subversion 1.8中的“--reintegrate”选项已被弃用,所以被downvote了。从SVN 1.8开始,这种类型的合并是自动的! - bahrep
8
感谢点赞,因为仍有很多人使用低于1.8版本的Subversion。 - juacala
我认为在答案中添加SVN版本信息是有必要的。 - Peter Mortensen
1
1.8在这里,如果没有这个解决方案,它将无法工作。 - Winter
因为这回答了问题,所以我点赞了。 - Joshua Breeden
客户的管理太差了,这真是一种耻辱:这只是一个算法,人类不应该需要删除任何已经合并的文件来让它满意。难道客户不能注意到我们在主干和分支上都在谈论同一个文件吗?它可以跳过它,而不是抱怨它挡路了吗?请看下面我的解决方案。 - Fabien Haddadi

7

这可能是因为客户端版本不统一造成的。

使用1.5版本的客户端和1.6版本的客户端连接同一个仓库会导致这种问题。(我自己刚刚遇到了这个问题。)


6
直到今天,至少在三个月前,我尝试将一个分支合并回主干时(使用TortoiseSVN 1.11),经常遇到数百个树冲突。无论是否重新定位。 自2004年以来,我一直在使用TortoiseSVN,并经常重新整合分支。我想最近一定发生了什么事情? 因此,今天我进行了这个简单的实验,并发现是什么导致了这些疯狂的冲突:
1.我从trunk @393创建了一个fork; 2.我随机修改了数十个文件,并创建了新文件; 3.我提交了更改,现在在@395(同事在394处创建了自己的fork)。 4.然后我尝试将分支重新整合回主干,只进行测试;按照TortoiseSVN向导的建议:“要合并所有修订版本(重新整合),请将该框留空”。为了实现这一点,我右键单击主干文件夹,选择“TortoiseSVN > Merge,from /path/to/branch”,并像对话框中建议的那样将修订版本范围保持为空
讨论:(见附件)

所有修订版本...是什么?我毫不知情,客户一定是在指 "目标的所有修订版本!(主干)",因为在重新集成该分支的过程中,我看到了提到 "合并修订版本 1-HEAD" 的内容!天哪。可怜的魔鬼,你正在坠入死亡之中。那个分支诞生于第393个版本,你不能读取它的出生证明吗?这就是为什么会发生这么多冲突:SVN-cli从第1个版本开始疯狂地进行操作

解决方案:

  1. 与专家建议的相反,确切地指定范围,覆盖...该分支的整个生命周期!因此,394-HEAD
  2. 现在再次运行合并测试,并获得一支雪茄。(请参见第二个附件)。

寓意: 我无法理解为什么他们还没有修复那个漏洞,因为它确实存在,我很抱歉。 我应该花时间向他们报告这个问题。


4
如果您遇到的树冲突似乎没有道理,因为您没有编辑/删除/接近文件,那么很有可能合并命令中存在错误。可能发生的情况是,您之前已经合并了许多您当前合并包含的更改。例如,在主干中,某人编辑了一个文件,然后将其重命名。如果在第一次合并中包括了该编辑,然后在第二次合并中包括了编辑和重命名(实质上是删除),那么它也会给您带来树冲突。原因是之前合并的编辑现在出现为您自己的编辑,因此不会自动执行删除操作。这至少会发生在1.4存储库上,我不确定1.5引入的mergetracking是否有所帮助。

1

我曾经遇到过类似的问题。唯一真正起作用的方法是使用以下命令删除冲突的子目录:

svn delete --force ./SUB_DIR_NAME

然后从另一个根目录中复制它们到具有这些文件的工作副本中:

svn copy ROOT_DIR_NAME/SUB_DIR_NAME

然后执行

svn cleanup

并且

svn add *

你可能会在最后一个得到警告,但只需忽略它们,最终完成

svn ci .

1
今天我也遇到了这个问题,尽管我的问题可能与你的不相关。在检查文件列表后,我意识到我所做的事情——我暂时从另一个程序集中使用了一个文件。我对它进行了很多更改,并且不想让SVN历史记录变得孤立,因此在我的分支中,我将文件从另一个程序集的文件夹中移动过来。这并没有被SVN跟踪,所以它看起来就像是文件被删除然后重新添加。这最终导致了树冲突。
我通过将文件移回原处、提交,然后合并我的分支来解决了这个问题。然后我再把文件移回去。:) 这似乎行得通。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接