]> git.ipfire.org Git - thirdparty/git.git/commitdiff
builtin/history: check for merges before asking for user input
authorPatrick Steinhardt <ps@pks.im>
Mon, 16 Feb 2026 06:45:45 +0000 (07:45 +0100)
committerJunio C Hamano <gitster@pobox.com>
Tue, 17 Feb 2026 16:37:51 +0000 (08:37 -0800)
The replay infrastructure is not yet capable of replaying merge commits.
Unfortunately, we only notice that we're about to replay merges after we
have already asked the user for input, so any commit message that the
user may have written will be discarded in that case.

Fix this by checking whether the revwalk contains merge commits before
we ask for user input.

Adapt one of the tests that is expected to fail because of this check
to use false(1) as editor. If the editor had been executed by Git, it
would fail with the error message "Aborting commit as launching the
editor failed."

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/history.c
t/t3451-history-reword.sh

index 1de51372ea0df95bf9541222af3f4ba7fd3a3823..ff90e93d6e9b9fb6020785a3f33fe67e513223bb 100644 (file)
@@ -177,6 +177,41 @@ static int parse_ref_action(const struct option *opt, const char *value, int uns
        return 0;
 }
 
+static int revwalk_contains_merges(struct repository *repo,
+                                  const struct strvec *revwalk_args)
+{
+       struct strvec args = STRVEC_INIT;
+       struct rev_info revs;
+       int ret;
+
+       strvec_pushv(&args, revwalk_args->v);
+       strvec_push(&args, "--min-parents=2");
+
+       repo_init_revisions(repo, &revs, NULL);
+
+       setup_revisions_from_strvec(&args, &revs, NULL);
+       if (args.nr != 1)
+               BUG("revisions were set up with invalid argument");
+
+       if (prepare_revision_walk(&revs) < 0) {
+               ret = error(_("error preparing revisions"));
+               goto out;
+       }
+
+       if (get_revision(&revs)) {
+               ret = error(_("replaying merge commits is not supported yet!"));
+               goto out;
+       }
+
+       reset_revision_walk();
+       ret = 0;
+
+out:
+       release_revisions(&revs);
+       strvec_clear(&args);
+       return ret;
+}
+
 static int setup_revwalk(struct repository *repo,
                         enum ref_action action,
                         struct commit *original,
@@ -236,6 +271,10 @@ static int setup_revwalk(struct repository *repo,
                strvec_push(&args, "HEAD");
        }
 
+       ret = revwalk_contains_merges(repo, &args);
+       if (ret < 0)
+               goto out;
+
        setup_revisions_from_strvec(&args, revs, NULL);
        if (args.nr != 1)
                BUG("revisions were set up with invalid argument");
index 6775ed62f903d0caa72675736b47a897d2698bf8..12a9a7d051078ce8c76ce069a1da323e38d1fa51 100755 (executable)
@@ -203,7 +203,7 @@ test_expect_success 'can reword a merge commit' '
 
                # It is not possible to replay merge commits embedded in the
                # history (yet).
-               test_must_fail git history reword HEAD~ 2>err &&
+               test_must_fail git -c core.editor=false history reword HEAD~ 2>err &&
                test_grep "replaying merge commits is not supported yet" err &&
 
                # But it is possible to reword a merge commit directly.