On Tue, Jul 3, 2012 at 1:26 AM, Nairn Baliber <planetkil...@gmail.com> wrote: > Hi Phillip. > > Thanks for the response. > > I am unclear about the intended functionality of SVN when using merge -c -M > (or -r M:<M-1>), given your response and the instructions in the svn book. > If I display the conflict brought up by the aforementioned merge command, > > svn merge -c -4 file:///path_to_repos/trunk, > > it reads as follows: > > ------ > this is an edit of testcode.py. r2. > > > this is another edit of testcode.py. r3. > <<<<<<< MINE (select with 'mc') (6,6) > > this is an edit of testcode.py. will get rid of this one. r4. > > > another edit of testcode.py. keeping it. r5. > > yet another edit of testcode.py. also keeping it. r6. > ||||||| ORIGINAL (6,2) > > this is an edit of testcode.py. will get rid of this one. r4. > ======= >>>>>>>> THEIRS (select with 'tc') (6,0) > ------ > > There is no choice for built-in conflict resolution that delivers the result > claimed in the svn book for "Undoing Changes." That is, neither resolved > (r), mine-conflict (mc), theirs-conflict (tc), mine-full (mf), nor > theirs-full (tf) will create a file with all lines of the working copy > intact except for the one ending in r4. Therefore, I'm not sure how a "more > permissive" algorithm could be a solution. The built-in choices for > conflict resolution (barring visual inspection and editing by the user) are > 1) keep the file as it was before the merge attempt, > 2)revert the file to r3, or > 3)revert the file to r4. > > The only way to produce the claimed functionality of undoing past changes in > this simple case is to visually inspect the displayed conflict using the dc > command (it is not at all obvious how to find the differences by postponing > and inspecting the resulting files, even in the ideal simple case I am > testing), edit the working copy to produce the desired result, and commit. > > In this very simple case, that is not very difficult. In real-life > situations, it would be at best extremely burdensome, and very prone to user > error. This doesn't seem to me to be the intended, and isn't anything like > the use case described in the svn book. > > If, however, this is the way SVN expects merge -c -M to be used to undo past > "bad" changes to files in a repository, then the intention is not properly > represented in the svn book. There should be a clear statement, in that > case, that the **only** case in which merge -c -M is useful is if all > changes committed in revision M were made at the end of the file or files > being committed. In real-world use cases, it would be just as easy if not > easier to svn cat or diff the files before and after the offending commit, > find the differences that way (with less clutter than appears in with the dc > command), and edit the working copy by hand to reverse the changes. > > But again, since you mentioned using a tool with a more permissive algorithm > to "allow a merge without a conflict," it sounds as though one of the > potential outcomes of the conflict raised by SVN should be a file with line > r4 having been removed. If that's not the case and everything is > functioning as designed, please let me know. I would again stress that if > that is the case, the instructions on the topic should be changed. In fact, > the whole "Undoing Changes" section of the svn book could be removed > entirely.
I'd like to point out that your example is really an edge case: where the lines immediately around the to-be-undone 'r4-line' (its context) have been changed since r4. Usually this is not the case, and the reverse 'r4' can be applied without problems. I've used the reverse-merge feature a couple of times, and never ran into conflicts. So the example from the book is still valid, it covers 99% of real-world cases IMHO. For your case, you can think of it this way: 'merge -c -M' first calculates the diff between M and M-1, and then tries to apply this diff (similar to what the standard unix 'patch' command does) to your working copy. The diff between 4 and 3 will look something like this (try 'svn diff -c -4'): [[[ C:\Temp\svntest\wc\trunk>svn diff -c -4 test.txt Index: test.txt =================================================================== --- test.txt (revision 4) +++ test.txt (revision 3) @@ -1,4 +1,3 @@ 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. ]]] As you can see, there are no context lines after line 4. Now when svn tries to apply this diff to your working copy, it will try to match line 4 to know which line to remove. But now it finds a non-empty context after line 4, i.e. the context doesn't match. So svn gives a conflict because it is (perhaps too) careful not to mess things up for you. Other merge/diff/patch algorithms may be more tolerant, and allow context lines to differ ... -- Johan