@@ -2271,6 +2271,47 @@ static void resolve_diffpair_statuses(struct diff_queue_struct *q)
2271
2271
}
2272
2272
}
2273
2273
2274
+ static void possibly_cache_new_pair (struct rename_info * renames ,
2275
+ struct diff_filepair * p ,
2276
+ unsigned side ,
2277
+ char * new_path )
2278
+ {
2279
+ char * old_value ;
2280
+
2281
+ if (!new_path ) {
2282
+ int val = strintmap_get (& renames -> relevant_sources [side ],
2283
+ p -> one -> path );
2284
+ if (val == 0 ) {
2285
+ assert (p -> status == 'D' );
2286
+ strset_add (& renames -> cached_irrelevant [side ],
2287
+ p -> one -> path );
2288
+ }
2289
+ if (val <= 0 )
2290
+ return ;
2291
+ }
2292
+ if (p -> status == 'D' ) {
2293
+ /*
2294
+ * If we already had this delete, we'll just set it's value
2295
+ * to NULL again, so no harm.
2296
+ */
2297
+ strmap_put (& renames -> cached_pairs [side ], p -> one -> path , NULL );
2298
+ } else if (p -> status == 'R' ) {
2299
+ if (!new_path )
2300
+ new_path = p -> two -> path ;
2301
+ new_path = xstrdup (new_path );
2302
+ old_value = strmap_put (& renames -> cached_pairs [side ],
2303
+ p -> one -> path , new_path );
2304
+ strset_add (& renames -> cached_target_names [side ], new_path );
2305
+ free (old_value );
2306
+ } else if (p -> status == 'A' && new_path ) {
2307
+ new_path = xstrdup (new_path );
2308
+ old_value = strmap_put (& renames -> cached_pairs [side ],
2309
+ p -> two -> path , new_path );
2310
+ strset_add (& renames -> cached_target_names [side ], new_path );
2311
+ assert (!old_value );
2312
+ }
2313
+ }
2314
+
2274
2315
static int compare_pairs (const void * a_ , const void * b_ )
2275
2316
{
2276
2317
const struct diff_filepair * a = * ((const struct diff_filepair * * )a_ );
@@ -2352,6 +2393,7 @@ static int collect_renames(struct merge_options *opt,
2352
2393
struct diff_filepair * p = side_pairs -> queue [i ];
2353
2394
char * new_path ; /* non-NULL only with directory renames */
2354
2395
2396
+ possibly_cache_new_pair (renames , p , side_index , NULL );
2355
2397
if (p -> status != 'A' && p -> status != 'R' ) {
2356
2398
diff_free_filepair (p );
2357
2399
continue ;
@@ -2368,7 +2410,7 @@ static int collect_renames(struct merge_options *opt,
2368
2410
diff_free_filepair (p );
2369
2411
continue ;
2370
2412
}
2371
-
2413
+ possibly_cache_new_pair ( renames , p , side_index , new_path );
2372
2414
if (new_path )
2373
2415
apply_directory_rename_modifications (opt , p , new_path );
2374
2416
@@ -3532,8 +3574,16 @@ static void merge_start(struct merge_options *opt, struct merge_result *result)
3532
3574
NULL , 1 );
3533
3575
strmap_init_with_options (& renames -> dir_renames [i ],
3534
3576
NULL , 0 );
3577
+ /*
3578
+ * relevant_sources uses -1 for the default, because we need
3579
+ * to be able to distinguish not-in-strintmap from valid
3580
+ * relevant_source values from enum file_rename_relevance.
3581
+ * In particular, possibly_cache_new_pair() expects a negative
3582
+ * value for not-found entries.
3583
+ */
3535
3584
strintmap_init_with_options (& renames -> relevant_sources [i ],
3536
- 0 , NULL , 0 );
3585
+ -1 /* explicitly invalid */ ,
3586
+ NULL , 0 );
3537
3587
strmap_init_with_options (& renames -> cached_pairs [i ],
3538
3588
NULL , 1 );
3539
3589
strset_init_with_options (& renames -> cached_irrelevant [i ],
0 commit comments