summaryrefslogtreecommitdiff
path: root/merge-ort.c
diff options
context:
space:
mode:
authorElijah Newren <newren@gmail.com>2021-07-16 05:22:34 (GMT)
committerJunio C Hamano <gitster@pobox.com>2021-07-20 21:47:39 (GMT)
commite0ef578eae4aea91920ef394a0d38170b39777d1 (patch)
tree00499f7b08f8ecf28b2740da66e3180b44738224 /merge-ort.c
parentd478f5675923d02d2676bf2e47f0ccdd4dba0da8 (diff)
downloadgit-e0ef578eae4aea91920ef394a0d38170b39777d1.zip
git-e0ef578eae4aea91920ef394a0d38170b39777d1.tar.gz
git-e0ef578eae4aea91920ef394a0d38170b39777d1.tar.bz2
merge-ort: add a handle_deferred_entries() helper function
In order to allow trivial directory resolution, we first need to be able to gather more information to determine if the optimization is safe. To enable that, we need a way of deferring the recursion into the directory until a later time. Naturally, deferring the entry into a subtree means that we need some function that will later recurse into the subdirectory exactly the same way that collect_merge_info_callback() would have done. Add a helper function that does this. For now this function is not used but a subsequent commit will change that. Future commits will also make the function sometimes resolve directories instead of traversing inside. 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.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/merge-ort.c b/merge-ort.c
index 15ce7f8..6f81795 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -1202,6 +1202,70 @@ static int collect_merge_info_callback(int n,
return mask;
}
+MAYBE_UNUSED
+static int handle_deferred_entries(struct merge_options *opt,
+ struct traverse_info *info)
+{
+ struct rename_info *renames = &opt->priv->renames;
+ struct hashmap_iter iter;
+ struct strmap_entry *entry;
+ int side, ret = 0;
+
+ for (side = MERGE_SIDE1; side <= MERGE_SIDE2; side++) {
+ renames->deferred[side].trivial_merges_okay = 0;
+ strintmap_for_each_entry(&renames->deferred[side].possible_trivial_merges,
+ &iter, entry) {
+ const char *path = entry->key;
+ unsigned dir_rename_mask = (intptr_t)entry->value;
+ struct conflict_info *ci;
+ unsigned dirmask;
+ struct tree_desc t[3];
+ void *buf[3] = {NULL,};
+ int i;
+
+ ci = strmap_get(&opt->priv->paths, path);
+ VERIFY_CI(ci);
+ dirmask = ci->dirmask;
+
+ info->name = path;
+ info->namelen = strlen(path);
+ info->pathlen = info->namelen + 1;
+
+ for (i = 0; i < 3; i++, dirmask >>= 1) {
+ if (i == 1 && ci->match_mask == 3)
+ t[1] = t[0];
+ else if (i == 2 && ci->match_mask == 5)
+ t[2] = t[0];
+ else if (i == 2 && ci->match_mask == 6)
+ t[2] = t[1];
+ else {
+ const struct object_id *oid = NULL;
+ if (dirmask & 1)
+ oid = &ci->stages[i].oid;
+ buf[i] = fill_tree_descriptor(opt->repo,
+ t+i, oid);
+ }
+ }
+
+ ci->match_mask &= ci->filemask;
+ opt->priv->current_dir_name = path;
+ renames->dir_rename_mask = dir_rename_mask;
+ if (renames->dir_rename_mask == 0 ||
+ renames->dir_rename_mask == 0x07)
+ ret = traverse_trees(NULL, 3, t, info);
+ else
+ ret = traverse_trees_wrapper(NULL, 3, t, info);
+
+ for (i = MERGE_BASE; i <= MERGE_SIDE2; i++)
+ free(buf[i]);
+
+ if (ret < 0)
+ return ret;
+ }
+ }
+ return ret;
+}
+
static int collect_merge_info(struct merge_options *opt,
struct tree *merge_base,
struct tree *side1,