From: Junio C Hamano Date: Wed, 6 Jul 2016 20:38:11 +0000 (-0700) Subject: Merge branch 'ew/mboxrd-format-am' X-Git-Tag: v2.10.0-rc0~158 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/e25a4ded8a47333a4c71a224927d6df87d7c295e?hp=-c Merge branch 'ew/mboxrd-format-am' Teach format-patch and mailsplit (hence "am") how a line that happens to begin with "From " in the e-mail message is quoted with ">", so that these lines can be restored to their original shape. * ew/mboxrd-format-am: am: support --patch-format=mboxrd mailsplit: support unescaping mboxrd messages pretty: support "mboxrd" output format --- e25a4ded8a47333a4c71a224927d6df87d7c295e diff --combined builtin/log.c index 8eef94f335,6d6f368175..de47b4e89a --- a/builtin/log.c +++ b/builtin/log.c @@@ -674,9 -674,9 +674,9 @@@ static int auto_number = 1 static char *default_attach = NULL; -static struct string_list extra_hdr; -static struct string_list extra_to; -static struct string_list extra_cc; +static struct string_list extra_hdr = STRING_LIST_INIT_NODUP; +static struct string_list extra_to = STRING_LIST_INIT_NODUP; +static struct string_list extra_cc = STRING_LIST_INIT_NODUP; static void add_header(const char *value) { @@@ -953,7 -953,7 +953,7 @@@ static void make_cover_letter(struct re struct pretty_print_context pp = {0}; struct commit *head = list[0]; - if (rev->commit_format != CMIT_FMT_EMAIL) + if (!cmit_fmt_is_mail(rev->commit_format)) die(_("Cover letter needs email format")); committer = git_committer_info(0); diff --combined pretty.c index c3ec430220,6abd8a1215..929e5aef97 --- a/pretty.c +++ b/pretty.c @@@ -92,6 -92,7 +92,7 @@@ static void setup_commit_formats(void { "medium", CMIT_FMT_MEDIUM, 0, 8 }, { "short", CMIT_FMT_SHORT, 0, 0 }, { "email", CMIT_FMT_EMAIL, 0, 0 }, + { "mboxrd", CMIT_FMT_MBOXRD, 0, 0 }, { "fuller", CMIT_FMT_FULLER, 0, 8 }, { "full", CMIT_FMT_FULL, 0, 8 }, { "oneline", CMIT_FMT_ONELINE, 1, 0 } @@@ -444,7 -445,7 +445,7 @@@ void pp_user_info(struct pretty_print_c if (pp->mailmap) map_user(pp->mailmap, &mailbuf, &maillen, &namebuf, &namelen); - if (pp->fmt == CMIT_FMT_EMAIL) { + if (cmit_fmt_is_mail(pp->fmt)) { if (pp->from_ident && ident_cmp(pp->from_ident, &ident)) { struct strbuf buf = STRBUF_INIT; @@@ -494,6 -495,7 +495,7 @@@ show_ident_date(&ident, &pp->date_mode)); break; case CMIT_FMT_EMAIL: + case CMIT_FMT_MBOXRD: strbuf_addf(sb, "Date: %s\n", show_ident_date(&ident, DATE_MODE(RFC2822))); break; @@@ -535,7 -537,7 +537,7 @@@ static void add_merge_info(const struc { struct commit_list *parent = commit->parents; - if ((pp->fmt == CMIT_FMT_ONELINE) || (pp->fmt == CMIT_FMT_EMAIL) || + if ((pp->fmt == CMIT_FMT_ONELINE) || (cmit_fmt_is_mail(pp->fmt)) || !parent || !parent->next) return; @@@ -1063,7 -1065,7 +1065,7 @@@ static size_t format_commit_one(struct switch (placeholder[0]) { case 'C': if (starts_with(placeholder + 1, "(auto)")) { - c->auto_color = 1; + c->auto_color = want_color(c->pretty_ctx->color); return 7; /* consumed 7 bytes, "C(auto)" */ } else { int ret = parse_color(sb, placeholder, c); @@@ -1614,7 -1616,7 +1616,7 @@@ void pp_title_line(struct pretty_print_ if (pp->after_subject) { strbuf_addstr(sb, pp->after_subject); } - if (pp->fmt == CMIT_FMT_EMAIL) { + if (cmit_fmt_is_mail(pp->fmt)) { strbuf_addch(sb, '\n'); } @@@ -1697,6 -1699,16 +1699,16 @@@ static void pp_handle_indent(struct pre strbuf_add(sb, line, linelen); } + static int is_mboxrd_from(const char *line, int len) + { + /* + * a line matching /^From $/ here would only have len == 4 + * at this point because is_empty_line would've trimmed all + * trailing space + */ + return len > 4 && starts_with(line + strspn(line, ">"), "From "); + } + void pp_remainder(struct pretty_print_context *pp, const char **msg_p, struct strbuf *sb, @@@ -1725,8 -1737,13 +1737,13 @@@ else if (pp->expand_tabs_in_log) strbuf_add_tabexpand(sb, pp->expand_tabs_in_log, line, linelen); - else + else { + if (pp->fmt == CMIT_FMT_MBOXRD && + is_mboxrd_from(line, linelen)) + strbuf_addch(sb, '>'); + strbuf_add(sb, line, linelen); + } strbuf_addch(sb, '\n'); } } @@@ -1750,14 -1767,14 +1767,14 @@@ void pretty_print_commit(struct pretty_ encoding = get_log_output_encoding(); msg = reencoded = logmsg_reencode(commit, NULL, encoding); - if (pp->fmt == CMIT_FMT_ONELINE || pp->fmt == CMIT_FMT_EMAIL) + if (pp->fmt == CMIT_FMT_ONELINE || cmit_fmt_is_mail(pp->fmt)) indent = 0; /* * We need to check and emit Content-type: to mark it * as 8-bit if we haven't done so. */ - if (pp->fmt == CMIT_FMT_EMAIL && need_8bit_cte == 0) { + if (cmit_fmt_is_mail(pp->fmt) && need_8bit_cte == 0) { int i, ch, in_body; for (in_body = i = 0; (ch = msg[i]); i++) { @@@ -1785,7 -1802,7 +1802,7 @@@ msg = skip_empty_lines(msg); /* These formats treat the title line specially. */ - if (pp->fmt == CMIT_FMT_ONELINE || pp->fmt == CMIT_FMT_EMAIL) + if (pp->fmt == CMIT_FMT_ONELINE || cmit_fmt_is_mail(pp->fmt)) pp_title_line(pp, &msg, sb, encoding, need_8bit_cte); beginning_of_body = sb->len; @@@ -1802,7 -1819,7 +1819,7 @@@ * format. Make sure we did not strip the blank line * between the header and the body. */ - if (pp->fmt == CMIT_FMT_EMAIL && sb->len <= beginning_of_body) + if (cmit_fmt_is_mail(pp->fmt) && sb->len <= beginning_of_body) strbuf_addch(sb, '\n'); unuse_commit_buffer(commit, reencoded); diff --combined t/t4014-format-patch.sh index 805dc9012d,8a1cab5892..1206c48392 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@@ -1072,7 -1072,7 +1072,7 @@@ test_expect_success '--from omits redun ' test_expect_success 'in-body headers trigger content encoding' ' - GIT_AUTHOR_NAME="éxötìc" test_commit exotic && + test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic && test_when_finished "git reset --hard HEAD^" && git format-patch -1 --stdout --from >patch && cat >expect <<-\EOF && @@@ -1565,4 -1565,45 +1565,45 @@@ test_expect_success 'format-patch --bas test_cmp expected actual ' + test_expect_success 'format-patch --pretty=mboxrd' ' + sp=" " && + cat >msg <<-INPUT_END && + mboxrd should escape the body + + From could trip up a loose mbox parser + >From extra escape for reversibility + >>From extra escape for reversibility 2 + from lower case not escaped + Fromm bad speling not escaped + From with leading space not escaped + + F + From + From$sp + From $sp + From $sp + INPUT_END + + cat >expect <<-INPUT_END && + >From could trip up a loose mbox parser + >>From extra escape for reversibility + >>>From extra escape for reversibility 2 + from lower case not escaped + Fromm bad speling not escaped + From with leading space not escaped + + F + From + From + From + From + INPUT_END + + C=$(git commit-tree HEAD^^{tree} -p HEAD patch && + git grep -h --no-index -A11 \ + "^>From could trip up a loose mbox parser" patch >actual && + test_cmp expect actual + ' + test_done