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

Re: 1.6 vs. 1.8: strange behavior of 'svn diff -cN WC-FILE' if the file was created in rev N by copying

From: Tobias Bading <tbading_at_web.de>
Date: Thu, 27 Jun 2013 12:00:26 +0200

On 27.06.2013 09:38, Bert Huijben wrote:
> We can't just redefine the behavior of '-c'
> The 'svn' commandline client explicitly implements '-c' as '-r N-1:N' (or -r
> N:N-1 when passing -c -N)
> This behavior is tied to more commands than diff and the internal APIs just
> see the revision numbers.
> Besides
> $ svn diff -c 12 FILE
> has many use cases
> what would you expect after:
> $ svn rm FILE
> $ svn cp OTHER-FILE_at_6 FILE
> $ svn ci -m "r12"
> (copy file with some history)

Granted, this is a toughy.
My 0.02 cents (after a first glance, I hereby reserve the right to
totally reverse my opinion later on in this thread ;-):
I'd expect 'diff -r11:12 (aka -c12) FILE' to show... umm... err...
Mom!!!! I don't want to play with Bert anymore, he's a party pooper! ;-)
Seriously, 'diff -c12 FILE' (without --notice-ancestry) should probably
ignore the fact that an other FILE_at_11 existed and show the differences
between OTHER-FILE_at_6 and FILE_at_12, that is work just like 'diff -r6:12
FILE' in this case.
'diff --notice-ancestry -c12 FILE' or 'diff -c12 DIR' (with DIR being
the directory containing FILE) should show the replacement, that is
FILE_at_12 as a new file.

Merge should probably work the other way around as usual, i.e. 'merge
-c12 FILE-IN-REPO' should replace an existing FILE and 'merge
--ignore-ancestry -c12 FILE-IN-REPO' should merge the changes between
OTHER-FILE_at_6 and FILE_at_12 into the local FILE.

> or after:
> $ svn rm FILE
> $ echo "QQQ"> FILE
> $ svn add FILE
> $ svn ci -m "r12"
> (add new file)

See above I'd say. Just a bit simpler here, because of the missing hole
in the time-space continuum created by copying OTHER-FILE_at_6 to FILE_at_12.

> $ echo new line>> FILE
> $ svn ci -m "r12"
> (text change)

I don't get this one. Just a simple line added in r12?

> [There are even more variants possible if you replace an ancestor instead of
> just the node itself]
> We can't handle all these use cases with a simple -r N-1:N. We really need
> more flags to capture all these cases.
> 'svn diff' is already implemented as layer over layer over layer of use
> cases.
> E.g. by default diff doesn't describe the ancestry of nodes: A file replaced
> by a file or a directory by a directory is described as a simple content
> change unless you pass --notice-ancestry (or --git). Which is nice if you
> want to use 'svn diff' as input for GNU patch, but not if you want it to
> describe the local changes.
> Another interesting case is that our merge is also build on top of diff, so
> users would expect that
> svn diff ^/trunk -c 1234
> Would be the same as what you merge with
> svn merge ^/trunk -c 1234

I agree, you should be able to foresee the result of a merge after
taking a look at the diff. Proper use of --ignore-ancestry or
--notice-ancestry provided of course.

> (And then of course there is that problem of backwards compatibility)

The reason for me to start this thread was the very specific problem of
the 'hole in the time-space continuum' that every copy of from-file_at_M to
to-file_at_N with M < N-1 creates. If you're looking at an annotated
version of to-file and found an interesting line, whose revision number
is -- ta-da! -- N, 'svn diff -rN-1:N to-file' fails in Subversion 1.6.23
and simply prints to-file_at_N as a new file in Subversion 1.8.0. This is a
very specific case, but a common use case IMHO.

I don't know if the changed behavior in this case in 1.8.0 was on
purpose, or if it's just an unintended side effect of some code change.
At the moment, neither Subversion 1.6.23 nor 1.8.0 are able to deal with
this case properly, so you shouldn't break anything if it was possible
to change the behavior for just this specific case, right?

> If you really want to make your head explode we can also bring in the
> problems around the definition or -r BASE in the context of diff or other
> commands.
> -r BASE is mostly used to describe the PRISTINE version of a node, but in
> some cases also as the clean checked out version... Which can be different
> in the case of a direct and/or ancestor replacement.


> Redefining any of this requires taking into account all these other ugly
> corner cases... and our backwards compatibility guarantees...
> (Small steps forward...)

Precision surgery, if possible? ;-)

Received on 2013-06-27 12:01:10 CEST

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