diff options
-rw-r--r-- | Documentation/git-rebase.txt | 3 | ||||
-rw-r--r-- | rebase-interactive.c | 1 | ||||
-rw-r--r-- | sequencer.c | 24 | ||||
-rw-r--r-- | t/lib-rebase.sh | 2 | ||||
-rwxr-xr-x | t/t3418-rebase-continue.sh | 9 |
5 files changed, 37 insertions, 2 deletions
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index d9771bd25b..6b71694b0d 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -561,6 +561,9 @@ By replacing the command "pick" with the command "edit", you can tell the files and/or the commit message, amend the commit, and continue rebasing. +To interrupt the rebase (just like an "edit" command would do, but without +cherry-picking any commit first), use the "break" command. + If you just want to edit the commit message for a commit, replace the command "pick" with the command "reword". 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..ee3961ec63 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); @@ -3247,6 +3249,23 @@ static int checkout_onto(struct replay_opts *opts, return update_ref(NULL, "ORIG_HEAD", &oid, NULL, 0, UPDATE_REFS_MSG_ON_ERR); } +static int stopped_at_head(void) +{ + struct object_id head; + struct commit *commit; + struct commit_message message; + + if (get_oid("HEAD", &head) || !(commit = lookup_commit(&head)) || + parse_commit(commit) || get_message(commit, &message)) + fprintf(stderr, _("Stopped at HEAD\n")); + else { + fprintf(stderr, _("Stopped at %s\n"), message.label); + free_message(commit, &message); + } + return 0; + +} + static const char rescheduled_advice[] = N_("Could not execute the todo command\n" "\n" @@ -3293,6 +3312,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) + return stopped_at_head(); } 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 |