format-patch: generate MIME header as needed even when there is format.header

Earlier, the callchain from pretty_print_commit() down to pp_title_line()
had an unwarranted assumption that the presense of "after_subject"
parameter, means the caller has already output MIME headers for
attachments.  The parameter's primary purpose is to give extra header
lines the caller wants to place after pp_title_line() generates the
"Subject: " line.

This assumption does not hold when the user used the format.header
configuration variable to pass extra headers, and caused a message with
non-ASCII character to lack proper MIME headers (e.g.  8-bit CTE header).
The earlier logic also failed to suppress duplicated MIME headers when
"format-patch -s --attach" is asked for and the signer's name demanded
8-bit clean transport.

This patch fixes the logic by introducing a separate need_8bit_cte
parameter passed down the callchain.  This can have one of these values:

 -1 : we've already done MIME crap and we do not want to add extra header
      to say this is 8bit in pp_title_line();

  0 : we haven't done MIME and we have not seen anything that is 8bit yet;

  1 : we haven't done MIME and we have seen something that is 8bit;
      pp_title_line() must add MIME header.

It adds two tests by Jeff King who independently diagnosed this issue.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Junio C Hamano
2008-03-14 17:10:09 -07:00
parent a0b54e7b73
commit 6bf4f1b4c9
5 changed files with 57 additions and 16 deletions

View File

@ -659,7 +659,7 @@ static void pp_title_line(enum cmit_fmt fmt,
const char *subject,
const char *after_subject,
const char *encoding,
int plain_non_ascii)
int need_8bit_cte)
{
struct strbuf title;
@ -692,7 +692,7 @@ static void pp_title_line(enum cmit_fmt fmt,
}
strbuf_addch(sb, '\n');
if (plain_non_ascii) {
if (need_8bit_cte > 0) {
const char *header_fmt =
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=%s\n"
@ -741,9 +741,9 @@ static void pp_remainder(enum cmit_fmt fmt,
}
void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
struct strbuf *sb, int abbrev,
const char *subject, const char *after_subject,
enum date_mode dmode, int plain_non_ascii)
struct strbuf *sb, int abbrev,
const char *subject, const char *after_subject,
enum date_mode dmode, int need_8bit_cte)
{
unsigned long beginning_of_body;
int indent = 4;
@ -769,13 +769,11 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
indent = 0;
/* After-subject is used to pass in Content-Type: multipart
* MIME header; in that case we do not have to do the
* plaintext content type even if the commit message has
* non 7-bit ASCII character. Otherwise, check if we need
* to say this is not a 7-bit ASCII.
/*
* We need to check and emit Content-type: to mark it
* as 8-bit if we haven't done so.
*/
if (fmt == CMIT_FMT_EMAIL && !after_subject) {
if (fmt == CMIT_FMT_EMAIL && need_8bit_cte == 0) {
int i, ch, in_body;
for (in_body = i = 0; (ch = msg[i]); i++) {
@ -788,7 +786,7 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
in_body = 1;
}
else if (non_ascii(ch)) {
plain_non_ascii = 1;
need_8bit_cte = 1;
break;
}
}
@ -813,7 +811,7 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
/* These formats treat the title line specially. */
if (fmt == CMIT_FMT_ONELINE || fmt == CMIT_FMT_EMAIL)
pp_title_line(fmt, &msg, sb, subject,
after_subject, encoding, plain_non_ascii);
after_subject, encoding, need_8bit_cte);
beginning_of_body = sb->len;
if (fmt != CMIT_FMT_ONELINE)