sequencer (rebase -i): respect the rebase.autostash setting
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Mon, 2 Jan 2017 15:28:27 +0000 (16:28 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 9 Jan 2017 22:57:30 +0000 (14:57 -0800)
Git's `rebase` command inspects the `rebase.autostash` config setting
to determine whether it should stash any uncommitted changes before
rebasing and re-apply them afterwards.

As we introduce more bits and pieces to let the sequencer act as
interactive rebase's backend, here is the part that adds support for
the autostash feature.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
sequencer.c
index 43ced8db31adbce1b92b4f438319c1993ba4b43e..06f7cebe488d6ee7ba74c7c14c1f5d598a8ec8ae 100644 (file)
@@ -113,6 +113,7 @@ static GIT_PATH_FUNC(rebase_path_orig_head, "rebase-merge/orig-head")
 static GIT_PATH_FUNC(rebase_path_verbose, "rebase-merge/verbose")
 static GIT_PATH_FUNC(rebase_path_head_name, "rebase-merge/head-name")
 static GIT_PATH_FUNC(rebase_path_onto, "rebase-merge/onto")
+static GIT_PATH_FUNC(rebase_path_autostash, "rebase-merge/autostash")
 
 static inline int is_rebase_i(const struct replay_opts *opts)
 {
@@ -1801,6 +1802,47 @@ static enum todo_command peek_command(struct todo_list *todo_list, int offset)
        return -1;
 }
 
+static int apply_autostash(struct replay_opts *opts)
+{
+       struct strbuf stash_sha1 = STRBUF_INIT;
+       struct child_process child = CHILD_PROCESS_INIT;
+       int ret = 0;
+
+       if (!read_oneliner(&stash_sha1, rebase_path_autostash(), 1)) {
+               strbuf_release(&stash_sha1);
+               return 0;
+       }
+       strbuf_trim(&stash_sha1);
+
+       child.git_cmd = 1;
+       argv_array_push(&child.args, "stash");
+       argv_array_push(&child.args, "apply");
+       argv_array_push(&child.args, stash_sha1.buf);
+       if (!run_command(&child))
+               printf(_("Applied autostash."));
+       else {
+               struct child_process store = CHILD_PROCESS_INIT;
+
+               store.git_cmd = 1;
+               argv_array_push(&store.args, "stash");
+               argv_array_push(&store.args, "store");
+               argv_array_push(&store.args, "-m");
+               argv_array_push(&store.args, "autostash");
+               argv_array_push(&store.args, "-q");
+               argv_array_push(&store.args, stash_sha1.buf);
+               if (run_command(&store))
+                       ret = error(_("cannot store %s"), stash_sha1.buf);
+               else
+                       printf(_("Applying autostash resulted in conflicts.\n"
+                               "Your changes are safe in the stash.\n"
+                               "You can run \"git stash pop\" or"
+                               " \"git stash drop\" at any time.\n"));
+       }
+
+       strbuf_release(&stash_sha1);
+       return ret;
+}
+
 static const char *reflog_message(struct replay_opts *opts,
        const char *sub_action, const char *fmt, ...)
 {
@@ -1980,6 +2022,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
                                run_command(&hook);
                        }
                }
+               apply_autostash(opts);
 
                strbuf_release(&buf);
                strbuf_release(&head_ref);