]> git.ipfire.org Git - thirdparty/git.git/blobdiff - merge-ort.c
hash-ll.h: split out of hash.h to remove dependency on repository.h
[thirdparty/git.git] / merge-ort.c
index e5f41cce48143db0526676ebc4949a4431cb8d9f..65837db77f0e9aae20ca05c6d16ff6ccb079bf44 100644 (file)
 #include "diff.h"
 #include "diffcore.h"
 #include "dir.h"
+#include "environment.h"
+#include "gettext.h"
+#include "hex.h"
 #include "entry.h"
 #include "ll-merge.h"
+#include "match-trees.h"
+#include "mem-pool.h"
+#include "object-name.h"
 #include "object-store.h"
+#include "oid-array.h"
 #include "promisor-remote.h"
 #include "revision.h"
 #include "strmap.h"
 #include "submodule-config.h"
 #include "submodule.h"
+#include "trace2.h"
 #include "tree.h"
 #include "unpack-trees.h"
 #include "xdiff-interface.h"
@@ -397,7 +405,7 @@ struct conflicted_submodule_item {
        int flag;
 };
 
-static void conflicted_submodule_item_free(void *util, const char *str)
+static void conflicted_submodule_item_free(void *util, const char *str UNUSED)
 {
        struct conflicted_submodule_item *item = util;
 
@@ -2619,8 +2627,40 @@ static void apply_directory_rename_modifications(struct merge_options *opt,
        }
 
        assert(ci->filemask == 2 || ci->filemask == 4);
-       assert(ci->dirmask == 0);
-       strmap_remove(&opt->priv->paths, old_path, 0);
+       assert(ci->dirmask == 0 || ci->dirmask == 1);
+       if (ci->dirmask == 0)
+               strmap_remove(&opt->priv->paths, old_path, 0);
+       else {
+               /*
+                * This file exists on one side, but we still had a directory
+                * at the old location that we can't remove until after
+                * processing all paths below it.  So, make a copy of ci in
+                * new_ci and only put the file information into it.
+                */
+               new_ci = mem_pool_calloc(&opt->priv->pool, 1, sizeof(*new_ci));
+               memcpy(new_ci, ci, sizeof(*ci));
+               assert(!new_ci->match_mask);
+               new_ci->dirmask = 0;
+               new_ci->stages[1].mode = 0;
+               oidcpy(&new_ci->stages[1].oid, null_oid());
+
+               /*
+                * Now that we have the file information in new_ci, make sure
+                * ci only has the directory information.
+                */
+               ci->filemask = 0;
+               ci->merged.clean = 1;
+               for (i = MERGE_BASE; i <= MERGE_SIDE2; i++) {
+                       if (ci->dirmask & (1 << i))
+                               continue;
+                       /* zero out any entries related to files */
+                       ci->stages[i].mode = 0;
+                       oidcpy(&ci->stages[i].oid, null_oid());
+               }
+
+               // Now we want to focus on new_ci, so reassign ci to it
+               ci = new_ci;
+       }
 
        branch_with_new_path   = (ci->filemask == 2) ? opt->branch1 : opt->branch2;
        branch_with_dir_rename = (ci->filemask == 2) ? opt->branch2 : opt->branch1;
@@ -3473,7 +3513,7 @@ static int read_oid_strbuf(struct merge_options *opt,
        void *buf;
        enum object_type type;
        unsigned long size;
-       buf = read_object_file(oid, &type, &size);
+       buf = repo_read_object_file(the_repository, oid, &type, &size);
        if (!buf)
                return err(opt, _("cannot read object %s"), oid_to_hex(oid));
        if (type != OBJ_BLOB) {
@@ -4184,7 +4224,7 @@ static void prefetch_for_content_merges(struct merge_options *opt,
        struct string_list_item *e;
        struct oid_array to_fetch = OID_ARRAY_INIT;
 
-       if (opt->repo != the_repository || !has_promisor_remote())
+       if (opt->repo != the_repository || !repo_has_promisor_remote(the_repository))
                return;
 
        for (e = &plist->items[plist->nr-1]; e >= plist->items; --e) {
@@ -4985,7 +5025,7 @@ static void merge_ort_internal(struct merge_options *opt,
        struct strbuf merge_base_abbrev = STRBUF_INIT;
 
        if (!merge_bases) {
-               merge_bases = get_merge_bases(h1, h2);
+               merge_bases = repo_get_merge_bases(the_repository, h1, h2);
                /* See merge-ort.h:merge_incore_recursive() declaration NOTE */
                merge_bases = reverse_commit_list(merge_bases);
        }