merge-ort: populate caches of rename detection results
Fill in cache_pairs, cached_target_names, and cached_irrelevant based on rename detection results. Future commits will make use of these values. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Elijah Newren committed
May 20, 2021 at 06:09 UTC
2734f2e3243ce19af1d9c9c92dffae13af7b0fe5
1 file changed
+72
-1
merge-ort.c
+72
-1
@@ -2344,6 +2344,67 @@ static void resolve_diffpair_statuses(struct diff_queue_struct *q)
2344
}
2345
}
2346
2347
+static void cache_new_pair(struct rename_info *renames,
2348
+ int side,
2349
+ char *old_path,
2350
+ char *new_path,
2351
+ int free_old_value)
2352
+{
2353
+ char *old_value;
2354
+ new_path = xstrdup(new_path);
2355
+ old_value = strmap_put(&renames->cached_pairs[side],
2356
+ old_path, new_path);
2357
+ strset_add(&renames->cached_target_names[side], new_path);
2358
+ if (free_old_value)
2359
+ free(old_value);
2360
+ else
2361
+ assert(!old_value);
2362
+}
2363
+
2364
+static void possibly_cache_new_pair(struct rename_info *renames,
2365
+ struct diff_filepair *p,
2366
+ unsigned side,
2367
+ char *new_path)
2368
+{
2369
+ int dir_renamed_side = 0;
2370
+
2371
+ if (new_path) {
2372
+ /*
2373
+ * Directory renames happen on the other side of history from
2374
+ * the side that adds new files to the old directory.
2375
+ */
2376
+ dir_renamed_side = 3 - side;
2377
+ } else {
2378
+ int val = strintmap_get(&renames->relevant_sources[side],
2379
+ p->one->path);
2380
+ if (val == RELEVANT_NO_MORE) {
2381
+ assert(p->status == 'D');
2382
+ strset_add(&renames->cached_irrelevant[side],
2383
+ p->one->path);
2384
+ }
2385
+ if (val <= 0)
2386
+ return;
2387
+ }
2388
+
2389
+ if (p->status == 'D') {
2390
+ /*
2391
+ * If we already had this delete, we'll just set it's value
2392
+ * to NULL again, so no harm.
2393
+ */
2394
+ strmap_put(&renames->cached_pairs[side], p->one->path, NULL);
2395
+ } else if (p->status == 'R') {
2396
+ if (!new_path)
2397
+ new_path = p->two->path;
2398
+ else
2399
+ cache_new_pair(renames, dir_renamed_side,
2400
+ p->two->path, new_path, 0);
2401
+ cache_new_pair(renames, side, p->one->path, new_path, 1);
2402
+ } else if (p->status == 'A' && new_path) {
2403
+ cache_new_pair(renames, dir_renamed_side,
2404
+ p->two->path, new_path, 0);
2405
+ }
2406
+}
2407
+
2408
static int compare_pairs(const void *a_, const void *b_)
2409
{
2410
const struct diff_filepair *a = *((const struct diff_filepair **)a_);
@@ -2426,6 +2487,7 @@ static int collect_renames(struct merge_options *opt,
2487
char *new_path; /* non-NULL only with directory renames */
2488
2489
if (p->status != 'A' && p->status != 'R') {
2490
+ possibly_cache_new_pair(renames, p, side_index, NULL);
2491
diff_free_filepair(p);
2492
continue;
2493
}
@@ -2437,6 +2499,7 @@ static int collect_renames(struct merge_options *opt,
2499
&collisions,
2500
&clean);
2501
2502
+ possibly_cache_new_pair(renames, p, side_index, new_path);
2503
if (p->status != 'R' && !new_path) {
2504
diff_free_filepair(p);
2505
continue;
@@ -3720,8 +3783,16 @@ static void merge_start(struct merge_options *opt, struct merge_result *result)
3783
NULL, 1);
3784
strmap_init_with_options(&renames->dir_renames[i],
3785
NULL, 0);
3786
+ /*
3787
+ * relevant_sources uses -1 for the default, because we need
3788
+ * to be able to distinguish not-in-strintmap from valid
3789
+ * relevant_source values from enum file_rename_relevance.
3790
+ * In particular, possibly_cache_new_pair() expects a negative
3791
+ * value for not-found entries.
3792
+ */
3793
strintmap_init_with_options(&renames->relevant_sources[i],
3724
- 0, NULL, 0);
3794
+ -1 /* explicitly invalid */,
3795
+ NULL, 0);
3796
strmap_init_with_options(&renames->cached_pairs[i],
3797
NULL, 1);
3798
strset_init_with_options(&renames->cached_irrelevant[i],