summaryrefslogtreecommitdiff
path: root/merge-ort.c
diff options
context:
space:
mode:
authorElijah Newren <newren@gmail.com>2021-05-20 06:09:35 (GMT)
committerJunio C Hamano <gitster@pobox.com>2021-05-20 06:40:39 (GMT)
commit2734f2e3243ce19af1d9c9c92dffae13af7b0fe5 (patch)
tree4d9d2495e1033f7b70ab2b81fb45a44a6cc450ea /merge-ort.c
parentd29bd6d73da5c40935713731919b1950692aff15 (diff)
downloadgit-2734f2e3243ce19af1d9c9c92dffae13af7b0fe5.zip
git-2734f2e3243ce19af1d9c9c92dffae13af7b0fe5.tar.gz
git-2734f2e3243ce19af1d9c9c92dffae13af7b0fe5.tar.bz2
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>
Diffstat (limited to 'merge-ort.c')
-rw-r--r--merge-ort.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/merge-ort.c b/merge-ort.c
index 6a06c6e..d515f5c 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -2344,6 +2344,67 @@ static void resolve_diffpair_statuses(struct diff_queue_struct *q)
}
}
+static void cache_new_pair(struct rename_info *renames,
+ int side,
+ char *old_path,
+ char *new_path,
+ int free_old_value)
+{
+ char *old_value;
+ new_path = xstrdup(new_path);
+ old_value = strmap_put(&renames->cached_pairs[side],
+ old_path, new_path);
+ strset_add(&renames->cached_target_names[side], new_path);
+ if (free_old_value)
+ free(old_value);
+ else
+ assert(!old_value);
+}
+
+static void possibly_cache_new_pair(struct rename_info *renames,
+ struct diff_filepair *p,
+ unsigned side,
+ char *new_path)
+{
+ int dir_renamed_side = 0;
+
+ if (new_path) {
+ /*
+ * Directory renames happen on the other side of history from
+ * the side that adds new files to the old directory.
+ */
+ dir_renamed_side = 3 - side;
+ } else {
+ int val = strintmap_get(&renames->relevant_sources[side],
+ p->one->path);
+ if (val == RELEVANT_NO_MORE) {
+ assert(p->status == 'D');
+ strset_add(&renames->cached_irrelevant[side],
+ p->one->path);
+ }
+ if (val <= 0)
+ return;
+ }
+
+ if (p->status == 'D') {
+ /*
+ * If we already had this delete, we'll just set it's value
+ * to NULL again, so no harm.
+ */
+ strmap_put(&renames->cached_pairs[side], p->one->path, NULL);
+ } else if (p->status == 'R') {
+ if (!new_path)
+ new_path = p->two->path;
+ else
+ cache_new_pair(renames, dir_renamed_side,
+ p->two->path, new_path, 0);
+ cache_new_pair(renames, side, p->one->path, new_path, 1);
+ } else if (p->status == 'A' && new_path) {
+ cache_new_pair(renames, dir_renamed_side,
+ p->two->path, new_path, 0);
+ }
+}
+
static int compare_pairs(const void *a_, const void *b_)
{
const struct diff_filepair *a = *((const struct diff_filepair **)a_);
@@ -2426,6 +2487,7 @@ static int collect_renames(struct merge_options *opt,
char *new_path; /* non-NULL only with directory renames */
if (p->status != 'A' && p->status != 'R') {
+ possibly_cache_new_pair(renames, p, side_index, NULL);
diff_free_filepair(p);
continue;
}
@@ -2437,6 +2499,7 @@ static int collect_renames(struct merge_options *opt,
&collisions,
&clean);
+ possibly_cache_new_pair(renames, p, side_index, new_path);
if (p->status != 'R' && !new_path) {
diff_free_filepair(p);
continue;
@@ -3720,8 +3783,16 @@ static void merge_start(struct merge_options *opt, struct merge_result *result)
NULL, 1);
strmap_init_with_options(&renames->dir_renames[i],
NULL, 0);
+ /*
+ * relevant_sources uses -1 for the default, because we need
+ * to be able to distinguish not-in-strintmap from valid
+ * relevant_source values from enum file_rename_relevance.
+ * In particular, possibly_cache_new_pair() expects a negative
+ * value for not-found entries.
+ */
strintmap_init_with_options(&renames->relevant_sources[i],
- 0, NULL, 0);
+ -1 /* explicitly invalid */,
+ NULL, 0);
strmap_init_with_options(&renames->cached_pairs[i],
NULL, 1);
strset_init_with_options(&renames->cached_irrelevant[i],