diff options
author | Junio C Hamano <gitster@pobox.com> | 2011-01-06 13:50:06 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2011-03-22 14:29:07 -0700 |
commit | f31027c99cb2ec4eb7ad8d1ebc7f0e20fef4bd1d (patch) | |
tree | ecc4d0213fcbd8c270b254cec1caff867034ac7d /diffcore-rename.c | |
parent | e88d6bc6f90059f6e87f6d51eba83ec15e4eecc9 (diff) | |
download | git-f31027c99cb2ec4eb7ad8d1ebc7f0e20fef4bd1d.tar.gz |
diffcore-rename: fall back to -C when -C -C busts the rename limit
When there are too many paths in the project, the number of rename source
candidates "git diff -C -C" finds will exceed the rename detection limit,
and no inexact rename detection is performed. We however could fall back
to "git diff -C" if the number of modified paths is sufficiently small.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'diffcore-rename.c')
-rw-r--r-- | diffcore-rename.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/diffcore-rename.c b/diffcore-rename.c index a932f762d2..f62587e523 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -420,11 +420,18 @@ static void record_if_better(struct diff_score m[], struct diff_score *o) m[worst] = *o; } +/* + * Returns: + * 0 if we are under the limit; + * 1 if we need to disable inexact rename detection; + * 2 if we would be under the limit if we were given -C instead of -C -C. + */ static int too_many_rename_candidates(int num_create, struct diff_options *options) { int rename_limit = options->rename_limit; int num_src = rename_src_nr; + int i; options->needed_rename_limit = 0; @@ -445,6 +452,20 @@ static int too_many_rename_candidates(int num_create, options->needed_rename_limit = num_src > num_create ? num_src : num_create; + + /* Are we running under -C -C? */ + if (!DIFF_OPT_TST(options, FIND_COPIES_HARDER)) + return 1; + + /* Would we bust the limit if we were running under -C? */ + for (num_src = i = 0; i < rename_src_nr; i++) { + if (diff_unmodified_pair(rename_src[i].p)) + continue; + num_src++; + } + if ((num_create <= rename_limit || num_src <= rename_limit) && + (num_create * num_src <= rename_limit * rename_limit)) + return 2; return 1; } @@ -476,7 +497,7 @@ void diffcore_rename(struct diff_options *options) struct diff_queue_struct *q = &diff_queued_diff; struct diff_queue_struct outq; struct diff_score *mx; - int i, j, rename_count; + int i, j, rename_count, skip_unmodified = 0; int num_create, num_src, dst_cnt; struct progress *progress = NULL; @@ -539,8 +560,16 @@ void diffcore_rename(struct diff_options *options) if (!num_create) goto cleanup; - if (too_many_rename_candidates(num_create, options)) + switch (too_many_rename_candidates(num_create, options)) { + case 1: goto cleanup; + case 2: + options->degraded_cc_to_c = 1; + skip_unmodified = 1; + break; + default: + break; + } if (options->show_rename_progress) { progress = start_progress_delay( @@ -563,6 +592,11 @@ void diffcore_rename(struct diff_options *options) for (j = 0; j < rename_src_nr; j++) { struct diff_filespec *one = rename_src[j].p->one; struct diff_score this_src; + + if (skip_unmodified && + diff_unmodified_pair(rename_src[j].p)) + continue; + this_src.score = estimate_similarity(one, two, minimum_score); this_src.name_score = basename_same(one, two); |