@@ -2260,6 +2260,27 @@ static void compute_collisions(struct strmap *collisions,
2260
2260
}
2261
2261
}
2262
2262
2263
+ static void free_collisions (struct strmap * collisions )
2264
+ {
2265
+ struct hashmap_iter iter ;
2266
+ struct strmap_entry * entry ;
2267
+
2268
+ /* Free each value in the collisions map */
2269
+ strmap_for_each_entry (collisions , & iter , entry ) {
2270
+ struct collision_info * info = entry -> value ;
2271
+ string_list_clear (& info -> source_files , 0 );
2272
+ }
2273
+ /*
2274
+ * In compute_collisions(), we set collisions.strdup_strings to 0
2275
+ * so that we wouldn't have to make another copy of the new_path
2276
+ * allocated by apply_dir_rename(). But now that we've used them
2277
+ * and have no other references to these strings, it is time to
2278
+ * deallocate them.
2279
+ */
2280
+ free_strmap_strings (collisions );
2281
+ strmap_clear (collisions , 1 );
2282
+ }
2283
+
2263
2284
static char * check_for_directory_rename (struct merge_options * opt ,
2264
2285
const char * path ,
2265
2286
unsigned side_index ,
@@ -2268,18 +2289,23 @@ static char *check_for_directory_rename(struct merge_options *opt,
2268
2289
struct strmap * collisions ,
2269
2290
int * clean_merge )
2270
2291
{
2271
- char * new_path = NULL ;
2292
+ char * new_path ;
2272
2293
struct strmap_entry * rename_info ;
2273
- struct strmap_entry * otherinfo = NULL ;
2294
+ struct strmap_entry * otherinfo ;
2274
2295
const char * new_dir ;
2296
+ int other_side = 3 - side_index ;
2275
2297
2298
+ /*
2299
+ * Cases where we don't have or don't want a directory rename for
2300
+ * this path.
2301
+ */
2276
2302
if (strmap_empty (dir_renames ))
2277
- return new_path ;
2303
+ return NULL ;
2304
+ if (strmap_get (& collisions [other_side ], path ))
2305
+ return NULL ;
2278
2306
rename_info = check_dir_renamed (path , dir_renames );
2279
2307
if (!rename_info )
2280
- return new_path ;
2281
- /* old_dir = rename_info->key; */
2282
- new_dir = rename_info -> value ;
2308
+ return NULL ;
2283
2309
2284
2310
/*
2285
2311
* This next part is a little weird. We do not want to do an
@@ -2305,6 +2331,7 @@ static char *check_for_directory_rename(struct merge_options *opt,
2305
2331
* As it turns out, this also prevents N-way transient rename
2306
2332
* confusion; See testcases 9c and 9d of t6043.
2307
2333
*/
2334
+ new_dir = rename_info -> value ; /* old_dir = rename_info->key; */
2308
2335
otherinfo = strmap_get_entry (dir_rename_exclusions , new_dir );
2309
2336
if (otherinfo ) {
2310
2337
path_msg (opt , rename_info -> key , 1 ,
@@ -2315,7 +2342,8 @@ static char *check_for_directory_rename(struct merge_options *opt,
2315
2342
}
2316
2343
2317
2344
new_path = handle_path_level_conflicts (opt , path , side_index ,
2318
- rename_info , collisions );
2345
+ rename_info ,
2346
+ & collisions [side_index ]);
2319
2347
* clean_merge &= (new_path != NULL );
2320
2348
2321
2349
return new_path ;
@@ -3024,18 +3052,15 @@ static int detect_regular_renames(struct merge_options *opt,
3024
3052
static int collect_renames (struct merge_options * opt ,
3025
3053
struct diff_queue_struct * result ,
3026
3054
unsigned side_index ,
3055
+ struct strmap * collisions ,
3027
3056
struct strmap * dir_renames_for_side ,
3028
3057
struct strmap * rename_exclusions )
3029
3058
{
3030
3059
int i , clean = 1 ;
3031
- struct strmap collisions ;
3032
3060
struct diff_queue_struct * side_pairs ;
3033
- struct hashmap_iter iter ;
3034
- struct strmap_entry * entry ;
3035
3061
struct rename_info * renames = & opt -> priv -> renames ;
3036
3062
3037
3063
side_pairs = & renames -> pairs [side_index ];
3038
- compute_collisions (& collisions , dir_renames_for_side , side_pairs );
3039
3064
3040
3065
for (i = 0 ; i < side_pairs -> nr ; ++ i ) {
3041
3066
struct diff_filepair * p = side_pairs -> queue [i ];
@@ -3051,7 +3076,7 @@ static int collect_renames(struct merge_options *opt,
3051
3076
side_index ,
3052
3077
dir_renames_for_side ,
3053
3078
rename_exclusions ,
3054
- & collisions ,
3079
+ collisions ,
3055
3080
& clean );
3056
3081
3057
3082
possibly_cache_new_pair (renames , p , side_index , new_path );
@@ -3077,20 +3102,6 @@ static int collect_renames(struct merge_options *opt,
3077
3102
result -> queue [result -> nr ++ ] = p ;
3078
3103
}
3079
3104
3080
- /* Free each value in the collisions map */
3081
- strmap_for_each_entry (& collisions , & iter , entry ) {
3082
- struct collision_info * info = entry -> value ;
3083
- string_list_clear (& info -> source_files , 0 );
3084
- }
3085
- /*
3086
- * In compute_collisions(), we set collisions.strdup_strings to 0
3087
- * so that we wouldn't have to make another copy of the new_path
3088
- * allocated by apply_dir_rename(). But now that we've used them
3089
- * and have no other references to these strings, it is time to
3090
- * deallocate them.
3091
- */
3092
- free_strmap_strings (& collisions );
3093
- strmap_clear (& collisions , 1 );
3094
3105
return clean ;
3095
3106
}
3096
3107
@@ -3101,6 +3112,7 @@ static int detect_and_process_renames(struct merge_options *opt,
3101
3112
{
3102
3113
struct diff_queue_struct combined = { 0 };
3103
3114
struct rename_info * renames = & opt -> priv -> renames ;
3115
+ struct strmap collisions [3 ];
3104
3116
int need_dir_renames , s , i , clean = 1 ;
3105
3117
unsigned detection_run = 0 ;
3106
3118
@@ -3150,12 +3162,22 @@ static int detect_and_process_renames(struct merge_options *opt,
3150
3162
ALLOC_GROW (combined .queue ,
3151
3163
renames -> pairs [1 ].nr + renames -> pairs [2 ].nr ,
3152
3164
combined .alloc );
3165
+ for (i = MERGE_SIDE1 ; i <= MERGE_SIDE2 ; i ++ ) {
3166
+ int other_side = 3 - i ;
3167
+ compute_collisions (& collisions [i ],
3168
+ & renames -> dir_renames [other_side ],
3169
+ & renames -> pairs [i ]);
3170
+ }
3153
3171
clean &= collect_renames (opt , & combined , MERGE_SIDE1 ,
3172
+ collisions ,
3154
3173
& renames -> dir_renames [2 ],
3155
3174
& renames -> dir_renames [1 ]);
3156
3175
clean &= collect_renames (opt , & combined , MERGE_SIDE2 ,
3176
+ collisions ,
3157
3177
& renames -> dir_renames [1 ],
3158
3178
& renames -> dir_renames [2 ]);
3179
+ for (i = MERGE_SIDE1 ; i <= MERGE_SIDE2 ; i ++ )
3180
+ free_collisions (& collisions [i ]);
3159
3181
STABLE_QSORT (combined .queue , combined .nr , compare_pairs );
3160
3182
trace2_region_leave ("merge" , "directory renames" , opt -> repo );
3161
3183
0 commit comments