Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conflict when attempting Undoing Changes example in Subversion

Tags:

merge

svn

In exploring functionality in Subversion, I attempted to test the use case described in the Undoing Changes subsection of the Basic Merging section of the Branching and Merging chapter of the svnbook. I'm using version 1.6.4, but the text for that section is the same in both versions of the book.

In my working copy directory, I edit a file testcode.py, adding one line per edit, and committing after each edit. After several commits, the file reads as follows:

this is my first import to trunk.  r1.

this is my first commit, first edit of testcode.py.  r2.

this is another edit of testcode.py.  r3.

this is an edit of testcode.py.  i'll get rid of this one.  r4.

this is another edit of testcode.py.  keeping it.  r5.

yet another edit.  keeping it.  r6.

The revision numbers in the repository match up to the lines in the file such that in /trunk/testcode.py@rN, the last line of the file is the one ending with rN. What I want to do is remove the line ending in r4, keeping everything else before and after unchanged.

Following the example in the Undoing Changes section of the svnbook, I run the command

svn merge -c -4 file:///path_to_repos/trunk

This creates a conflict (upon running that command, not on commit), whereby the merge-left file contains everything up until line r4, and the merge-right file contains everything up until line r3. In other words, instead of removing a past change, the command seems to want to revert the entire file back to either revision 3 or 4, removing changes in subsequent revisions (5 and 6, in this case).

The way I read the example in the svnbook, which has the user reversing a change committed in revision 303 and committing the result to revision 350 with no conflicts, the command I ran should have produced a file with an svn status of M that retains all lines except the one ending in r4.

Am I reading the book's example incorrectly, is the example wrong, or is there some other form of user error I fell into unawares?

like image 522
krosbonz Avatar asked Jun 25 '12 18:06

krosbonz


People also ask

How do I resolve conflicts in svn?

To resolve a conflict do one of three things: Merge the conflicted text by hand (by examining and editing the conflict markers within the file). Copy one of the temporary files on top of the working file. Run svn revert FILENAME to throw away all of the local changes.

What is svn tree conflict?

Since 1.6 version SVN recognizes a new kind of conflict, known as a "tree conflict". Such conflicts manifest at the level of directory structure, rather than file content. Situations now flagged as conflicts include deletions of locally modified files, and incoming edits to locally deleted files.

How many temporary files does are made for each file when there is a text conflict during svn update?

Once you've resolved the conflict, you need to let Subversion know by running svn resolved. This removes the three temporary files and Subversion no longer considers the file to be in a state of conflict.


1 Answers

The basic issue is that Subversion's diff algorithm handles changes at the beginning and end of files in a way that's not necessarily intuitive. Your example hits that corner case, while the majority of changes in the wild do not. Consider a file that looks like this after a series of commits:

later commit (r5)
change to be reverted at beginning of file (r2)
initial commit (r1)
change to be reverted in middle of file (r3)
initial commit (r1)
change to be reverted at end of file (r4)
later commit (r5)

Trying to revert the commits to the beginning or end of the file (revisions 2 and 4 in the example), gives a conflict. Reverting the change to the middle of the file works as expected.

Conceptually, it might help to think of changesets as having a scope limited by surrounding lines. A change to the middle of a file is bounded by the surrounding unchanged lines. The scope of a change at the beginning or end of a file extends all the way to the beginning or end of the file regardless of how far away that point is subsequently moved.

So in the example above, the second line added in revision 5 comes right in the middle of revision 4's scope. In the same way that you'd expect a conflict reverting revision 10 here because changes in revision 11 are smack dab in the middle of it:

...                    <-- Line unchanged by revision 10, bounding its scope
line from revision 10  <--\
line from revision 11     | Revision 10's scope
line from revision 10  <--/
...                    <-- Line unchanged by revision 10, bounding its scope

you should expect a conflict here, for the same reason:

...                    <-- Line unchanged by revision 10, bounding its scope
line from revision 10  <--\
line from revision 11     | Revision 10's scope
<EOF>                  <--/ (No unchanged line bounding the scope this direction)

Note that this is only meant as a conceptual explanation of why the beginning and end of the file are seemingly treated differently, not as a comprehensive explanation for understanding Subversion's merge process.

like image 151
blahdiblah Avatar answered Oct 23 '22 20:10

blahdiblah