]> git.ipfire.org Git - thirdparty/git.git/commitdiff
pull: fix handling of multiple heads
authorElijah Newren <newren@gmail.com>
Thu, 22 Jul 2021 05:04:50 +0000 (05:04 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 22 Jul 2021 18:54:30 +0000 (11:54 -0700)
With multiple heads, we should not allow rebasing or fast-forwarding.
Make sure any fast-forward request calls out specifically the fact that
multiple branches are in play.  Also, since we cannot fast-forward to
multiple branches, fix our computation of can_ff.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/pull.c
t/t7601-merge-pull-config.sh

index 2f1d1f4037d0760d576e51aaf86078ad085dbda2..b311ea6b9dfda0479b36c96408d21ff4cdda7ae9 100644 (file)
@@ -913,12 +913,18 @@ static int run_rebase(const struct object_id *newbase,
        return ret;
 }
 
-static int get_can_ff(struct object_id *orig_head, struct object_id *orig_merge_head)
+static int get_can_ff(struct object_id *orig_head,
+                     struct oid_array *merge_heads)
 {
        int ret;
        struct commit_list *list = NULL;
        struct commit *merge_head, *head;
+       struct object_id *orig_merge_head;
 
+       if (merge_heads->nr > 1)
+               return 0;
+
+       orig_merge_head = &merge_heads->oid[0];
        head = lookup_commit_reference(the_repository, orig_head);
        commit_list_insert(head, &list);
        merge_head = lookup_commit_reference(the_repository, orig_merge_head);
@@ -1057,10 +1063,14 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
                        die(_("Cannot merge multiple branches into empty head."));
                return pull_into_void(merge_heads.oid, &curr_head);
        }
-       if (opt_rebase && merge_heads.nr > 1)
-               die(_("Cannot rebase onto multiple branches."));
+       if (merge_heads.nr > 1) {
+               if (opt_rebase)
+                       die(_("Cannot rebase onto multiple branches."));
+               if (opt_ff && !strcmp(opt_ff, "--ff-only"))
+                       die(_("Cannot fast-forward to multiple branches."));
+       }
 
-       can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);
+       can_ff = get_can_ff(&orig_head, &merge_heads);
 
        /* ff-only takes precedence over rebase */
        if (opt_ff && !strcmp(opt_ff, "--ff-only")) {
index 742ed3981c7644fa95db890d6e88d40f2e06c1ff..1f652f433ee276b1420324f6609ae51c5b02863c 100755 (executable)
@@ -331,7 +331,7 @@ test_expect_success 'Multiple heads warns about inability to fast forward' '
        test_i18ngrep "You have divergent branches" err
 '
 
-test_expect_failure 'Multiple can never be fast forwarded' '
+test_expect_success 'Multiple can never be fast forwarded' '
        git reset --hard c0 &&
        test_must_fail git -c pull.ff=only pull . c1 c2 c3 2>err &&
        test_i18ngrep ! "You have divergent branches" err &&