Currently, if the s-o-b footer of a commit message contains a "(cherry picked from ..." line that was added by a previous cherry-pick -x, it is not recognized as a s-o-b footer and will cause a newline to be inserted before an additional s-o-b is added. So, rework ends_rfc2822_footer to recognize the "(cherry picked from ..." string as part of the footer. Plus mark the test in t3511 as fixed. Signed-off-by: Brandon Casey <bcasey@xxxxxxxxxx> --- sequencer.c | 44 +++++++++++++++++++++++++++++--------------- t/t3511-cherry-pick-x.sh | 2 +- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/sequencer.c b/sequencer.c index 01edec2..27e684c 100644 --- a/sequencer.c +++ b/sequencer.c @@ -18,6 +18,7 @@ #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION" const char sign_off_header[] = "Signed-off-by: "; +const char cherry_picked_prefix[] = "(cherry picked from commit "; static void remove_sequencer_state(void) { @@ -492,7 +493,7 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts) } if (opts->record_origin) { - strbuf_addstr(&msgbuf, "(cherry picked from commit "); + strbuf_addstr(&msgbuf, cherry_picked_prefix); strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1)); strbuf_addstr(&msgbuf, ")\n"); } @@ -1017,13 +1018,34 @@ int sequencer_pick_revisions(struct replay_opts *opts) return pick_commits(todo_list, opts); } +static int is_rfc2822_line(const char *buf, int len) +{ + int i; + + for (i = 0; i < len; i++) { + int ch = buf[i]; + if (ch == ':') + break; + if (isalnum(ch) || (ch == '-')) + continue; + return 0; + } + + return 1; +} + +static int is_cherry_pick_from_line(const char *buf, int len) +{ + return (strlen(cherry_picked_prefix) + 41) <= len && + !prefixcmp(buf, cherry_picked_prefix); +} + static int ends_rfc2822_footer(struct strbuf *sb, int ignore_footer) { - int ch; int hit = 0; - int i, j, k; + int i, k; int len = sb->len - ignore_footer; - int first = 1; + int last_was_rfc2822 = 0; const char *buf = sb->buf; for (i = len - 1; i > 0; i--) { @@ -1040,20 +1062,12 @@ static int ends_rfc2822_footer(struct strbuf *sb, int ignore_footer) ; /* do nothing */ k++; - if ((buf[i] == ' ' || buf[i] == '\t') && !first) + if (last_was_rfc2822 && (buf[i] == ' ' || buf[i] == '\t')) continue; - first = 0; - - for (j = 0; i + j < len; j++) { - ch = buf[i + j]; - if (ch == ':') - break; - if (isalnum(ch) || - (ch == '-')) - continue; + if (!((last_was_rfc2822 = is_rfc2822_line(buf+i, k-i)) || + is_cherry_pick_from_line(buf+i, k-i))) return 0; - } } return 1; } diff --git a/t/t3511-cherry-pick-x.sh b/t/t3511-cherry-pick-x.sh index b2098e0..785486e 100755 --- a/t/t3511-cherry-pick-x.sh +++ b/t/t3511-cherry-pick-x.sh @@ -63,7 +63,7 @@ test_expect_success 'cherry-pick -s not confused by rfc2822 continuation line' ' test_cmp expect actual ' -test_expect_failure 'cherry-pick treats -s "(cherry picked from..." line as part of footer' ' +test_expect_success 'cherry-pick treats -s "(cherry picked from..." line as part of footer' ' pristine_detach initial && git cherry-pick -s rfc2822-cherry-base && cat <<-EOF >expect && -- 1.8.0 -- 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