@matheusbsbs / matheus-bagliano / commits / 0940e5f211
Fork 0

diffcore-rename: properly honor the difference between -M and -C

We would allow rename detection to do copy detection even when asked purely for renames. That confuses users, but more importantly it can terminally confuse the recursive merge rename logic. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Linus Torvalds committed Feb 18, 2011 at 20:10 UTC 0940e5f211452ec2520d1b04233acddf0a872c06
6 files changed +32 -33
diffcore-rename.c
+26 -27
@@ -278,6 +278,8 @@ static int find_identical_files(struct file_similarity *src,
278 }
279 /* Give higher scores to sources that haven't been used already */
280 score = !source->rename_used;
281 + if (source->rename_used && options->detect_rename != DIFF_DETECT_COPY)
282 + continue;
283 score += basename_same(source, target);
284 if (score > best_score) {
285 best = p;
@@ -416,6 +418,27 @@ static void record_if_better(struct diff_score m[], struct diff_score *o)
418 m[worst] = *o;
419 }
420
421 +static int find_renames(struct diff_score *mx, int dst_cnt, int minimum_score, int copies)
422 +{
423 + int count = 0, i;
424 +
425 + for (i = 0; i < dst_cnt * NUM_CANDIDATE_PER_DST; i++) {
426 + struct diff_rename_dst *dst;
427 +
428 + if ((mx[i].dst < 0) ||
429 + (mx[i].score < minimum_score))
430 + break; /* there is no more usable pair. */
431 + dst = &rename_dst[mx[i].dst];
432 + if (dst->pair)
433 + continue; /* already done, either exact or fuzzy. */
434 + if (!copies && rename_src[mx[i].src].one->rename_used)
435 + continue;
436 + record_rename_pair(mx[i].dst, mx[i].src, mx[i].score);
437 + count++;
438 + }
439 + return count;
440 +}
441 +
442 void diffcore_rename(struct diff_options *options)
443 {
444 int detect_rename = options->detect_rename;
@@ -538,33 +561,9 @@ void diffcore_rename(struct diff_options *options)
561 /* cost matrix sorted by most to least similar pair */
562 qsort(mx, dst_cnt * NUM_CANDIDATE_PER_DST, sizeof(*mx), score_compare);
563
541 - for (i = 0; i < dst_cnt * NUM_CANDIDATE_PER_DST; i++) {
542 - struct diff_rename_dst *dst;
543 -
544 - if ((mx[i].dst < 0) ||
545 - (mx[i].score < minimum_score))
546 - break; /* there is no more usable pair. */
547 - dst = &rename_dst[mx[i].dst];
548 - if (dst->pair)
549 - continue; /* already done, either exact or fuzzy. */
550 - if (rename_src[mx[i].src].one->rename_used)
551 - continue;
552 - record_rename_pair(mx[i].dst, mx[i].src, mx[i].score);
553 - rename_count++;
554 - }
555 -
556 - for (i = 0; i < dst_cnt * NUM_CANDIDATE_PER_DST; i++) {
557 - struct diff_rename_dst *dst;
558 -
559 - if ((mx[i].dst < 0) ||
560 - (mx[i].score < minimum_score))
561 - break; /* there is no more usable pair. */
562 - dst = &rename_dst[mx[i].dst];
563 - if (dst->pair)
564 - continue; /* already done, either exact or fuzzy. */
565 - record_rename_pair(mx[i].dst, mx[i].src, mx[i].score);
566 - rename_count++;
567 - }
564 + rename_count += find_renames(mx, dst_cnt, minimum_score, 0);
565 + if (detect_rename == DIFF_DETECT_COPY)
566 + rename_count += find_renames(mx, dst_cnt, minimum_score, 1);
567 free(mx);
568
569 cleanup:
t/t4003-diff-rename-1.sh
+1 -1
@@ -29,7 +29,7 @@ test_expect_success \
29 # copy-and-edit one, and rename-and-edit the other. We do not say
30 # anything about rezrov.
31
32 -GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree >current
32 +GIT_DIFF_OPTS=--unified=0 git diff-index -C -p $tree >current
33 cat >expected <<\EOF
34 diff --git a/COPYING b/COPYING.1
35 copy from COPYING
t/t4004-diff-rename-symlink.sh
+1 -1
@@ -35,7 +35,7 @@ test_expect_success SYMLINKS \
35 # a new creation.
36
37 test_expect_success SYMLINKS 'setup diff output' "
38 - GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree >current &&
38 + GIT_DIFF_OPTS=--unified=0 git diff-index -C -p $tree >current &&
39 cat >expected <<\EOF
40 diff --git a/bozbar b/bozbar
41 new file mode 120000
t/t4005-diff-rename-2.sh
+1 -1
@@ -29,7 +29,7 @@ test_expect_success \
29 # and COPYING.2 are based on COPYING, and do not say anything about
30 # rezrov.
31
32 -git diff-index -M $tree >current
32 +git diff-index -C $tree >current
33
34 cat >expected <<\EOF
35 :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234 COPYING COPYING.1
t/t4008-diff-break-rewrite.sh
+2 -2
@@ -173,8 +173,8 @@ test_expect_success \
173 'compare_diff_raw expected current'
174
175 test_expect_success \
176 - 'run diff with -B -M' \
177 - 'git diff-index -B -M "$tree" >current'
176 + 'run diff with -B -C' \
177 + 'git diff-index -B -C "$tree" >current'
178
179 cat >expected <<\EOF
180 :100644 100644 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 08bb2fb671deff4c03a4d4a0a1315dff98d5732c C095 file0 file1
t/t4009-diff-rename-4.sh
+1 -1
@@ -29,7 +29,7 @@ test_expect_success \
29 # and COPYING.2 are based on COPYING, and do not say anything about
30 # rezrov.
31
32 -git diff-index -z -M $tree >current
32 +git diff-index -z -C $tree >current
33
34 cat >expected <<\EOF
35 :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 0603b3238a076dc6c8022aedc6648fa523a17178 C1234