@@ -2398,6 +2398,27 @@ static void compute_collisions(struct strmap *collisions,
2398
2398
}
2399
2399
}
2400
2400
2401
+ static void free_collisions (struct strmap * collisions )
2402
+ {
2403
+ struct hashmap_iter iter ;
2404
+ struct strmap_entry * entry ;
2405
+
2406
+ /* Free each value in the collisions map */
2407
+ strmap_for_each_entry (collisions , & iter , entry ) {
2408
+ struct collision_info * info = entry -> value ;
2409
+ string_list_clear (& info -> source_files , 0 );
2410
+ }
2411
+ /*
2412
+ * In compute_collisions(), we set collisions.strdup_strings to 0
2413
+ * so that we wouldn't have to make another copy of the new_path
2414
+ * allocated by apply_dir_rename(). But now that we've used them
2415
+ * and have no other references to these strings, it is time to
2416
+ * deallocate them.
2417
+ */
2418
+ free_strmap_strings (collisions );
2419
+ strmap_clear (collisions , 1 );
2420
+ }
2421
+
2401
2422
static char * check_for_directory_rename (struct merge_options * opt ,
2402
2423
const char * path ,
2403
2424
unsigned side_index ,
@@ -2406,18 +2427,23 @@ static char *check_for_directory_rename(struct merge_options *opt,
2406
2427
struct strmap * collisions ,
2407
2428
int * clean_merge )
2408
2429
{
2409
- char * new_path = NULL ;
2430
+ char * new_path ;
2410
2431
struct strmap_entry * rename_info ;
2411
- struct strmap_entry * otherinfo = NULL ;
2432
+ struct strmap_entry * otherinfo ;
2412
2433
const char * new_dir ;
2434
+ int other_side = 3 - side_index ;
2413
2435
2436
+ /*
2437
+ * Cases where we don't have or don't want a directory rename for
2438
+ * this path.
2439
+ */
2414
2440
if (strmap_empty (dir_renames ))
2415
- return new_path ;
2441
+ return NULL ;
2442
+ if (strmap_get (& collisions [other_side ], path ))
2443
+ return NULL ;
2416
2444
rename_info = check_dir_renamed (path , dir_renames );
2417
2445
if (!rename_info )
2418
- return new_path ;
2419
- /* old_dir = rename_info->key; */
2420
- new_dir = rename_info -> value ;
2446
+ return NULL ;
2421
2447
2422
2448
/*
2423
2449
* This next part is a little weird. We do not want to do an
@@ -2443,6 +2469,7 @@ static char *check_for_directory_rename(struct merge_options *opt,
2443
2469
* As it turns out, this also prevents N-way transient rename
2444
2470
* confusion; See testcases 9c and 9d of t6043.
2445
2471
*/
2472
+ new_dir = rename_info -> value ; /* old_dir = rename_info->key; */
2446
2473
otherinfo = strmap_get_entry (dir_rename_exclusions , new_dir );
2447
2474
if (otherinfo ) {
2448
2475
path_msg (opt , INFO_DIR_RENAME_SKIPPED_DUE_TO_RERENAME , 1 ,
@@ -2454,7 +2481,8 @@ static char *check_for_directory_rename(struct merge_options *opt,
2454
2481
}
2455
2482
2456
2483
new_path = handle_path_level_conflicts (opt , path , side_index ,
2457
- rename_info , collisions );
2484
+ rename_info ,
2485
+ & collisions [side_index ]);
2458
2486
* clean_merge &= (new_path != NULL );
2459
2487
2460
2488
return new_path ;
@@ -3171,18 +3199,15 @@ static int detect_regular_renames(struct merge_options *opt,
3171
3199
static int collect_renames (struct merge_options * opt ,
3172
3200
struct diff_queue_struct * result ,
3173
3201
unsigned side_index ,
3202
+ struct strmap * collisions ,
3174
3203
struct strmap * dir_renames_for_side ,
3175
3204
struct strmap * rename_exclusions )
3176
3205
{
3177
3206
int i , clean = 1 ;
3178
- struct strmap collisions ;
3179
3207
struct diff_queue_struct * side_pairs ;
3180
- struct hashmap_iter iter ;
3181
- struct strmap_entry * entry ;
3182
3208
struct rename_info * renames = & opt -> priv -> renames ;
3183
3209
3184
3210
side_pairs = & renames -> pairs [side_index ];
3185
- compute_collisions (& collisions , dir_renames_for_side , side_pairs );
3186
3211
3187
3212
for (i = 0 ; i < side_pairs -> nr ; ++ i ) {
3188
3213
struct diff_filepair * p = side_pairs -> queue [i ];
@@ -3198,7 +3223,7 @@ static int collect_renames(struct merge_options *opt,
3198
3223
side_index ,
3199
3224
dir_renames_for_side ,
3200
3225
rename_exclusions ,
3201
- & collisions ,
3226
+ collisions ,
3202
3227
& clean );
3203
3228
3204
3229
possibly_cache_new_pair (renames , p , side_index , new_path );
@@ -3224,20 +3249,6 @@ static int collect_renames(struct merge_options *opt,
3224
3249
result -> queue [result -> nr ++ ] = p ;
3225
3250
}
3226
3251
3227
- /* Free each value in the collisions map */
3228
- strmap_for_each_entry (& collisions , & iter , entry ) {
3229
- struct collision_info * info = entry -> value ;
3230
- string_list_clear (& info -> source_files , 0 );
3231
- }
3232
- /*
3233
- * In compute_collisions(), we set collisions.strdup_strings to 0
3234
- * so that we wouldn't have to make another copy of the new_path
3235
- * allocated by apply_dir_rename(). But now that we've used them
3236
- * and have no other references to these strings, it is time to
3237
- * deallocate them.
3238
- */
3239
- free_strmap_strings (& collisions );
3240
- strmap_clear (& collisions , 1 );
3241
3252
return clean ;
3242
3253
}
3243
3254
@@ -3248,6 +3259,7 @@ static int detect_and_process_renames(struct merge_options *opt,
3248
3259
{
3249
3260
struct diff_queue_struct combined = { 0 };
3250
3261
struct rename_info * renames = & opt -> priv -> renames ;
3262
+ struct strmap collisions [3 ];
3251
3263
int need_dir_renames , s , i , clean = 1 ;
3252
3264
unsigned detection_run = 0 ;
3253
3265
@@ -3297,12 +3309,22 @@ static int detect_and_process_renames(struct merge_options *opt,
3297
3309
ALLOC_GROW (combined .queue ,
3298
3310
renames -> pairs [1 ].nr + renames -> pairs [2 ].nr ,
3299
3311
combined .alloc );
3312
+ for (i = MERGE_SIDE1 ; i <= MERGE_SIDE2 ; i ++ ) {
3313
+ int other_side = 3 - i ;
3314
+ compute_collisions (& collisions [i ],
3315
+ & renames -> dir_renames [other_side ],
3316
+ & renames -> pairs [i ]);
3317
+ }
3300
3318
clean &= collect_renames (opt , & combined , MERGE_SIDE1 ,
3319
+ collisions ,
3301
3320
& renames -> dir_renames [2 ],
3302
3321
& renames -> dir_renames [1 ]);
3303
3322
clean &= collect_renames (opt , & combined , MERGE_SIDE2 ,
3323
+ collisions ,
3304
3324
& renames -> dir_renames [1 ],
3305
3325
& renames -> dir_renames [2 ]);
3326
+ for (i = MERGE_SIDE1 ; i <= MERGE_SIDE2 ; i ++ )
3327
+ free_collisions (& collisions [i ]);
3306
3328
STABLE_QSORT (combined .queue , combined .nr , compare_pairs );
3307
3329
trace2_region_leave ("merge" , "directory renames" , opt -> repo );
3308
3330
0 commit comments