sequencer: fix "rebase -i --root" corrupting author header timestamp
[gitweb.git] / sequencer.c
index cca968043ea86c4515e6af1b4fe9251a0140c0a3..580516959dac54aadec12a24b55d92c680ed090d 100644 (file)
@@ -651,6 +651,7 @@ static int write_author_script(const char *message)
                        strbuf_addch(&buf, *(message++));
                else
                        strbuf_addf(&buf, "'\\\\%c'", *(message++));
+       strbuf_addch(&buf, '\'');
        res = write_message(buf.buf, buf.len, rebase_path_author_script(), 1);
        strbuf_release(&buf);
        return res;
@@ -705,14 +706,16 @@ static const char *read_author_ident(struct strbuf *buf)
        const char *keys[] = {
                "GIT_AUTHOR_NAME=", "GIT_AUTHOR_EMAIL=", "GIT_AUTHOR_DATE="
        };
-       char *in, *out, *eol;
-       int i = 0, len;
+       struct strbuf out = STRBUF_INIT;
+       char *in, *eol;
+       const char *val[3];
+       int i = 0;
 
        if (strbuf_read_file(buf, rebase_path_author_script(), 256) <= 0)
                return NULL;
 
        /* dequote values and construct ident line in-place */
-       for (in = out = buf->buf; i < 3 && in - buf->buf < buf->len; i++) {
+       for (in = buf->buf; i < 3 && in - buf->buf < buf->len; i++) {
                if (!skip_prefix(in, keys[i], (const char **)&in)) {
                        warning("could not parse '%s' (looking for '%s'",
                                rebase_path_author_script(), keys[i]);
@@ -721,17 +724,12 @@ static const char *read_author_ident(struct strbuf *buf)
 
                eol = strchrnul(in, '\n');
                *eol = '\0';
-               sq_dequote(in);
-               len = strlen(in);
-
-               if (i > 0) /* separate values by spaces */
-                       *(out++) = ' ';
-               if (i == 1) /* email needs to be surrounded by <...> */
-                       *(out++) = '<';
-               memmove(out, in, len);
-               out += len;
-               if (i == 1) /* email needs to be surrounded by <...> */
-                       *(out++) = '>';
+               if (!sq_dequote(in)) {
+                       warning(_("bad quoting on %s value in '%s'"),
+                               keys[i], rebase_path_author_script());
+                       return NULL;
+               }
+               val[i] = in;
                in = eol + 1;
        }
 
@@ -741,7 +739,9 @@ static const char *read_author_ident(struct strbuf *buf)
                return NULL;
        }
 
-       buf->len = out - buf->buf;
+       strbuf_addstr(&out, fmt_ident(val[0], val[1], val[2], 0));
+       strbuf_swap(buf, &out);
+       strbuf_release(&out);
        return buf->buf;
 }
 
@@ -784,7 +784,7 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
        struct child_process cmd = CHILD_PROCESS_INIT;
        const char *value;
 
-       if (flags & CREATE_ROOT_COMMIT) {
+       if ((flags & CREATE_ROOT_COMMIT) && !(flags & AMEND_MSG)) {
                struct strbuf msg = STRBUF_INIT, script = STRBUF_INIT;
                const char *author = is_rebase_i(opts) ?
                        read_author_ident(&script) : NULL;