blame: -C -C -C

When you do this, existing "blame -C -C" would not find that the
latter half of the file2 came from the existing file1:

	... both file1 and file2 are tracked ...
	$ cat file1 >>file2
	$ git add file1 file2
	$ git commit

This is because we avoid the expensive find-copies-harder code
that makes unchanged file (in this case, file1) as a candidate
for copy & paste source when annotating an existing file
(file2).  The third -C now allows it.  However, this obviously
makes the process very expensive.  We've actually seen this
patch before, but I dismissed it because it covers such a narrow
(and arguably stupid) corner case.

Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Junio C Hamano 2007-05-05 21:18:57 -07:00
parent dd166aa8e5
commit c63777c0d7

View File

@ -55,6 +55,7 @@ static int num_commits;
#define PICKAXE_BLAME_MOVE 01 #define PICKAXE_BLAME_MOVE 01
#define PICKAXE_BLAME_COPY 02 #define PICKAXE_BLAME_COPY 02
#define PICKAXE_BLAME_COPY_HARDER 04 #define PICKAXE_BLAME_COPY_HARDER 04
#define PICKAXE_BLAME_COPY_HARDEST 010
/* /*
* blame for a blame_entry with score lower than these thresholds * blame for a blame_entry with score lower than these thresholds
@ -1079,8 +1080,9 @@ static int find_copy_in_parent(struct scoreboard *sb,
* and this code needs to be after diff_setup_done(), which * and this code needs to be after diff_setup_done(), which
* usually makes find-copies-harder imply copy detection. * usually makes find-copies-harder imply copy detection.
*/ */
if ((opt & PICKAXE_BLAME_COPY_HARDER) && if ((opt & PICKAXE_BLAME_COPY_HARDEST)
(!porigin || strcmp(target->path, porigin->path))) || ((opt & PICKAXE_BLAME_COPY_HARDER)
&& (!porigin || strcmp(target->path, porigin->path))))
diff_opts.find_copies_harder = 1; diff_opts.find_copies_harder = 1;
if (is_null_sha1(target->commit->object.sha1)) if (is_null_sha1(target->commit->object.sha1))
@ -2127,6 +2129,15 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
blame_move_score = parse_score(arg+2); blame_move_score = parse_score(arg+2);
} }
else if (!prefixcmp(arg, "-C")) { else if (!prefixcmp(arg, "-C")) {
/*
* -C enables copy from removed files;
* -C -C enables copy from existing files, but only
* when blaming a new file;
* -C -C -C enables copy from existing files for
* everybody
*/
if (opt & PICKAXE_BLAME_COPY_HARDER)
opt |= PICKAXE_BLAME_COPY_HARDEST;
if (opt & PICKAXE_BLAME_COPY) if (opt & PICKAXE_BLAME_COPY)
opt |= PICKAXE_BLAME_COPY_HARDER; opt |= PICKAXE_BLAME_COPY_HARDER;
opt |= PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE; opt |= PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE;