]> git.ipfire.org Git - thirdparty/git.git/commitdiff
rebase: write script before initializing state
authorØystein Walle <oystwa@gmail.com>
Mon, 9 Jun 2025 22:10:55 +0000 (00:10 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 9 Jun 2025 22:56:57 +0000 (15:56 -0700)
If rebase.instructionFormat is invalid the repository is left in a
strange state when the interactive rebase fails. `git status` outputs
boths the same as it would in the normal case *and* something related to
interactive rebase:

    $ git -c rebase.instructionFormat=blah rebase -i
    fatal: invalid --pretty format: blah
    $ git status
    On branch master
    Your branch is ahead of 'upstream/master' by 1 commit.
      (use "git push" to publish your local commits)

    git-rebase-todo is missing.
    No commands done.
    No commands remaining.
    You are currently editing a commit while rebasing branch 'master' on '8db3019401'.
      (use "git commit --amend" to amend the current commit)
      (use "git rebase --continue" once you are satisfied with your changes)

By attempting to write the rebase script before initializing the state
this potential scenario is avoided.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/rebase.c
t/t3415-rebase-autosquash.sh

index d4715ed35d77edf9065dec9a46ed433a30d7fd68..06da8e4f367098bb1e4d7c1937784d567b4200ed 100644 (file)
@@ -292,15 +292,6 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
                                &revisions, &shortrevisions))
                goto cleanup;
 
-       if (init_basic_state(&replay,
-                            opts->head_name ? opts->head_name : "detached HEAD",
-                            opts->onto, &opts->orig_head->object.oid))
-               goto cleanup;
-
-       if (!opts->upstream && opts->squash_onto)
-               write_file(path_squash_onto(), "%s\n",
-                          oid_to_hex(opts->squash_onto));
-
        strvec_pushl(&make_script_args, "", revisions, NULL);
        if (opts->restrict_revision)
                strvec_pushf(&make_script_args, "^%s",
@@ -309,21 +300,30 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
        ret = sequencer_make_script(the_repository, &todo_list.buf,
                                    make_script_args.nr, make_script_args.v,
                                    flags);
-
-       if (ret)
+       if (ret) {
                error(_("could not generate todo list"));
-       else {
-               discard_index(the_repository->index);
-               if (todo_list_parse_insn_buffer(the_repository, &replay,
-                                               todo_list.buf.buf, &todo_list))
-                       BUG("unusable todo list");
-
-               ret = complete_action(the_repository, &replay, flags,
-                       shortrevisions, opts->onto_name, opts->onto,
-                       &opts->orig_head->object.oid, &opts->exec,
-                       opts->autosquash, opts->update_refs, &todo_list);
+               goto cleanup;
        }
 
+       if (init_basic_state(&replay,
+                            opts->head_name ? opts->head_name : "detached HEAD",
+                            opts->onto, &opts->orig_head->object.oid))
+               goto cleanup;
+
+       if (!opts->upstream && opts->squash_onto)
+               write_file(path_squash_onto(), "%s\n",
+                          oid_to_hex(opts->squash_onto));
+
+       discard_index(the_repository->index);
+       if (todo_list_parse_insn_buffer(the_repository, &replay,
+                                       todo_list.buf.buf, &todo_list))
+               BUG("unusable todo list");
+
+       ret = complete_action(the_repository, &replay, flags,
+               shortrevisions, opts->onto_name, opts->onto,
+               &opts->orig_head->object.oid, &opts->exec,
+               opts->autosquash, opts->update_refs, &todo_list);
+
 cleanup:
        replay_opts_release(&replay);
        free(revisions);
index fcc40d6fe1fd5b2a9c4f2a5e4ede15e73c247790..d4c624b841effc0988f178e45c70f9b7221e712f 100755 (executable)
@@ -394,6 +394,16 @@ test_expect_success 'autosquash with empty custom instructionFormat' '
        )
 '
 
+test_expect_success 'autosquash with invalid custom instructionFormat' '
+       git reset --hard base &&
+       test_commit invalid-instructionFormat-test &&
+       (
+               test_must_fail git -c rebase.instructionFormat=blah \
+                       rebase --autosquash  --force-rebase -i HEAD^ &&
+               test_path_is_missing .git/rebase-merge
+       )
+'
+
 set_backup_editor () {
        write_script backup-editor.sh <<-\EOF
        cp "$1" .git/backup-"$(basename "$1")"