If a sequencing gets interrupted (by a conflict or an empty commit or whatever), the user can now opt to just skip it passing the `--skip` command line option, which acts like a `--continue`, except that the current commit gets skipped. Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@xxxxxxxxx> --- Documentation/sequencer.txt | 10 +++++++++- builtin/revert.c | 7 +++++-- sequencer.c | 32 ++++++++++++++++++++++++++++---- sequencer.h | 2 +- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/Documentation/sequencer.txt b/Documentation/sequencer.txt index 5747f442f2..095d6cd732 100644 --- a/Documentation/sequencer.txt +++ b/Documentation/sequencer.txt @@ -1,7 +1,15 @@ --continue:: Continue the operation in progress using the information in '.git/sequencer'. Can be used to continue after resolving - conflicts in a failed cherry-pick or revert. + conflicts in a failed cherry-pick or revert. Use `--skip` + instead if the current commit should be ignored. + +--skip:: + Skips the current commit, and then continues the operation + in progress using the information in '.git/sequencer'.i + Can be used to continue to a cherry-pick or rever that was + interrupted by an empty commit, or by a commit that conflicts + and for which the resolution is to discard the commit. --quit:: Forget about the current operation in progress. Can be used diff --git a/builtin/revert.c b/builtin/revert.c index aca8a1d9d0..dece0bebf7 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -79,6 +79,7 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts) struct option base_options[] = { OPT_CMDMODE(0, "quit", &cmd, N_("end revert or cherry-pick sequence"), 'q'), OPT_CMDMODE(0, "continue", &cmd, N_("resume revert or cherry-pick sequence"), 'c'), + OPT_CMDMODE(0, "skip", &cmd, N_("resume revert or cherry-pick sequence, skipping this commit"), 's'), OPT_CMDMODE(0, "abort", &cmd, N_("cancel revert or cherry-pick sequence"), 'a'), OPT_BOOL('n', "no-commit", &opts->no_commit, N_("don't automatically commit")), OPT_BOOL('e', "edit", &opts->edit, N_("edit the commit message")), @@ -127,6 +128,8 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts) this_operation = "--quit"; else if (cmd == 'c') this_operation = "--continue"; + else if (cmd == 's') + this_operation = "--skip"; else { assert(cmd == 'a'); this_operation = "--abort"; @@ -188,8 +191,8 @@ static int run_sequencer(int argc, const char **argv, struct replay_opts *opts) if (cmd == 'q') return sequencer_remove_state(opts); - if (cmd == 'c') - return sequencer_continue(opts); + if (cmd == 'c' || cmd == 's') + return sequencer_continue(opts, cmd); if (cmd == 'a') return sequencer_rollback(opts); return sequencer_pick_revisions(opts); diff --git a/sequencer.c b/sequencer.c index 333d9112de..cfe8c06989 100644 --- a/sequencer.c +++ b/sequencer.c @@ -1359,21 +1359,45 @@ static int continue_single_pick(void) return run_command_v_opt(argv, RUN_GIT_CMD); } -int sequencer_continue(struct replay_opts *opts) +/* + * Continue the sequencing, after either committing + * (cmd == 'c') or skipping (cmd == 's') the current + * commit. + */ +int sequencer_continue(struct replay_opts *opts, char cmd) { struct todo_list todo_list = TODO_LIST_INIT; - int res; + int single, res; if (read_and_refresh_cache(opts)) return -1; - if (!file_exists(get_todo_path(opts))) - return continue_single_pick(); + if (!file_exists(get_todo_path(opts))) { + if (cmd == 'c') { + return continue_single_pick(); + } else { + assert(cmd == 's'); + /* Skipping the only commit is equivalent to an abort */ + return sequencer_rollback(opts); + } + } if (read_populate_opts(opts)) return -1; if ((res = read_populate_todo(&todo_list, opts))) goto release_todo_list; + /* If we were asked to skip this commit, rollback + * and continue with the next */ + if (cmd == 's') { + if ((res = rollback_single_pick())) + goto release_todo_list; + discard_cache(); + if ((res = read_cache()) < 0) + goto release_todo_list; + printf("index unchanged: %d\n", is_index_unchanged()); + goto skip_this_commit; + } + /* check if there is something to commit */ res = is_index_unchanged(); if (res < 0) diff --git a/sequencer.h b/sequencer.h index f8b8bd0063..afc4bb4e6c 100644 --- a/sequencer.h +++ b/sequencer.h @@ -41,7 +41,7 @@ struct replay_opts { #define REPLAY_OPTS_INIT { -1 } int sequencer_pick_revisions(struct replay_opts *opts); -int sequencer_continue(struct replay_opts *opts); +int sequencer_continue(struct replay_opts *opts, char cmd); int sequencer_rollback(struct replay_opts *opts); int sequencer_remove_state(struct replay_opts *opts); -- 2.11.0.616.gd72966cf44.dirty