@@ -684,7 +684,7 @@ int git_diff_find_similar(
684
684
git_diff_find_options opts ;
685
685
size_t num_rewrites = 0 , num_updates = 0 ;
686
686
void * * cache ; /* cache of similarity metric file signatures */
687
- diff_find_match * matches ; /* cache of best matches */
687
+ diff_find_match * match_sources , * match_targets ; /* cache of best matches */
688
688
689
689
if ((error = normalize_find_opts (diff , & opts , given_opts )) < 0 )
690
690
return error ;
@@ -697,16 +697,18 @@ int git_diff_find_similar(
697
697
cache = git__calloc (cache_size , sizeof (void * ));
698
698
GITERR_CHECK_ALLOC (cache );
699
699
700
- matches = git__calloc (diff -> deltas .length , sizeof (diff_find_match ));
701
- GITERR_CHECK_ALLOC (matches );
700
+ match_sources = git__calloc (diff -> deltas .length , sizeof (diff_find_match ));
701
+ match_targets = git__calloc (diff -> deltas .length , sizeof (diff_find_match ));
702
+ GITERR_CHECK_ALLOC (match_sources );
703
+ GITERR_CHECK_ALLOC (match_targets );
702
704
703
705
/* next find the most similar delta for each rename / copy candidate */
704
706
705
707
git_vector_foreach (& diff -> deltas , i , to ) {
706
708
size_t tried_sources = 0 ;
707
709
708
- matches [i ].idx = i ;
709
- matches [i ].similarity = 0 ;
710
+ match_targets [i ].idx = i ;
711
+ match_targets [i ].similarity = 0 ;
710
712
711
713
/* skip things that are not rename targets */
712
714
if (!is_rename_target (diff , & opts , i , cache ))
@@ -734,23 +736,26 @@ int git_diff_find_similar(
734
736
continue ;
735
737
}
736
738
737
- if (matches [i ].similarity < (uint32_t )similarity ) {
738
- matches [i ].similarity = (uint32_t )similarity ;
739
- matches [i ].idx = j ;
739
+ if (match_targets [i ].similarity < (uint32_t )similarity &&
740
+ match_sources [j ].similarity < (uint32_t )similarity ) {
741
+ match_targets [i ].similarity = (uint32_t )similarity ;
742
+ match_sources [j ].similarity = (uint32_t )similarity ;
743
+ match_targets [i ].idx = j ;
744
+ match_sources [j ].idx = i ;
740
745
}
741
746
}
742
747
}
743
748
744
749
/* next rewrite the diffs with renames / copies */
745
750
746
751
git_vector_foreach (& diff -> deltas , i , to ) {
747
-
748
- /* check if this delta was matched to another one */
749
- if ((similarity = (int )matches [i ].similarity ) <= 0 )
752
+ /* check if this delta was the target of a similarity */
753
+ if ((similarity = (int )match_targets [i ].similarity ) <= 0 )
750
754
continue ;
755
+
751
756
assert (to && (to -> flags & GIT_DIFF_FLAG__IS_RENAME_TARGET ) != 0 );
752
757
753
- from = GIT_VECTOR_GET (& diff -> deltas , matches [i ].idx );
758
+ from = GIT_VECTOR_GET (& diff -> deltas , match_targets [i ].idx );
754
759
assert (from && (from -> flags & GIT_DIFF_FLAG__IS_RENAME_SOURCE ) != 0 );
755
760
756
761
/* possible scenarios:
@@ -847,14 +852,14 @@ int git_diff_find_similar(
847
852
/* in the off chance that we've just swapped the new
848
853
* element into the correct place, clear the SPLIT flag
849
854
*/
850
- if (matches [ matches [i ].idx ].idx == i &&
851
- matches [ matches [i ].idx ].similarity >
855
+ if (match_targets [ match_targets [i ].idx ].idx == i &&
856
+ match_targets [ match_targets [i ].idx ].similarity >
852
857
opts .rename_from_rewrite_threshold ) {
853
858
854
859
from -> status = GIT_DELTA_RENAMED ;
855
860
from -> similarity =
856
- (uint32_t )matches [ matches [i ].idx ].similarity ;
857
- matches [ matches [i ].idx ].similarity = 0 ;
861
+ (uint32_t )match_targets [ match_targets [i ].idx ].similarity ;
862
+ match_targets [ match_targets [i ].idx ].similarity = 0 ;
858
863
from -> flags &= ~GIT_DIFF_FLAG__TO_SPLIT ;
859
864
num_rewrites -- ;
860
865
}
@@ -882,7 +887,8 @@ int git_diff_find_similar(
882
887
FLAG_SET (& opts , GIT_DIFF_BREAK_REWRITES ));
883
888
884
889
cleanup :
885
- git__free (matches );
890
+ git__free (match_sources );
891
+ git__free (match_targets );
886
892
887
893
for (i = 0 ; i < cache_size ; ++ i ) {
888
894
if (cache [i ] != NULL )
0 commit comments