Friday, November 27, 2009

Section 5.6.  Resolving Conflicts









5.6. Resolving Conflicts


Whenever Subversion encounters changes from two different sources, it attempts to perform an automatic merge. If Subversion fails to successfully merge, a conflict occurs. This can happen in a couple of cases. The first is the instance where the changes occur in the same location in the two versions of the file. Because Subversion doesn't know anything about the context of a file, it has no way to merge colliding changes, and must declare a conflict. The other case where a conflict occurs is the case where a binary file is being merged. Binary files are usually very intolerant to minor changes performed by something that doesn't understand the file, which means that using Subversion's textual merge on a binary file would more often than not result in a file that was unreadable. Because Subversion doesn't have any means to merge a binary file, it always declares a conflict when changes from two different sources must be merged.


When a conflict does occur, Subversion creates several different copies of the original file in your home directory. Each copy of the file is a different version of the file from one of several different revisions. The files are all named with an extension telling where the file came from, appended onto the original name of the file. For example, if the file comes from revision 52 of the file foo.h, it will be named foo.h.r52. If the version of the file is the local working copy version, it will have .mine appended. If the conflict occurs as the result of a merge, the righthand and lefthand files from the merge will be named with .right and .left, respectively. In total, the versions of the file that Subversion will create in the case of a conflict consist of the local working copy version of the file with all local modifications, a pristine copy of the local version with no local modifications, and any remote versions of the file that are involved in the conflict.


If the conflicted file is a text file (i.e., not binary), Subversion also modifies the original version of the file (in the working copy) so that it contains both versions of any conflicted sections inline. The conflicted sections are placed, one after the other, with a separator between them (consisting of = signs). Each version is also labeled with its source. The top version shows its source at the beginning of the section, and the bottom source ends with a source label. The labels are denoted with < s and > s respectively, as you can see in the following example.



The Fox: A poem

The quick brown fox
<<<<<<< .mine
with a javelin, leaped
=======
jumped over
>>>>>>> .r378
the lazy dog


The work of resolving the conflict is left to you to perform by hand. When you are done, the final, resolved version of the file should reside in your working copy under the original name of the file being resolved (if the file is bar.txt, the resolved version should be bar.txt). You can accomplish this either by editing the original file or by overwriting it with another filesuch as one of the versions of the file that Subversion generated in response to the conflict.


While a file is in a conflicted state, Subversion doesn't allow you to commit the file. If you try, it throws an error and the commit fails. To be able to commit again, you need to tell Subversion when you have finished resolving a conflict. This is done with the svn resolved command, which removes all of the extra files created by Subversion when the conflict was declared (leaving only the originally named version of the file) and removes the block on committing the file. It does not in any way modify the originally named file. As an example, the following shows the complete process you might go through when resolving a conflict during an update. In this case, the version of the file in revision 75 is the correct one to use; it's moved to replace bar.c.



$ svn update
C bar.c
$ ls
bar.c bar.c.mine bar.c.r75
$ mv bar.c.r75 bar.c
$ svn resolved
Resolved conflicted state of 'bar.c'
$ ls
bar.c









    No comments: