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.bilo...@gmail.com>
---
 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

Reply via email to