Once in a while, you will get a conflict when you update/merge your files from the repository or when you switch your working copy to a different URL. There are two kinds of conflicts:
当在
update/merge
仓库或者switch
仓库时,有两种不同的冲突:
- 文件冲突
如果两个(或多个)开发人员修改了相同文件的相同的某些行,就会出现文件冲突
- 树冲突
当开发人员移动/重命名/修改了一个文件或文件夹,其他开发人员也同时移动/重命名/删除或者修改了这个文件或文件夹,就会出现树冲突
A file conflict occurs when two or more developers have changed the same few lines of a file. As Subversion knows nothing of your project, it leaves resolving the conflicts to the developers. The conflicting area in a text file is marked like this:
当有两个以上开发人员同时修改了一个文件的相同的某些行就会出现文件冲突。Subversion并不知道如何处理,会将选择权留给开发人员。文件中冲突的区域就像下面这样标记:
<<<<<<< filename
your changes
=======
code merged from repository
>>>>>>> revision
Also, for every conflicted file Subversion places three additional files in your directory:
同时,对每个冲突的文件,Subversion会在相同的文件夹中生成三个文件:
发生冲突前的本地文件版本,就是你update后修改过的
发生冲突前的本地版本,就是在你修改前的最近一次update下来的文件
发生冲突时服务器的版本
You can either launch an external merge tool / conflict editor with TortoiseSVN
→ Edit Conflicts
or you can use any text editor to resolve the conflict manually. You should decide what the code should look like, do the necessary changes and save the file. Using a merge tool such as TortoiseMerge or one of the other popular tools is generally the easier option as they generally present the files involved in a 3-pane view and you don’t have to worry about the conflict markers. If you do use a text editor then you should search for lines starting with the string <<<<<<<
.
你也可以使用其他的合并工具/冲突编辑器,如乌龟壳
Edit Conflict
,或者使用文本编辑器手动处理冲突。[罗里吧嗦…]手工处理不好,建议使用合并工具如TortoiseMerge
,合并工具提供三视图方便对比.
Afterwards execute the command TortoiseSVN → Resolved and commit your modifications to the repository. Please note that the Resolve command does not really resolve the conflict. It just removes the filename.ext.mine
and filename.ext.r*
files, to allow you to commit your changes.
当使用
TortoiseSVN
-Resolved
并提交后,注意Resolve
命令并不是真正解决冲突,它只是删除了filename.ext.mine
和filename.ext.r*
等文件来允许你提交变更.
If you have conflicts with binary files, Subversion does not attempt to merge the files itself. The local file remains unchanged (exactly as you last changed it) and you have filename.ext.r*
files. If you want to discard your changes and keep the repository version, just use the Revert command. If you want to keep your version and overwrite the repository version, use the Resolved command, then commit your version.
如果有二进制文件发生冲突,Subversion不会尝试合并这些文件。本地修改后的文件仍然存在,并且同时会生成
filename.ext.r*
文件。如果要忽略本地选择仓库版本,使用Revert
命令。如果要保留本地版本并覆盖仓库版本,使用Resovled
命令,然后提交本地版本。
You can use the Resolved command for multiple files if you right click on the parent folder and select TortoiseSVN → Resolved… This will bring up a dialog listing all conflicted files in that folder, and you can select which ones to mark as resolved.
右键上级文件夹,选择
TortoiseSVN
-Resovled...
可以批量处理,它会弹出一个对话框,显示这个文件夹下的所有发生冲突的文件,你可以自由选择并标记冲突解决。
A property conflict occurs when two or more developers have changed the same property. As with file content, resolving the conflict can only be done by the developers.
当两个或多个开发修改了同一个属性就会出现属性冲突。解决文件内容的冲突只能有开发人员处理。
If one of the changes must override the other then choose the option to Resolve using local property or Resolve using remote property. If the changes must be merged then select Manually edit property, sort out what the property value should be and mark as resolved.
如果要覆盖变更,使用行选择使用本地版本还是远程版本;如果要合并属性,需要手动编辑属性并标记已解决冲突。
A tree conflict occurs when a developer moved/renamed/deleted a file or folder, which another developer either also has moved/renamed/deleted or just modified. There are many different situations that can result in a tree conflict, and all of them require different steps to resolve the conflict.
When a file is deleted locally in Subversion, the file is also deleted from the local file system, so even if it is part of a tree conflict it cannot show a conflicted overlay and you cannot right click on it to resolve the conflict. Use the Check for Modifications dialog instead to access the Edit conflicts option.
当一个文件在本地库被删除,它同时在本地文件系统中也删除了,尽管它是树冲突的一部分,你也不能通过右键来解决冲突。使用
Check for Modifications
打开对话框访问Edit conflicts
选项。
TortoiseSVN can help find the right place to merge changes, but there may be additional work required to sort out the conflicts. Remember that after an update the working BASE will always contain the revision of each item as it was in the repository at the time of update. If you revert a change after updating it goes back to the repository state, not to the way it was when you started making your own local changes.
乌龟壳可以帮助合并变更,但是仍有些额外的工作来解决冲突。注意,在更新之后,工作库始终包含每个文件的修订版,就像更新库一样。如果在更新后你还原,会还原到仓库状态,而不是本地修改后的状态。
- 开发人员A修改了
Foo.c
并提交到仓库
- 开发人员B同时将将他工作空间的
Foo.c
移动到Bar.c
或者删除了或者移动到其他路径。
An update of developer B’s working copy results in a tree conflict:
开发人员B更新工作空间出现树冲突:
Foo.c
从工作空间删除,被标记为树冲突。
如果冲突来自于重命名而不是删除,
Bar.c
被标记为新增,但是不包含开发者A的修改。
Developer B now has to choose whether to keep Developer A’s changes. In the case of a file rename, he can merge the changes to Foo.c into the renamed file Bar.c. For simple file or directory deletions he can choose to keep the item with Developer A’s changes and discard the deletion. Or, by marking the conflict as resolved without doing anything he effectively discards Developer A’s changes.
开发者B现在需要选择是否保留开发者A的变更。在重命名这种场景下,他可以选择合并
Foo.c
的变更到重命名后的Bar.c
。对于简单的文件或目录删除,他可以选择保留开发者A的变更并忽略删除。或者,通过标记冲突已解决来忽略任何变动,实际上他放弃了开发者A的修改。
The conflict edit dialog offers to merge changes if it can find the original file of the renamed Bar.c. If there are multiple files that are possible move sources, then a button for each of these files is shown which allow you to chose the correct file.
如果可以找到重命名后的
Bar.c
的之前的源文件,冲突编辑窗口就会提供合并更改的功能。如果存在多个可能的源文件,那么每个文件都出提供一个按钮供选择哪一个才是正确的文件。
Foo.c
to Bar.c
and commits it to the repository.开发者A移动
Foo.c
到Bar.c
并提交到远程仓库。
Foo.c
in his working copy.开发者B在本地工作空间修改
Foo.c
。
Or in the case of a folder move …
或者如果出现文件夹变动…
FooFolder
to BarFolder
and commits it to the repository.开发者A移动父文件夹
FooFolder
到BarFolder
并提交到远程
开发者B在本地工作空间修改了
Foo.c
。
An update of developer B’s working copy results in a tree conflict. For a simple file conflict:
开发者B更新工作空间出现树冲突。对于简单的文件冲突:
Bar.c
is added to the working copy as a normal file.
Bar.c
被加入当工作空间并标记为普通文件
Foo.c is
marked as added (with history) and has a tree conflict.
Foo.c
被标记为新增并存在树冲突
For a folder conflict:
对于文件夹冲突:
BarFolder
is added to the working copy as a normal folder.
BarFolder
作为普通文件夹被加入当工作空间
FooFolder
is marked as added (with history) and has a tree conflict.Foo.c
is marked as modified.
FooFolder
被标记为新增并存在树冲突
Foo.c
被标记为修改。
Developer B now has to decide whether to go with developer A’s reorganisation and merge her changes into the corresponding file in the new structure, or simply revert A’s changes and keep the local file.
开发者B现在需要决策是接受开发者A的修改,还是选择回滚A的修改并保留自己本地的文件。
To merge her local changes with the reshuffle, Developer B must first find out to what filename the conflicted file Foo.c was renamed/moved in the repository. This can be done by using the log dialog. Then use the button which shows the correct source file to resolve the conflict.
要合并这种调整,开发者B必须找到冲突的文件Foo.c被重命名/移动之前的状态。可以通过日志窗口找到,然后找到正确的那个文件并解决冲突。
If Developer B decides that A’s changes were wrong then she must choose the Mark as resolved button in the conflict editor dialog. This marks the conflicted file/folder as resolved, but Developer A’s changes need to be removed by hand. Again the log dialog helps to track down what was moved.
如果开发者B认为A的调整是错误的,他必须在冲突解决窗口界面标记冲突已解决,但是开发者B还需要手动删除开发者A的调整。同样的,可以使用日志窗口追踪那些被移动了。
Foo.c
to Bar.c
and commits it to the repository.开发者A将
Foo.c
移动到Bar.c
并提交到远程仓库
Foo.c
to Bix.c
.开发者B将
Foo.c
移动到Bix.c
。
An update of developer B’s working copy results in a tree conflict:
开发者B更新工作空间出现树冲突
Bix.c
is marked as added with history.
Bix.c
被标记为新增
Bar.c
is added to the working copy with status ‘normal’.
Bar.c
被添加到工作空间,状态正常
Foo.c
is marked as deleted and has a tree conflict.
Foo.c
被标记删除,并存在树冲突
To resolve this conflict, Developer B has to find out to what filename the conflicted file Foo.c
was renamed/moved in the repository. This can be done by using the log dialog.
要解决这类冲突,开发者B必须找到
Foo.c
被重命名/移动之前的文件名,可以通过日志窗口追踪。
Then developer B has to decide which new filename of Foo.c
to keep - the one done by developer A or the rename done by himself.
然后,开发者B必须决策保留哪一个
Foo.c
的新文件 - 是开发者A修改的,或者他自己修改的那份
After developer B has manually resolved the conflict, the tree conflict has to be marked as resolved with the button in the conflict editor dialog.
当开发者B手动解决冲突后,树冲突被标记已解决。
Foo.c
and commits it to the repository开发者A在trunk分支修改了
Foo.c
并提交到远程仓库。
Foo.c
to Bar.c
and commits it to the repository开发者B在branch移动
Foo.c
到Bar.c
并提交到远程仓库。
A merge of developer A’s trunk changes to developer B’s branch working copy results in a tree conflict:
合并trunk到branch会出现树冲突。
Bar.c
is already in the working copy with status ‘normal’.
Bar.c
已经在工作空间,状态正常。
Foo.c
is marked as missing with a tree conflict.
Foo.c
被标记缺失并存在树冲突。
To resolve this conflict, Developer B has to mark the file as resolved in the conflict editor dialog, which will remove it from the conflict list. She then has to decide whether to copy the missing file Foo.c from the repository to the working copy, whether to merge Developer A’s changes to Foo.c
into the renamed Bar.c
or whether to ignore the changes by marking the conflict as resolved and doing nothing else.
要解决这类冲突,开发者B需要在冲突编辑窗口标记冲突已解决,然后决定是否从远程将缺失的Foo.c拷贝到本地,是否将开发者A对
Foo.c
的修改合并到Bar.c
,或者是否忽略冲突,什么也不处理。
Note that if you copy the missing file from the repository and then mark as resolved, your copy will be removed again. You have to resolve the conflict first.
注意,如果你缺失的文件从远程拷贝下来并标记解决,你需要再移动一次。
Foo.c
to Bar.c
and commits it to the repository.
- 开发者A在trunk将
Foo.c
移动到Bar.c
并提交到远程仓库。
Foo.c
and commits it to the repository.
- 开发者B在branch分支修改
Foo.c
并提交到远程仓库。
or …
或者
FooFolder
to BarFolder
and commits it to the repository.
- 开发者A在trunk分支移动文件夹
FooFolder
到BarFolder
并提交到远程仓库。
Foo.c
in her working copy.
- 开发者B在branch修改
Foo.c
。
A merge of developer A’s trunk changes to developer B’s branch working copy results in a tree conflict:
将trunk分支合并到branch分就会出现树冲突
Bar.c
is marked as added.
Bar.c
被标记为新增
Foo.c
is marked as modified with a tree conflict.
Foo.c
被标记为修改,并存在树冲突
Developer B now has to decide whether to go with developer A’s reorganisation and merge her changes into the corresponding file in the new structure, or simply revert A’s changes and keep the local file.
开发者B现在需要决策是接受A的修改并将A的修改合并到本地,或者直接忽略A的修改选择本地的变更。
To merge her local changes with the reshuffle, Developer B must first find out to what filename the conflicted file Foo.c
was renamed/moved in the repository. This can be done by using the log dialog for the merge source. The conflict editor only shows the log for the working copy as it does not know which path was used in the merge, so you will have to find that yourself. The changes must then be merged by hand as there is currently no way to automate or even simplify this process. Once the changes have been ported across, the conflicted path is redundant and can be deleted.
要将本地的修改与远程合并,开发者B必须先找到被重命名/移动的冲突文件
Foo.c
在远程的文件名,可以通过日志窗口追踪。冲突合并窗口并不清楚合并中用了哪个路径,只展示工作空间的日志,因此开发者必须自己查找。然后开发者必须手动合并这些文件,这里不能自动合并或者有更简单的方法。[…]
If Developer B decides that A’s changes were wrong then she must choose the Mark as resolved button in the conflict editor dialog. This marks the conflicted file/folder as resolved, but Developer A’s changes need to be removed by hand. Again the log dialog for the merge source helps to track down what was moved.
如果开发者B认为A的调整是错误的,他必须在冲突解决窗口界面标记冲突已解决,但是开发者B还需要手动删除开发者A的调整。同样的,可以使用日志窗口追踪那些被移动了。
Foo.c
to Bar.c
and commits it to the repository.开发者A在trunk分支将
Foo.c
移动到Bar.c
并提交到远程仓库。
Foo.c
to Bix.c
and commits it to the repository.开发者B在branch将
Foo.c
移动到Bix.c
并提交到远程仓库。
A merge of developer A’s trunk changes to developer B’s branch working copy results in a tree conflict:
合并trunk分支到branch分支出现树冲突:
Bix.c
is marked with normal (unmodified) status.
Bix.c
状态正常
Bar.c
is marked as added with history.
Bar.c
状态添加
Foo.c
is marked as missing and has a tree conflict.
Foo.c
被标记缺失,并显示树冲突。
To resolve this conflict, Developer B has to find out to what filename the conflicted file Foo.c
was renamed/moved in the repository. This can be done by using the log dialog for the merge source.
要解决这类冲突,开发者B必须先找到被重命名/移动的冲突文件
Foo.c
在远程的文件名,可以通过日志窗口追踪。
Then developer B has to decide which new filename of Foo.c
to keep - the one done by developer A or the rename done by himself.
然后,开发者B必须决策保留哪一个
Foo.c
的新文件 - 是开发者A修改的,或者他自己修改的那份
After developer B has manually resolved the conflict, the tree conflict has to be marked as resolved with the button in the conflict editor dialog.
当开发者B手动解决冲突后,树冲突被标记已解决。
There are other cases which are labelled as tree conflicts simply because the conflict involves a folder rather than a file. For example if you add a folder with the same name to both trunk and branch and then try to merge you will get a tree conflict. If you want to keep the folder from the merge target, just mark the conflict as resolved. If you want to use the one in the merge source then you need to SVN delete the one in the target first and run the merge again. If you need anything more complicated then you have to resolve manually.
还有其他类型的树冲突,因为冲突涉及文件夹而不仅仅只是文件。比如如果你在trunk和branch同时添加了一个文件夹,然后你尝试合并就会出现树冲突。如果你想在合并中保留目标分支的版本,只需要标记冲突已解决即可。如果你想保留源分支的版本,你需要先删除目标分支的版本,然后再进行合并。如果有更复杂合并,必须手工处理。