]> git.ipfire.org Git - thirdparty/git.git/commitdiff
read-tree: make three-way merge sparse-aware
authorVictoria Dye <vdye@github.com>
Tue, 1 Mar 2022 20:24:31 +0000 (20:24 +0000)
committerJunio C Hamano <gitster@pobox.com>
Tue, 1 Mar 2022 20:36:01 +0000 (12:36 -0800)
Enable use of 'merged_sparse_dir' in 'threeway_merge'. As with two-way
merge, the contents of each conflicted sparse directory are merged without
referencing the index, avoiding sparse index expansion.

As with two-way merge, the 't/t1092-sparse-checkout-compatibility.sh' test
'read-tree --merge with edit/edit conflicts in sparse directories' confirms
that three-way merges with edit/edit changes (both with and without
conflicts) inside a sparse directory result in the correct index state or
error message. To ensure the index is not unnecessarily expanded, add
three-way merge cases to 'sparse index is not expanded: read-tree'.

Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/read-tree.c
t/t1092-sparse-checkout-compatibility.sh
unpack-trees.c

index 9227f07ab1589272104366188c5dad41b4442c2f..9f1f33e95466a4b2ff4f99a3b5e95878e40c6d38 100644 (file)
@@ -234,11 +234,6 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
                        break;
                case 3:
                default:
-                       /*
-                        * TODO: update threeway_merge to handle edit/edit conflicts in
-                        * sparse directories.
-                        */
-                       ensure_full_index(&the_index);
                        opts.fn = threeway_merge;
                        break;
                }
index 61dc2ea777c70a32b1844af3e490eded3880a928..8be8e3c06a6755a121cde49ea8a2b268311e1b17 100755 (executable)
@@ -1413,7 +1413,9 @@ test_expect_success 'sparse index is not expanded: read-tree' '
        init_repos &&
 
        ensure_not_expanded checkout -b test-branch update-folder1 &&
-       for MERGE_TREES in "base update-folder2" \
+       for MERGE_TREES in "base HEAD update-folder2" \
+                          "base HEAD rename-base" \
+                          "base update-folder2" \
                           "base rename-base" \
                           "update-folder2"
        do
index 0c2a678cd6d7d4869756ac719ca896acf4533e75..b876caca0d131052a9567f081cf71e1fd56beb7e 100644 (file)
@@ -2643,16 +2643,24 @@ int threeway_merge(const struct cache_entry * const *stages,
         */
        /* #14, #14ALT, #2ALT */
        if (remote && !df_conflict_head && head_match && !remote_match) {
-               if (index && !same(index, remote) && !same(index, head))
-                       return reject_merge(index, o);
+               if (index && !same(index, remote) && !same(index, head)) {
+                       if (S_ISSPARSEDIR(index->ce_mode))
+                               return merged_sparse_dir(stages, 4, o);
+                       else
+                               return reject_merge(index, o);
+               }
                return merged_entry(remote, index, o);
        }
        /*
         * If we have an entry in the index cache, then we want to
         * make sure that it matches head.
         */
-       if (index && !same(index, head))
-               return reject_merge(index, o);
+       if (index && !same(index, head)) {
+               if (S_ISSPARSEDIR(index->ce_mode))
+                       return merged_sparse_dir(stages, 4, o);
+               else
+                       return reject_merge(index, o);
+       }
 
        if (head) {
                /* #5ALT, #15 */
@@ -2714,11 +2722,21 @@ int threeway_merge(const struct cache_entry * const *stages,
 
        }
 
-       /* Below are "no merge" cases, which require that the index be
-        * up-to-date to avoid the files getting overwritten with
-        * conflict resolution files.
-        */
+       /* Handle "no merge" cases (see t/t1000-read-tree-m-3way.sh) */
        if (index) {
+               /*
+                * If we've reached the "no merge" cases and we're merging
+                * a sparse directory, we may have an "edit/edit" conflict that
+                * can be resolved by individually merging directory contents.
+                */
+               if (S_ISSPARSEDIR(index->ce_mode))
+                       return merged_sparse_dir(stages, 4, o);
+
+               /*
+                * If we're not merging a sparse directory, ensure the index is
+                * up-to-date to avoid files getting overwritten with conflict
+                * resolution files
+                */
                if (verify_uptodate(index, o))
                        return -1;
        }