rebase: write script before initializing state

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>
This commit is contained in:
Øystein Walle
2025-06-10 00:10:55 +02:00
committed by Junio C Hamano
parent d50a5e8939
commit ade14bffd7
2 changed files with 31 additions and 21 deletions

View File

@@ -292,6 +292,19 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
&revisions, &shortrevisions))
goto cleanup;
strvec_pushl(&make_script_args, "", revisions, NULL);
if (opts->restrict_revision)
strvec_pushf(&make_script_args, "^%s",
oid_to_hex(&opts->restrict_revision->object.oid));
ret = sequencer_make_script(the_repository, &todo_list.buf,
make_script_args.nr, make_script_args.v,
flags);
if (ret) {
error(_("could not generate todo list"));
goto cleanup;
}
if (init_basic_state(&replay,
opts->head_name ? opts->head_name : "detached HEAD",
opts->onto, &opts->orig_head->object.oid))
@@ -301,28 +314,15 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
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",
oid_to_hex(&opts->restrict_revision->object.oid));
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 = sequencer_make_script(the_repository, &todo_list.buf,
make_script_args.nr, make_script_args.v,
flags);
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);
}
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);