sequencer: allow editing the commit message on a case-by-case basis
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Fri, 21 Oct 2016 12:25:12 +0000 (14:25 +0200)
committerJunio C Hamano <gitster@pobox.com>
Fri, 21 Oct 2016 16:32:34 +0000 (09:32 -0700)
In the upcoming commits, we will implement more and more of rebase -i's
functionality inside the sequencer. One particular feature of the
commands to come is that some of them allow editing the commit message
while others don't, i.e. we cannot define in the replay_opts whether the
commit message should be edited or not.

Let's add a new parameter to the run_git_commit() function. Previously,
it was the duty of the caller to ensure that the opts->edit setting
indicates whether to let the user edit the commit message or not,
indicating that it is an "all or nothing" setting, i.e. that the
sequencer wants to let the user edit *all* commit message, or none at
all. In the upcoming rebase -i mode, it will depend on the particular
command that is currently executed, though.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
sequencer.c
index 282c4d19e8da52763a56662c8a2532c2f6eab8f3..c0a0aa0ed62b164f615da7b024bdb1610b3b7c37 100644 (file)
@@ -15,6 +15,7 @@
 #include "merge-recursive.h"
 #include "refs.h"
 #include "argv-array.h"
+#include "quote.h"
 
 #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
 
@@ -33,6 +34,11 @@ static GIT_PATH_FUNC(git_path_head_file, "sequencer/head")
  * being rebased.
  */
 static GIT_PATH_FUNC(rebase_path_author_script, "rebase-merge/author-script")
+/*
+ * The following files are written by git-rebase just after parsing the
+ * command-line (and are only consumed, not modified, by the sequencer).
+ */
+static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, "rebase-merge/gpg_sign_opt")
 
 /* We will introduce the 'interactive rebase' mode later */
 static inline int is_rebase_i(const struct replay_opts *opts)
@@ -132,6 +138,16 @@ static int has_conforming_footer(struct strbuf *sb, struct strbuf *sob,
        return 1;
 }
 
+static const char *gpg_sign_opt_quoted(struct replay_opts *opts)
+{
+       static struct strbuf buf = STRBUF_INIT;
+
+       strbuf_reset(&buf);
+       if (opts->gpg_sign)
+               sq_quotef(&buf, "-S%s", opts->gpg_sign);
+       return buf.buf;
+}
+
 int sequencer_remove_state(struct replay_opts *opts)
 {
        struct strbuf dir = STRBUF_INIT;
@@ -468,7 +484,7 @@ static char **read_author_script(void)
  * author metadata.
  */
 static int run_git_commit(const char *defmsg, struct replay_opts *opts,
-                         int allow_empty)
+                         int allow_empty, int edit)
 {
        char **env = NULL;
        struct argv_array array;
@@ -477,17 +493,20 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
 
        if (is_rebase_i(opts)) {
                env = read_author_script();
-               if (!env)
+               if (!env) {
+                       const char *gpg_opt = gpg_sign_opt_quoted(opts);
+
                        return error("You have staged changes in your working "
                                "tree. If these changes are meant to be\n"
                                "squashed into the previous commit, run:\n\n"
-                               "  git commit --amend $gpg_sign_opt_quoted\n\n"
+                               "  git commit --amend %s\n\n"
                                "If they are meant to go into a new commit, "
                                "run:\n\n"
-                               "  git commit $gpg_sign_opt_quoted\n\n"
+                               "  git commit %s\n\n"
                                "In both cases, once you're done, continue "
                                "with:\n\n"
-                               "  git rebase --continue\n");
+                               "  git rebase --continue\n", gpg_opt, gpg_opt);
+               }
        }
 
        argv_array_init(&array);
@@ -500,7 +519,7 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
                argv_array_push(&array, "-s");
        if (defmsg)
                argv_array_pushl(&array, "-F", defmsg, NULL);
-       if (opts->edit)
+       if (edit)
                argv_array_push(&array, "-e");
        else if (!opts->signoff && !opts->record_origin &&
                 git_config_get_value("commit.cleanup", &value))
@@ -767,7 +786,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
        }
        if (!opts->no_commit)
                res = run_git_commit(opts->edit ? NULL : git_path_merge_msg(),
-                                    opts, allow);
+                                    opts, allow, opts->edit);
 
 leave:
        free_message(commit, &msg);
@@ -989,8 +1008,21 @@ static int populate_opts_cb(const char *key, const char *value, void *data)
 
 static int read_populate_opts(struct replay_opts *opts)
 {
-       if (is_rebase_i(opts))
+       if (is_rebase_i(opts)) {
+               struct strbuf buf = STRBUF_INIT;
+
+               if (read_oneliner(&buf, rebase_path_gpg_sign_opt(), 1)) {
+                       if (!starts_with(buf.buf, "-S"))
+                               strbuf_reset(&buf);
+                       else {
+                               free(opts->gpg_sign);
+                               opts->gpg_sign = xstrdup(buf.buf + 2);
+                       }
+               }
+               strbuf_release(&buf);
+
                return 0;
+       }
 
        if (!file_exists(git_path_opts_file()))
                return 0;