]> git.ipfire.org Git - thirdparty/git.git/commitdiff
merge-tree: add a --allow-unrelated-histories flag
authorElijah Newren <newren@gmail.com>
Sat, 18 Jun 2022 00:20:59 +0000 (00:20 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 22 Jun 2022 23:10:06 +0000 (16:10 -0700)
Folks may want to merge histories that have no common ancestry; provide
a flag with the same name as used by `git merge` to allow this.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-merge-tree.txt
builtin/merge-tree.c
t/t4301-merge-tree-write-tree.sh

index 75b57f8abab8d7f7e5c9aa81b65e5026b5d6f1e0..628324646d3a91671c3455407a64bd44fde1baf4 100644 (file)
@@ -59,6 +59,11 @@ OPTIONS
        default is to include these messages if there are merge
        conflicts, and to omit them otherwise.
 
+--allow-unrelated-histories::
+       merge-tree will by default error out if the two branches specified
+       share no common history.  This flag can be given to override that
+       check and make the merge proceed anyway.
+
 [[OUTPUT]]
 OUTPUT
 ------
index c159e317743bf31a58237629185f26c48db9a0cd..ae5782917b96c57917b60b7e192f74f18e77794c 100644 (file)
@@ -399,6 +399,7 @@ enum mode {
 
 struct merge_tree_options {
        int mode;
+       int allow_unrelated_histories;
        int show_messages;
        int name_only;
 };
@@ -434,7 +435,7 @@ static int real_merge(struct merge_tree_options *o,
         * merge_incore_recursive in merge-ort.h
         */
        merge_bases = get_merge_bases(parent1, parent2);
-       if (!merge_bases)
+       if (!merge_bases && !o->allow_unrelated_histories)
                die(_("refusing to merge unrelated histories"));
        merge_bases = reverse_commit_list(merge_bases);
 
@@ -500,6 +501,10 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)
                           &o.name_only,
                           N_("list filenames without modes/oids/stages"),
                           PARSE_OPT_NONEG),
+               OPT_BOOL_F(0, "allow-unrelated-histories",
+                          &o.allow_unrelated_histories,
+                          N_("allow merging unrelated histories"),
+                          PARSE_OPT_NONEG),
                OPT_END()
        };
 
index 88e75b18cc54c442c3006a6a0a8a2bc4038a5d23..f091259a55eba49fd632694b08495a4b8e8b0429 100755 (executable)
@@ -44,7 +44,13 @@ test_expect_success setup '
        git checkout side3 &&
        git mv numbers sequence &&
        test_tick &&
-       git commit -m rename-numbers
+       git commit -m rename-numbers &&
+
+       git switch --orphan unrelated &&
+       >something-else &&
+       git add something-else &&
+       test_tick &&
+       git commit -m first-commit
 '
 
 test_expect_success 'Clean merge' '
@@ -215,4 +221,20 @@ test_expect_success 'NUL terminated conflicted file "lines"' '
        test_cmp expect actual
 '
 
+test_expect_success 'error out by default for unrelated histories' '
+       test_expect_code 128 git merge-tree --write-tree side1 unrelated 2>error &&
+
+       grep "refusing to merge unrelated histories" error
+'
+
+test_expect_success 'can override merge of unrelated histories' '
+       git merge-tree --write-tree --allow-unrelated-histories side1 unrelated >tree &&
+       TREE=$(cat tree) &&
+
+       git rev-parse side1:numbers side1:greeting side1:whatever unrelated:something-else >expect &&
+       git rev-parse $TREE:numbers $TREE:greeting $TREE:whatever $TREE:something-else >actual &&
+
+       test_cmp expect actual
+'
+
 test_done