[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: bug in "Undoing Changes" functionality of merge -c -N?

From: Johan Corveleyn <jcorvel_at_gmail.com>
Date: Tue, 3 Jul 2012 09:47:22 +0200

On Tue, Jul 3, 2012 at 1:26 AM, Nairn Baliber <planetkiller_at_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
Received on 2012-07-03 09:48:17 CEST

This is an archived mail posted to the Subversion Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.