@@ -55,22 +55,23 @@ static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two,
55
55
56
56
/* Table of rename/copy src files */
57
57
static struct diff_rename_src {
58
- struct diff_filespec * one ;
58
+ struct diff_filepair * p ;
59
59
unsigned short score ; /* to remember the break score */
60
60
} * rename_src ;
61
61
static int rename_src_nr , rename_src_alloc ;
62
62
63
- static struct diff_rename_src * register_rename_src (struct diff_filespec * one ,
64
- unsigned short score )
63
+ static struct diff_rename_src * register_rename_src (struct diff_filepair * p )
65
64
{
66
65
int first , last ;
66
+ struct diff_filespec * one = p -> one ;
67
+ unsigned short score = p -> score ;
67
68
68
69
first = 0 ;
69
70
last = rename_src_nr ;
70
71
while (last > first ) {
71
72
int next = (last + first ) >> 1 ;
72
73
struct diff_rename_src * src = & (rename_src [next ]);
73
- int cmp = strcmp (one -> path , src -> one -> path );
74
+ int cmp = strcmp (one -> path , src -> p -> one -> path );
74
75
if (!cmp )
75
76
return src ;
76
77
if (cmp < 0 ) {
@@ -90,7 +91,7 @@ static struct diff_rename_src *register_rename_src(struct diff_filespec *one,
90
91
if (first < rename_src_nr )
91
92
memmove (rename_src + first + 1 , rename_src + first ,
92
93
(rename_src_nr - first - 1 ) * sizeof (* rename_src ));
93
- rename_src [first ].one = one ;
94
+ rename_src [first ].p = p ;
94
95
rename_src [first ].score = score ;
95
96
return & (rename_src [first ]);
96
97
}
@@ -205,7 +206,7 @@ static void record_rename_pair(int dst_index, int src_index, int score)
205
206
if (rename_dst [dst_index ].pair )
206
207
die ("internal error: dst already matched." );
207
208
208
- src = rename_src [src_index ].one ;
209
+ src = rename_src [src_index ].p -> one ;
209
210
src -> rename_used ++ ;
210
211
src -> count ++ ;
211
212
@@ -389,7 +390,7 @@ static int find_exact_renames(struct diff_options *options)
389
390
390
391
init_hash (& file_table );
391
392
for (i = 0 ; i < rename_src_nr ; i ++ )
392
- insert_file_table (& file_table , -1 , i , rename_src [i ].one );
393
+ insert_file_table (& file_table , -1 , i , rename_src [i ].p -> one );
393
394
394
395
for (i = 0 ; i < rename_dst_nr ; i ++ )
395
396
insert_file_table (& file_table , 1 , i , rename_dst [i ].two );
@@ -419,6 +420,55 @@ static void record_if_better(struct diff_score m[], struct diff_score *o)
419
420
m [worst ] = * o ;
420
421
}
421
422
423
+ /*
424
+ * Returns:
425
+ * 0 if we are under the limit;
426
+ * 1 if we need to disable inexact rename detection;
427
+ * 2 if we would be under the limit if we were given -C instead of -C -C.
428
+ */
429
+ static int too_many_rename_candidates (int num_create ,
430
+ struct diff_options * options )
431
+ {
432
+ int rename_limit = options -> rename_limit ;
433
+ int num_src = rename_src_nr ;
434
+ int i ;
435
+
436
+ options -> needed_rename_limit = 0 ;
437
+
438
+ /*
439
+ * This basically does a test for the rename matrix not
440
+ * growing larger than a "rename_limit" square matrix, ie:
441
+ *
442
+ * num_create * num_src > rename_limit * rename_limit
443
+ *
444
+ * but handles the potential overflow case specially (and we
445
+ * assume at least 32-bit integers)
446
+ */
447
+ if (rename_limit <= 0 || rename_limit > 32767 )
448
+ rename_limit = 32767 ;
449
+ if ((num_create <= rename_limit || num_src <= rename_limit ) &&
450
+ (num_create * num_src <= rename_limit * rename_limit ))
451
+ return 0 ;
452
+
453
+ options -> needed_rename_limit =
454
+ num_src > num_create ? num_src : num_create ;
455
+
456
+ /* Are we running under -C -C? */
457
+ if (!DIFF_OPT_TST (options , FIND_COPIES_HARDER ))
458
+ return 1 ;
459
+
460
+ /* Would we bust the limit if we were running under -C? */
461
+ for (num_src = i = 0 ; i < rename_src_nr ; i ++ ) {
462
+ if (diff_unmodified_pair (rename_src [i ].p ))
463
+ continue ;
464
+ num_src ++ ;
465
+ }
466
+ if ((num_create <= rename_limit || num_src <= rename_limit ) &&
467
+ (num_create * num_src <= rename_limit * rename_limit ))
468
+ return 2 ;
469
+ return 1 ;
470
+ }
471
+
422
472
static int find_renames (struct diff_score * mx , int dst_cnt , int minimum_score , int copies )
423
473
{
424
474
int count = 0 , i ;
@@ -432,7 +482,7 @@ static int find_renames(struct diff_score *mx, int dst_cnt, int minimum_score, i
432
482
dst = & rename_dst [mx [i ].dst ];
433
483
if (dst -> pair )
434
484
continue ; /* already done, either exact or fuzzy. */
435
- if (!copies && rename_src [mx [i ].src ].one -> rename_used )
485
+ if (!copies && rename_src [mx [i ].src ].p -> one -> rename_used )
436
486
continue ;
437
487
record_rename_pair (mx [i ].dst , mx [i ].src , mx [i ].score );
438
488
count ++ ;
@@ -444,11 +494,10 @@ void diffcore_rename(struct diff_options *options)
444
494
{
445
495
int detect_rename = options -> detect_rename ;
446
496
int minimum_score = options -> rename_score ;
447
- int rename_limit = options -> rename_limit ;
448
497
struct diff_queue_struct * q = & diff_queued_diff ;
449
498
struct diff_queue_struct outq ;
450
499
struct diff_score * mx ;
451
- int i , j , rename_count ;
500
+ int i , j , rename_count , skip_unmodified = 0 ;
452
501
int num_create , num_src , dst_cnt ;
453
502
struct progress * progress = NULL ;
454
503
@@ -476,15 +525,15 @@ void diffcore_rename(struct diff_options *options)
476
525
*/
477
526
if (p -> broken_pair && !p -> score )
478
527
p -> one -> rename_used ++ ;
479
- register_rename_src (p -> one , p -> score );
528
+ register_rename_src (p );
480
529
}
481
530
else if (detect_rename == DIFF_DETECT_COPY ) {
482
531
/*
483
532
* Increment the "rename_used" score by
484
533
* one, to indicate ourselves as a user.
485
534
*/
486
535
p -> one -> rename_used ++ ;
487
- register_rename_src (p -> one , p -> score );
536
+ register_rename_src (p );
488
537
}
489
538
}
490
539
if (rename_dst_nr == 0 || rename_src_nr == 0 )
@@ -511,23 +560,15 @@ void diffcore_rename(struct diff_options *options)
511
560
if (!num_create )
512
561
goto cleanup ;
513
562
514
- /*
515
- * This basically does a test for the rename matrix not
516
- * growing larger than a "rename_limit" square matrix, ie:
517
- *
518
- * num_create * num_src > rename_limit * rename_limit
519
- *
520
- * but handles the potential overflow case specially (and we
521
- * assume at least 32-bit integers)
522
- */
523
- options -> needed_rename_limit = 0 ;
524
- if (rename_limit <= 0 || rename_limit > 32767 )
525
- rename_limit = 32767 ;
526
- if ((num_create > rename_limit && num_src > rename_limit ) ||
527
- (num_create * num_src > rename_limit * rename_limit )) {
528
- options -> needed_rename_limit =
529
- num_src > num_create ? num_src : num_create ;
563
+ switch (too_many_rename_candidates (num_create , options )) {
564
+ case 1 :
530
565
goto cleanup ;
566
+ case 2 :
567
+ options -> degraded_cc_to_c = 1 ;
568
+ skip_unmodified = 1 ;
569
+ break ;
570
+ default :
571
+ break ;
531
572
}
532
573
533
574
if (options -> show_rename_progress ) {
@@ -549,8 +590,13 @@ void diffcore_rename(struct diff_options *options)
549
590
m [j ].dst = -1 ;
550
591
551
592
for (j = 0 ; j < rename_src_nr ; j ++ ) {
552
- struct diff_filespec * one = rename_src [j ].one ;
593
+ struct diff_filespec * one = rename_src [j ].p -> one ;
553
594
struct diff_score this_src ;
595
+
596
+ if (skip_unmodified &&
597
+ diff_unmodified_pair (rename_src [j ].p ))
598
+ continue ;
599
+
554
600
this_src .score = estimate_similarity (one , two ,
555
601
minimum_score );
556
602
this_src .name_score = basename_same (one , two );
0 commit comments