Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> writes: > [ However, there does seem to be a bug in the "-B" logic, so it doesn't > actually work as well as it should! See below ] I finally had a bit of time to follow this through. After running your set-up using revision.c and Makefile to emulate the situation, you can try running: $ git diff-tree -B -C --numstat --summary HEAD or $ git diff-tree -B -M --numstat --summary HEAD which would say: 90028d007986de4db8c3af30a2d5e5c00e5a2c8b 0 0 revision.c => old-revision.c 1117 1579 revision.c rename revision.c => old-revision.c (100%) rewrite revision.c (98%) The code is working as intended (it is a different discussion if "as intended" is actually the desired behaviour). We take the preimage tree as a whole, and express postimage in terms of series of patches, _however_ we do not interpret the series of patches as _incremental_. IOW, when we talk about the effect of the second patch that describes the postimage of revision.c, we pretend as if nothing happened with the first patch (which renamed away revision.c). So "rewrite revision.c" is what we say, not "create revision.c anew, because the first one renamed it away". This behaviour actually was a bit counterintuitive to me. I did not implement the very original rename/copy the way we currently operate. It was corrected into the current behaviour, following the guiding principle described in this message: http://thread.gmane.org/gmane.comp.version-control.git/3807 which is reproduced below. From: Linus Torvalds <torvalds@xxxxxxxx> Date: Mon, 23 May 2005 07:49:01 -0700 (PDT) Subject: Re: [PATCH] Make sure diff-helper can tell rename/copy in the new diff-raw format. Message-ID: <Pine.LNX.4.58.0505230736180.2307@xxxxxxxxxxxxxxx> On Mon, 23 May 2005, Junio C Hamano wrote: > > This adds tests to make sure that diff-helper can tell renames > from copies using the same "everything but the last one are > copies and the last one is either rename or stay" logic. Btw, I still disagree... ... For example, let's say that you have modified "fileA" _and_ you have created a "fileB" that is a copy of the original "fileA" with some _other_ slight modifications. We'll call the SHA1's involved "sha_A", "sha_A'" and "sha_B" I think it's perfectly valid to say :100644 100644 <sha_A> <sha_A'> M fileA fileA :100644 100644 <sha_A> <sha_B> C89 fileA fileB which says "fileA" was modified from orig-A to new-A, and "fileB" is a copy based on orig-A. Now, when the above is turned into a "diff", that diff is no longer something you can apply "incrementally" - you have to apply it as if you're applying all differences to the "original tree". But the thing is, that's actually what I _want_, because I was planning on writing a tool that applies patches that applies them all-or-nothing. Also, it turns out that this kind of "non-incremental" diff is the kind that I personally want to see as a _human_, because quite frankly, my brain-capacity is that of a demented ocelot, and I can't _remember_ what happened in other parts of the diff. I much prefer the stateless "oh, this file X is in that relation Y to the previous version of file Z". I do that partly because I actually routinely edit patches. If you have the incremental format, that's practically impossible, while the stateless version is fine. See? So I think all the clever "don't re-use files we have modified" etc is actually wrong. If you want to make a traditional diff that can be applied with normal "patch", you just don't use the -M or -C flags. Linus - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html