From: Johannes Schindelin <johannes.schindelin@xxxxxx> The 'edit' command can be used to cherry-pick a commit and then immediately drop out of the interactive rebase, with exit code 0, to let the user amend the commit, or test it, or look around. Sometimes this functionality would come in handy *without* cherry-picking a commit, e.g. to interrupt the interactive rebase even before cherry-picking a commit, or immediately after an 'exec' or a 'merge'. This commit introduces that functionality, as the spanking new 'break' command. Suggested-by: Stefan Beller <sbeller@xxxxxxxxxx> Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx> --- rebase-interactive.c | 1 + sequencer.c | 7 ++++++- t/lib-rebase.sh | 2 +- t/t3418-rebase-continue.sh | 9 +++++++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/rebase-interactive.c b/rebase-interactive.c index 0f4119cbae..78f3263fc1 100644 --- a/rebase-interactive.c +++ b/rebase-interactive.c @@ -14,6 +14,7 @@ void append_todo_help(unsigned edit_todo, unsigned keep_empty, "s, squash <commit> = use commit, but meld into previous commit\n" "f, fixup <commit> = like \"squash\", but discard this commit's log message\n" "x, exec <command> = run command (the rest of the line) using shell\n" +"b, break = stop here (continue rebase later with 'git rebase --continue')\n" "d, drop <commit> = remove commit\n" "l, label <label> = label current HEAD with a name\n" "t, reset <label> = reset HEAD to a label\n" diff --git a/sequencer.c b/sequencer.c index 8dd6db5a01..b209f8af46 100644 --- a/sequencer.c +++ b/sequencer.c @@ -1416,6 +1416,7 @@ enum todo_command { TODO_SQUASH, /* commands that do something else than handling a single commit */ TODO_EXEC, + TODO_BREAK, TODO_LABEL, TODO_RESET, TODO_MERGE, @@ -1437,6 +1438,7 @@ static struct { { 'f', "fixup" }, { 's', "squash" }, { 'x', "exec" }, + { 'b', "break" }, { 'l', "label" }, { 't', "reset" }, { 'm', "merge" }, @@ -1964,7 +1966,7 @@ static int parse_insn_line(struct todo_item *item, const char *bol, char *eol) padding = strspn(bol, " \t"); bol += padding; - if (item->command == TODO_NOOP) { + if (item->command == TODO_NOOP || item->command == TODO_BREAK) { if (bol != eol) return error(_("%s does not accept arguments: '%s'"), command_to_string(item->command), bol); @@ -3293,6 +3295,9 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts) unlink(rebase_path_stopped_sha()); unlink(rebase_path_amend()); delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF); + + if (item->command == TODO_BREAK) + break; } if (item->command <= TODO_SQUASH) { if (is_rebase_i(opts)) diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index 25a77ee5cb..584604ee63 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -49,7 +49,7 @@ set_fake_editor () { case $line in squash|fixup|edit|reword|drop) action="$line";; - exec*) + exec*|break) echo "$line" | sed 's/_/ /g' >> "$1";; "#") echo '# comment' >> "$1";; diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh index c145dbac38..185a491089 100755 --- a/t/t3418-rebase-continue.sh +++ b/t/t3418-rebase-continue.sh @@ -239,5 +239,14 @@ test_rerere_autoupdate -m GIT_SEQUENCE_EDITOR=: && export GIT_SEQUENCE_EDITOR test_rerere_autoupdate -i test_rerere_autoupdate --preserve-merges +unset GIT_SEQUENCE_EDITOR + +test_expect_success 'the todo command "break" works' ' + rm -f execed && + FAKE_LINES="break exec_>execed" git rebase -i HEAD && + test_path_is_missing execed && + git rebase --continue && + test_path_is_file execed +' test_done -- gitgitgadget