In case 'git cherry-pick -s <commit>' failed, the user had to use 'git commit -s' (i.e. state the -s option again), which is easy to forget about. Instead, write the signed-off-by line early, so plain 'git commit' will have the same result. Signed-off-by: Miklos Vajna <vmiklos@xxxxxxx> --- Hi, See http://article.gmane.org/gmane.comp.documentfoundation.libreoffice.devel/36103 for motivation. :-) Given that I needed sign_off_header / ends_rfc2822_footer and some code from builtin/commit.c in sequencer.c, I moved them there, let me know if there is a place better than sequencer.c for them. Thanks, Miklos builtin/commit.c | 63 ++------------------------------------ sequencer.c | 65 +++++++++++++++++++++++++++++++++++++++ sequencer.h | 4 ++ t/t3507-cherry-pick-conflict.sh | 6 +++ 4 files changed, 78 insertions(+), 60 deletions(-) diff --git a/builtin/commit.c b/builtin/commit.c index 778cf16..7d0df9a 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -28,6 +28,7 @@ #include "submodule.h" #include "gpg-interface.h" #include "column.h" +#include "sequencer.h" static const char * const builtin_commit_usage[] = { N_("git commit [options] [--] <filepattern>..."), @@ -466,8 +467,6 @@ static int is_a_merge(const struct commit *current_head) return !!(current_head->parents && current_head->parents->next); } -static const char sign_off_header[] = "Signed-off-by: "; - static void export_one(const char *var, const char *s, const char *e, int hack) { struct strbuf buf = STRBUF_INIT; @@ -552,47 +551,6 @@ static void determine_author_info(struct strbuf *author_ident) } } -static int ends_rfc2822_footer(struct strbuf *sb) -{ - int ch; - int hit = 0; - int i, j, k; - int len = sb->len; - int first = 1; - const char *buf = sb->buf; - - for (i = len - 1; i > 0; i--) { - if (hit && buf[i] == '\n') - break; - hit = (buf[i] == '\n'); - } - - while (i < len - 1 && buf[i] == '\n') - i++; - - for (; i < len; i = k) { - for (k = i; k < len && buf[k] != '\n'; k++) - ; /* do nothing */ - k++; - - if ((buf[k] == ' ' || buf[k] == '\t') && !first) - continue; - - first = 0; - - for (j = 0; i + j < len; j++) { - ch = buf[i + j]; - if (ch == ':') - break; - if (isalnum(ch) || - (ch == '-')) - continue; - return 0; - } - } - return 1; -} - static char *cut_ident_timestamp_part(char *string) { char *ket = strrchr(string, '>'); @@ -716,23 +674,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix, if (clean_message_contents) stripspace(&sb, 0); - if (signoff) { - struct strbuf sob = STRBUF_INIT; - int i; - - strbuf_addstr(&sob, sign_off_header); - strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"), - getenv("GIT_COMMITTER_EMAIL"))); - strbuf_addch(&sob, '\n'); - for (i = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--) - ; /* do nothing */ - if (prefixcmp(sb.buf + i, sob.buf)) { - if (!i || !ends_rfc2822_footer(&sb)) - strbuf_addch(&sb, '\n'); - strbuf_addbuf(&sb, &sob); - } - strbuf_release(&sob); - } + if (signoff) + append_signoff(&sb); if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len) die_errno(_("could not write commit template")); diff --git a/sequencer.c b/sequencer.c index f86f116..402dcd6 100644 --- a/sequencer.c +++ b/sequencer.c @@ -17,6 +17,8 @@ #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION" +const char sign_off_header[] = "Signed-off-by: "; + void remove_sequencer_state(void) { struct strbuf seq_dir = STRBUF_INIT; @@ -249,6 +251,9 @@ static int do_recursive_merge(struct commit *base, struct commit *next, } } + if (opts->signoff) + append_signoff(msgbuf); + return !clean; } @@ -1011,3 +1016,63 @@ int sequencer_pick_revisions(struct replay_opts *opts) save_opts(opts); return pick_commits(todo_list, opts); } + +static int ends_rfc2822_footer(struct strbuf *sb) +{ + int ch; + int hit = 0; + int i, j, k; + int len = sb->len; + int first = 1; + const char *buf = sb->buf; + + for (i = len - 1; i > 0; i--) { + if (hit && buf[i] == '\n') + break; + hit = (buf[i] == '\n'); + } + + while (i < len - 1 && buf[i] == '\n') + i++; + + for (; i < len; i = k) { + for (k = i; k < len && buf[k] != '\n'; k++) + ; /* do nothing */ + k++; + + if ((buf[k] == ' ' || buf[k] == '\t') && !first) + continue; + + first = 0; + + for (j = 0; i + j < len; j++) { + ch = buf[i + j]; + if (ch == ':') + break; + if (isalnum(ch) || + (ch == '-')) + continue; + return 0; + } + } + return 1; +} + +void append_signoff(struct strbuf *msgbuf) +{ + struct strbuf sob = STRBUF_INIT; + int i; + + strbuf_addstr(&sob, sign_off_header); + strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"), + getenv("GIT_COMMITTER_EMAIL"))); + strbuf_addch(&sob, '\n'); + for (i = msgbuf->len - 1; i > 0 && msgbuf->buf[i - 1] != '\n'; i--) + ; /* do nothing */ + if (prefixcmp(msgbuf->buf + i, sob.buf)) { + if (!i || !ends_rfc2822_footer(msgbuf)) + strbuf_addch(msgbuf, '\n'); + strbuf_addbuf(msgbuf, &sob); + } + strbuf_release(&sob); +} diff --git a/sequencer.h b/sequencer.h index d849420..440b0c9 100644 --- a/sequencer.h +++ b/sequencer.h @@ -49,4 +49,8 @@ extern void remove_sequencer_state(void); int sequencer_pick_revisions(struct replay_opts *opts); +extern const char sign_off_header[]; + +void append_signoff(struct strbuf *msgbuf); + #endif diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh index 0c81b3c..eb52f1e 100755 --- a/t/t3507-cherry-pick-conflict.sh +++ b/t/t3507-cherry-pick-conflict.sh @@ -340,4 +340,10 @@ test_expect_success 'revert conflict, diff3 -m style' ' test_cmp expected actual ' +test_expect_success 'failed cherry-pick does not forget -s' ' + pristine_detach initial && + test_must_fail git cherry-pick -s picked && + test_i18ngrep -e "Signed-off-by" .git/MERGE_MSG +' + test_done -- 1.7.7 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html