树冲突当一个开发者移动/重命名/删除文件或文件夹,而另一个开发者也移动/重命名/删除或仅仅修改了该文件或文件夹时,会发生树冲突。有许多不同的情况可能导致树冲突,所有这些情况都需要不同的步骤来解决冲突。

当文件在 Subversion 中本地删除时,该文件也会从本地文件系统中删除,因此即使它是树冲突的一部分,它也无法显示冲突覆盖,并且您无法右键单击它来解决冲突。请改用 检查修改 对话框来访问 编辑冲突 选项。

TortoiseSVN 可以帮助找到合并更改的正确位置,但可能需要额外的操作来解决冲突。请记住,在更新后,工作 BASE 将始终包含每个项目在更新时在版本库中的修订版本。如果您在更新后还原更改,它将返回到版本库状态,而不是返回到您开始进行本地更改时的状态。

本地删除,更新时传入编辑开发者 A 修改了 Foo.c 并将其提交到版本库。

开发者 B 同时在他的工作副本中将 Foo.c 移动到 Bar.c,或者只是删除了 Foo.c 或其父文件夹。

开发者 B 的工作副本更新会导致树冲突

Foo.c 已从工作副本中删除,但标记为树冲突。

如果冲突是由重命名而不是删除引起的,则 Bar.c 被标记为已添加,但不包含开发者 A 的修改。

开发者 B 现在必须选择是否保留开发者 A 的更改。在文件重命名的情况下,他可以将 Foo.c 的更改合并到重命名的文件 Bar.c 中。对于简单的文件或目录删除,他可以选择保留包含开发者 A 更改的项目并放弃删除。或者,通过在不执行任何操作的情况下将冲突标记为已解决,他实际上放弃了开发者 A 的更改。

如果冲突编辑对话框可以找到重命名的 Bar.c 的原始文件,它会提供合并更改的选项。如果有多个文件可能是移动源,则会显示每个文件的按钮,允许您选择正确的文件。

本地编辑,更新时传入删除开发者 A 将 Foo.c 移动到 Bar.c 并将其提交到版本库。

开发者 B 修改了他的工作副本中的 Foo.c。

或者在文件夹移动的情况下...

开发者 A 将父文件夹 FooFolder 移动到 BarFolder 并将其提交到版本库。

开发者 B 修改了他的工作副本中的 Foo.c。

开发者 B 的工作副本更新会导致树冲突。对于简单的文件冲突

Bar.c 作为普通文件添加到工作副本中。

Foo.c 被标记为已添加(带有历史记录)并具有树冲突。

对于文件夹冲突

BarFolder 作为普通文件夹添加到工作副本中。

FooFolder 被标记为已添加(带有历史记录)并具有树冲突。

Foo.c 被标记为已修改。

开发者 B 现在必须决定是接受开发者 A 的重组并将她的更改合并到新结构中的相应文件中,还是仅仅还原 A 的更改并保留本地文件。

要将她的本地更改与重新组织合并,开发者 B 必须首先找出冲突文件 Foo.c 在版本库中被重命名/移动到哪个文件名。这可以通过使用日志对话框来完成。然后使用显示正确源文件的按钮来解决冲突。

如果开发者 B 认为 A 的更改是错误的,那么她必须在冲突编辑器对话框中选择 标记为已解决 按钮。这会将冲突文件/文件夹标记为已解决,但开发者 A 的更改需要手动删除。同样,日志对话框有助于跟踪移动的内容。

本地删除,更新时传入删除开发者 A 将 Foo.c 移动到 Bar.c 并将其提交到版本库。

开发者 B 将 Foo.c 移动到 Bix.c。

开发者 B 的工作副本更新会导致树冲突

Bix.c 被标记为已添加并带有历史记录。

Bar.c 以“正常”状态添加到工作副本中。

Foo.c 被标记为已删除并具有树冲突。

要解决此冲突,开发者 B 必须找出冲突文件 Foo.c 在版本库中被重命名/移动到哪个文件名。这可以通过使用日志对话框来完成。

然后开发者 B 必须决定保留 Foo.c 的哪个新文件名 - 开发者 A 完成的还是他自己完成的重命名。

在开发者 B 手动解决冲突后,必须使用冲突编辑器对话框中的按钮将树冲突标记为已解决。

本地丢失,合并时传入编辑在主干上工作的开发者 A 修改了 Foo.c 并将其提交到版本库

在分支上工作的开发者 B 将 Foo.c 移动到 Bar.c 并将其提交到版本库

将开发者 A 的主干更改合并到开发者 B 的分支工作副本会导致树冲突

Bar.c 已经在工作副本中,状态为“正常”。

Foo.c 被标记为丢失并具有树冲突。

要解决此冲突,开发者 B 必须在冲突编辑器对话框中将文件标记为已解决,这将从冲突列表中删除它。然后她必须决定是否将丢失的文件 Foo.c 从版本库复制到工作副本,是否将开发者 A 对 Foo.c 的更改合并到重命名的 Bar.c 中,或者是否通过将冲突标记为已解决并且不执行其他任何操作来忽略更改。

请注意,如果您从版本库复制丢失的文件,然后标记为已解决,您的副本将再次被删除。您必须先解决冲突。

本地编辑,合并时传入删除在主干上工作的开发者 A 将 Foo.c 移动到 Bar.c 并将其提交到版本库。

在分支上工作的开发者 B 修改了 Foo.c 并将其提交到版本库。

在主干上工作的开发者 A 将父文件夹 FooFolder 移动到 BarFolder 并将其提交到版本库。

在分支上工作的开发者 B 修改了她的工作副本中的 Foo.c。

将开发者 A 的主干更改合并到开发者 B 的分支工作副本会导致树冲突

Bar.c 被标记为已添加。

Foo.c 被标记为已修改并具有树冲突。

开发者 B 现在必须决定是接受开发者 A 的重组并将她的更改合并到新结构中的相应文件中,还是仅仅还原 A 的更改并保留本地文件。

要将她的本地更改与重新组织合并,开发者 B 必须首先找出冲突文件 Foo.c 在版本库中被重命名/移动到哪个文件名。这可以通过使用合并源的日志对话框来完成。冲突编辑器仅显示工作副本的日志,因为它不知道合并中使用了哪个路径,因此您必须自己找到该路径。然后必须手动合并更改,因为目前没有自动化甚至简化此过程的方法。一旦更改被移植过来,冲突的路径就是多余的,可以删除。

如果开发者 B 认为 A 的更改是错误的,那么她必须在冲突编辑器对话框中选择 标记为已解决 按钮。这会将冲突文件/文件夹标记为已解决,但开发者 A 的更改需要手动删除。同样,合并源的日志对话框有助于跟踪移动的内容。

本地删除,合并时传入删除在主干上工作的开发者 A 将 Foo.c 移动到 Bar.c 并将其提交到版本库。

在分支上工作的开发者 B 将 Foo.c 移动到 Bix.c 并将其提交到版本库。

将开发者 A 的主干更改合并到开发者 B 的分支工作副本会导致树冲突

Bix.c 被标记为正常(未修改)状态。

Bar.c 被标记为已添加并带有历史记录。

Foo.c 被标记为丢失并具有树冲突。

要解决此冲突,开发者 B 必须找出冲突文件 Foo.c 在版本库中被重命名/移动到哪个文件名。这可以通过使用合并源的日志对话框来完成。

然后开发者 B 必须决定保留 Foo.c 的哪个新文件名 - 开发者 A 完成的还是他自己完成的重命名。

在开发者 B 手动解决冲突后,必须使用冲突编辑器对话框中的按钮将树冲突标记为已解决。

其他树冲突还有其他情况被标记为树冲突,仅仅是因为冲突涉及文件夹而不是文件。例如,如果您向主干和分支都添加了同名的文件夹,然后尝试合并,您将得到一个树冲突。如果您想保留来自合并目标的文件夹,只需将冲突标记为已解决。如果您想使用合并源中的文件夹,那么您需要先 SVN 删除目标中的文件夹,然后再次运行合并。如果您需要更复杂的操作,那么您必须手动解决。