Always assume format_commit_item() takes an utf-8 string for string handling simplicity (we can handle utf-8 strings, but can't with other encodings). If commit message is in non-utf8, or output encoding is not, then the commit is first converted to utf-8, processed, then output converted to output encoding. This of course only works with encodings that are compatible with Unicode. This also fixes the iso8859-1 test in t6006. It's supposed to create an iso8859-1 commit, but the commit content in t6006 is in UTF-8. t6006 is now converted back in UTF-8 (the downside is we can't put utf-8 strings there anymore). Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- pretty.c | 24 ++++++++++++++++++++++-- t/t6006-rev-list-format.sh | 12 ++++++------ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/pretty.c b/pretty.c index 092dd1d..3f4809a 100644 --- a/pretty.c +++ b/pretty.c @@ -1003,7 +1003,8 @@ static int format_reflog_person(struct strbuf *sb, return format_person_part(sb, part, ident, strlen(ident), dmode); } -static size_t format_commit_one(struct strbuf *sb, const char *placeholder, +static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ + const char *placeholder, void *context) { struct format_commit_context *c = context; @@ -1235,7 +1236,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder, return 0; /* unknown placeholder */ } -static size_t format_commit_item(struct strbuf *sb, const char *placeholder, +static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */ + const char *placeholder, void *context) { int consumed; @@ -1315,6 +1317,7 @@ void format_commit_message(const struct commit *commit, { struct format_commit_context context; const char *output_enc = pretty_ctx->output_encoding; + const char *utf8 = "UTF-8"; memset(&context, 0, sizeof(context)); context.commit = commit; @@ -1327,6 +1330,23 @@ void format_commit_message(const struct commit *commit, strbuf_expand(sb, format, format_commit_item, &context); rewrap_message_tail(sb, &context, 0, 0, 0); + if (output_enc) { + if (same_encoding(utf8, output_enc)) + output_enc = NULL; + } else { + if (context.commit_encoding && + !same_encoding(context.commit_encoding, utf8)) + output_enc = context.commit_encoding; + } + + if (output_enc) { + int outsz; + char *out = reencode_string(sb->buf, sb->len, + output_enc, utf8, &outsz); + if (out) + strbuf_attach(sb, out, outsz, outsz + 1); + } + free(context.commit_encoding); logmsg_free(context.message, commit); free(context.signature.gpg_output); diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index 3fc3b74..0393c9f 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -184,7 +184,7 @@ Test printing of complex bodies This commit message is much longer than the others, and it will be encoded in iso8859-1. We should therefore -include an iso8859 character: ¡bueno! +include an iso8859 character: �bueno! EOF test_expect_success 'setup complex body' ' git config i18n.commitencoding iso8859-1 && @@ -192,14 +192,14 @@ git config i18n.commitencoding iso8859-1 && ' test_format complex-encoding %e <<'EOF' -commit f58db70b055c5718631e5c61528b28b12090cdea +commit 1ed88da4a5b5ed8c449114ac131efc62178734c3 iso8859-1 commit 131a310eb913d107dd3c09a65d1651175898735d commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 EOF test_format complex-subject %s <<'EOF' -commit f58db70b055c5718631e5c61528b28b12090cdea +commit 1ed88da4a5b5ed8c449114ac131efc62178734c3 Test printing of complex bodies commit 131a310eb913d107dd3c09a65d1651175898735d changed foo @@ -208,17 +208,17 @@ added foo EOF test_format complex-body %b <<'EOF' -commit f58db70b055c5718631e5c61528b28b12090cdea +commit 1ed88da4a5b5ed8c449114ac131efc62178734c3 This commit message is much longer than the others, and it will be encoded in iso8859-1. We should therefore -include an iso8859 character: ¡bueno! +include an iso8859 character: �bueno! commit 131a310eb913d107dd3c09a65d1651175898735d commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 EOF test_expect_success '%x00 shows NUL' ' - echo >expect commit f58db70b055c5718631e5c61528b28b12090cdea && + echo >expect commit 1ed88da4a5b5ed8c449114ac131efc62178734c3 && echo >>expect fooQbar && git rev-list -1 --format=foo%x00bar HEAD >actual.nul && nul_to_q <actual.nul >actual && -- 1.8.2.83.gc99314b -- 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