]> git.ipfire.org Git - thirdparty/git.git/blobdiff - sequencer.c
sequencer: allow editing the commit message on a case-by-case basis
[thirdparty/git.git] / 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;