]> git.ipfire.org Git - thirdparty/git.git/commitdiff
merge-ort: add a handle_deferred_entries() helper function
authorElijah Newren <newren@gmail.com>
Fri, 16 Jul 2021 05:22:34 +0000 (05:22 +0000)
committerJunio C Hamano <gitster@pobox.com>
Tue, 20 Jul 2021 21:47:39 +0000 (14:47 -0700)
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>
merge-ort.c

index 15ce7f8c52be359de8fd806eeb5ebfebd8b1ce7a..6f817958460078afad4626413d1cc3e141ebbab7 100644 (file)
@@ -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,