[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: Tue, 25 Jun 2013 17:59:27 +0200

On 25.06.2013, at 16:45, Stefan Sperling wrote:
> On Tue, Jun 25, 2013 at 04:24:36PM +0200, Tobias Bading wrote:
>> Dear Devs,
>> GNU Emacs 24.3 was behaving a little odd today while trying to
>> display a svn diff from Annotate mode. It simply barked "svn: Unable
>> to find repository location for '...' in revision ..." at me :-(.
>> Since this wasn't the first time Emacs left me in the rain like
>> this, I thought it was time to take a closer look.
>> This much I was able to figure out:
>> If you copy a file from revision N-1, modify the copy and then
>> commit it as revision N, 'svn diff -cN FILE' works as expected
>> afterwards. It works no matter whether you use Subversion 1.6 or
>> 1.8, no matter whether you specify FILE as a working copy path or a
>> repository URL. "Works as expected" meaning that it shows the
>> modifications you made, not the entire file as an add.
>> However, if you copy a file from a revision M that is smaller than
>> N-1, modify the copy and then commit it as revision N, 'svn diff -cN
>> FILE' won't play along. Subversion 1.6 simply barks "svn: Unable to
>> find repository location for 'FILE' in revision N-1", whereas
>> Subversion 1.8 shows the whole file as an add, i.e. does a diff
>> -r0:N :-(. An 'svn diff -rM:N FILE' on the other hand works fine.
> There is a related issue that was fixed in 1.7.2:
> http://subversion.tigris.org/issues/show_bug.cgi?id=2873
>> Emacs executes 'svn --non-interactive diff -r N-1:N FILE' for
>> revision N at the current line when you press d in Annotate mode,
>> which of course barfs just as much as 'diff -cN' does in the
>> described case with M < N-1.
>> Would it be possible to spice up the semantics of -cN a bit?
> The meaning of -c is and always has been '-r N-1:N'.
> I don't think we'd want to change this, even if only for compatibility
> purposes.
>> I don't know enough about the innards of Subversion to understand
>> why -rM:N works but -rN-1:N doesn't, but I think trying to figure
>> out the correct value of M for the current line in Emacs' Annotate
>> mode might get painfull.
> I cannot comment on the emacs plugin you're using.

There's no plugin involved, simply GNU Emacs' vc-svn.el, i.e. the implementation of Emacs version control features for Subversion. There are other implementations for git/bazaar/..., all using the same menus, keyboard shortcuts etc. Annotate mode is simply the output of 'svn blame' (or similar for other VC systems) with rainbow coloring on top, that is coloring from red for new lines to blue for old ones.

> Note that however if the file does not exist at revision N-1 and does exist at rN, and you're asking 'svn diff' to show how this file differs between revision N-1 and N, you'll always see a full copy of the file. I don't see anything wrong with that.

Hmm, but why is diff -cM:N working if the file was copied from revision M? Sure, the target of the copy operation did not exist in revision N-1 if M < N-1, but it didn't exist in revision M either.

> I would say the emacs plugin needs to be made smarter about the
> revision ranges it is diffing when showing changes. Perhaps try
> to contact the plugin's maintainer for help.

IMHO this has nothing to do with Emacs, at least not from my point of view. But maybe I'm just expecting too much of 'diff -cN'.

This is how I personally use 'svn diff -cN XYZ' and what I expect to see when using it:
If XYZ is a directory in a working copy or a directory in a repository, show me what was changed in revision N below that directory (including property changes of the directory itself).
If XYZ is a file in a working copy or a file in a repository, show me what was changed in revision N in that file (including property changes).

My expectations and reality usually match nicely (in this case). But there's always someone who doesn't want to play along ;-).

So the question is this:
If I'd like to see (or merge) the changes made in a revision N to a file that was created by copying and then modifying in that very revision, what would be the proper command to run?

Let's say the log of a revision 42 says:
   A /D2/f (from /D1/f:7)
This log line alone does not tell me whether f was simply copied, or copied and then modified. Do I really have to do a 'svn diff -r7:42 D2/f' (or even worse 'svn diff D1/f_at_7 D2/f_at_42') to figure out whether the copy was modified? How is a tool supposed to come up with the 7, if the user would simply like to know "What was changed in revision 42 in D2/f?" The tool would have to look at the log of D2/f to check for the revision prior to 42 and then do the 'diff -r7:42'. A working 'diff -c42' would be that much nicer...

Received on 2013-06-25 18:00:09 CEST

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