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],