git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: bisect / history preserving on rename + update

From
Linus Torvalds <torvalds@linux-foundation.org>
Date
Aug 14, 2007, 16:14 UTC
Message-ID
<alpine.LFD.0.999.0708140853500.30176@woody.linux-foundation.org>
In-Reply-To
<1187080681.12828.174.camel@chaos>
On Tue, 14 Aug 2007, Thomas Gleixner wrote:
Show 5 quoted lines
>
> is there a built in way to handle the following situation:
> 
> file A is renamed to B
> file A is created again and new content is added.
That "should just work".
[ 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 ]

BUT! By default, rename detection isn't on at all, mostly because it results in patches that non-git "patch" cannot apply, but partly also because it can slow certain things down.

So to get nice diffs, use
	git show -B -C
where the magic is:
 - "-B" means "break file associations when a file is *too* dissimilar" 
   Normally, git will assume that if a filename stays around, it's the 
   same file. However, with "-B", it does similarity analysis even for 
   files that are the same, and if they are very different, git will 
   decide that maybe they weren't the same file after all!
 - "-C" is "find code movement and copying".

However, nobody ever actually uses "-B" (it's so rare as to effectively not exist, and it does slow things down a bit), so it seems to have bit-rotted (or maybe it had this bug even originally: as I said, I don't think anybody has ever really _used_ this functionality).

Junio, look at this:
	# create a repo in "testing"
	cd
	mkdir testing
	cd testing/
	git init
	# copy a file from the git repo
	cp ~/git/revision.c .
	git add revision.c
	git commit -a -m "Add file 'A'"
	# move it around, copy another file in its stead
	git mv revision.c old-revision.c
	cp ~/git/Makefile revision.c
	git add revision.c
	git commit -a -m "Move file 'A' to 'B', create new 'A'"
	git show -B -C
and notice how "-B" *did* actually work, and we get a nice:
	diff --git a/revision.c b/old-revision.c
	similarity index 100%
	rename from revision.c
	rename to old-revision.c
but then it breaks: instead of creating the new "revision.c", we get:
	diff --git a/revision.c b/revision.c
	dissimilarity index 98%
	index 038693c..4eb4637 100644
	--- a/revision.c
	+++ b/revision.c
	@@ -1,1572 +1,1117 @@
	-#include "cache.h"
	...

which uses "reivision.c" as the base, even though it was already broken up! I think it *should* have looked like

	diff --git a/old-revision.c b/old-revision.c
	new file mode 100644
	index 0000000..4eb4637
	--- /dev/null
	+++ b/revision.c
	+# The default target of this Makefile is...
	...

so I think there is a bug there where the "-B" thing doesn't really "stick", and some part still uses the old file content even though it was dis-associated with the new content!

Hmm?
			Linus
Previous: David KastrupNext: Junio C Hamano
Message 11 of 15 in “bisect / history preserving on rename + update”
  1. Thomas GleixnerAug 14, 2007
  2. Karl HasselströmAug 14, 2007
  3. Thomas GleixnerAug 14, 2007
  4. Karl HasselströmAug 14, 2007
  5. Thomas GleixnerAug 14, 2007
  6. David KastrupAug 14, 2007
  7. Karl HasselströmAug 14, 2007
  8. Thomas GleixnerAug 14, 2007
  9. David KastrupAug 14, 2007
  10. David KastrupAug 14, 2007
  11. Linus TorvaldsAug 14, 2007
  12. Junio C HamanoAug 25, 2007
  13. David KastrupAug 25, 2007
  14. Linus TorvaldsAug 25, 2007
  15. Junio C HamanoAug 25, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.