{"thread":{"id":"53167","subject":"[PATCH] format-patch: teach --no-encode-headers","startedAt":"2020-04-06T00:27:32Z","lastAt":"2020-04-08T04:34:05Z","messageCount":15,"participants":["Emma Brooks","brian m. carlson","Junio C Hamano","Jeff King","Danh Doan"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"394816","messageId":"20200405231109.8249-1-me@pluvano.com","threadId":"53167","inReplyTo":null,"subject":"[PATCH] format-patch: teach --no-encode-headers","fromName":"Emma Brooks","fromEmail":"me@pluvano.com","sentAt":"2020-04-05T23:11:09Z","receivedAt":"2020-04-06T00:27:32Z","isPatch":true,"sender":{"key":"me@pluvano.com","avatar":"https://avatars.githubusercontent.com/u/50312486?v=4"},"body":"When commit subjects or authors have non-ASCII characters, git\nformat-patch Q-encodes them so they can be safely sent over email.\nHowever, if the patch transfer method is something other than email (web\nreview tools, sneakernet), this only serves to make the patch metadata\nharder to read without first applying it (unless you can decode RFC 2047\nin your head). git am as well as some email software supports\nnon-Q-encoded mail as described in RFC 6531.\n\nAdd --[no-]encode-headers and format.encodeHeaders to let the user\ncontrol this behavior.\n\nSigned-off-by: Emma Brooks <me@pluvano.com>\n---\n Documentation/config/format.txt    |  4 +++\n Documentation/git-format-patch.txt |  7 ++++\n builtin/log.c                      |  7 ++++\n log-tree.c                         |  1 +\n pretty.c                           |  6 ++--\n pretty.h                           |  1 +\n revision.c                         |  4 +++\n revision.h                         |  3 +-\n t/t4014-format-patch.sh            | 53 ++++++++++++++++++++++++++++++\n 9 files changed, 83 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config/format.txt b/Documentation/config/format.txt\nindex 45c7bd5a8f..ee0eb4c5da 100644\n--- a/Documentation/config/format.txt\n+++ b/Documentation/config/format.txt\n@@ -57,6 +57,10 @@ format.suffix::\n \t`.patch`. Use this variable to change that suffix (make sure to\n \tinclude the dot if you want it).\n \n+format.encodeHeaders::\n+\tEncode email headers that have non-ASCII characters with\n+\t\"Q-encoding\" for email transmission. Defaults to true.\n+\n format.pretty::\n \tThe default pretty format for log/show/whatchanged command,\n \tSee linkgit:git-log[1], linkgit:git-show[1],\ndiff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\nindex 0d4f8951bb..a1483a6a34 100644\n--- a/Documentation/git-format-patch.txt\n+++ b/Documentation/git-format-patch.txt\n@@ -24,6 +24,7 @@ SYNOPSIS\n \t\t   [(--reroll-count|-v) <n>]\n \t\t   [--to=<email>] [--cc=<email>]\n \t\t   [--[no-]cover-letter] [--quiet]\n+\t\t   [--[no-]encode-headers]\n \t\t   [--no-notes | --notes[=<ref>]]\n \t\t   [--interdiff=<previous>]\n \t\t   [--range-diff=<previous> [--creation-factor=<percent>]]\n@@ -253,6 +254,12 @@ feeding the result to `git send-email`.\n \tcontaining the branch description, shortlog and the overall diffstat.  You can\n \tfill in a description in the file before sending it out.\n \n+--[no-]encode-headers::\n+\tEncode email headers that have non-ASCII characters with\n+\t\"Q-encoding\", instead of outputting the headers verbatim. The\n+\tdefault is `--encode-headers` unless the `format.encodeHeaders`\n+\tconfiguration variable is set.\n+\n --interdiff=<previous>::\n \tAs a reviewer aid, insert an interdiff into the cover letter,\n \tor as commentary of the lone patch of a 1-patch series, showing\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 83a4a6188e..1a27049c88 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -46,6 +46,7 @@ static int default_abbrev_commit;\n static int default_show_root = 1;\n static int default_follow;\n static int default_show_signature;\n+static int default_encode_headers = 1;\n static int decoration_style;\n static int decoration_given;\n static int use_mailmap_config = 1;\n@@ -151,6 +152,7 @@ static void cmd_log_init_defaults(struct rev_info *rev)\n \trev->show_root_diff = default_show_root;\n \trev->subject_prefix = fmt_patch_subject_prefix;\n \trev->show_signature = default_show_signature;\n+\trev->encode_headers = default_encode_headers;\n \trev->diffopt.flags.allow_textconv = 1;\n \n \tif (default_date_mode)\n@@ -438,6 +440,10 @@ static int git_log_config(const char *var, const char *value, void *cb)\n \t\treturn git_config_string(&fmt_pretty, var, value);\n \tif (!strcmp(var, \"format.subjectprefix\"))\n \t\treturn git_config_string(&fmt_patch_subject_prefix, var, value);\n+\tif (!strcmp(var, \"format.encodeheaders\")) {\n+\t\tdefault_encode_headers = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n \tif (!strcmp(var, \"log.abbrevcommit\")) {\n \t\tdefault_abbrev_commit = git_config_bool(var, value);\n \t\treturn 0;\n@@ -1719,6 +1725,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \trev.show_notes = show_notes;\n \tmemcpy(&rev.notes_opt, &notes_opt, sizeof(notes_opt));\n \trev.commit_format = CMIT_FMT_EMAIL;\n+\trev.encode_headers = default_encode_headers;\n \trev.expand_tabs_in_log_default = 0;\n \trev.verbose_header = 1;\n \trev.diff = 1;\ndiff --git a/log-tree.c b/log-tree.c\nindex 897a90233e..eaec299762 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -693,6 +693,7 @@ void show_log(struct rev_info *opt)\n \tctx.abbrev = opt->diffopt.abbrev;\n \tctx.after_subject = extra_headers;\n \tctx.preserve_subject = opt->preserve_subject;\n+\tctx.encode_headers = opt->encode_headers;\n \tctx.reflog_info = opt->reflog_info;\n \tctx.fmt = opt->commit_format;\n \tctx.mailmap = opt->mailmap;\ndiff --git a/pretty.c b/pretty.c\nindex 28afc701b6..12959cca4d 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -474,7 +474,8 @@ void pp_user_info(struct pretty_print_context *pp,\n \t\t}\n \n \t\tstrbuf_addstr(sb, \"From: \");\n-\t\tif (needs_rfc2047_encoding(namebuf, namelen)) {\n+\t\tif (pp->encode_headers &&\n+\t\t\t\tneeds_rfc2047_encoding(namebuf, namelen)) {\n \t\t\tadd_rfc2047(sb, namebuf, namelen,\n \t\t\t\t    encoding, RFC2047_ADDRESS);\n \t\t\tmax_length = 76; /* per rfc2047 */\n@@ -1767,7 +1768,8 @@ void pp_title_line(struct pretty_print_context *pp,\n \tif (pp->print_email_subject) {\n \t\tif (pp->rev)\n \t\t\tfmt_output_email_subject(sb, pp->rev);\n-\t\tif (needs_rfc2047_encoding(title.buf, title.len))\n+\t\tif (pp->encode_headers &&\n+\t\t\t\tneeds_rfc2047_encoding(title.buf, title.len))\n \t\t\tadd_rfc2047(sb, title.buf, title.len,\n \t\t\t\t\t\tencoding, RFC2047_SUBJECT);\n \t\telse\ndiff --git a/pretty.h b/pretty.h\nindex 4ad1fc31ff..4840f7e559 100644\n--- a/pretty.h\n+++ b/pretty.h\n@@ -43,6 +43,7 @@ struct pretty_print_context {\n \tstruct string_list *mailmap;\n \tint color;\n \tstruct ident_split *from_ident;\n+\tunsigned encode_headers:1;\n \n \t/*\n \t * Fields below here are manipulated internally by pp_* functions and\ndiff --git a/revision.c b/revision.c\nindex 8136929e23..961a901985 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -2241,6 +2241,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg\n \t\trevs->topo_order = 1;\n \t\trevs->rewrite_parents = 1;\n \t\trevs->graph = graph_init(revs);\n+\t} else if (!strcmp(arg, \"--encode-headers\")) {\n+\t\trevs->encode_headers = 1;\n+\t} else if (!strcmp(arg, \"--no-encode-headers\")) {\n+\t\trevs->encode_headers = 0;\n \t} else if (!strcmp(arg, \"--root\")) {\n \t\trevs->show_root_diff = 1;\n \t} else if (!strcmp(arg, \"--no-commit-id\")) {\ndiff --git a/revision.h b/revision.h\nindex 475f048fb6..e4dff23d62 100644\n--- a/revision.h\n+++ b/revision.h\n@@ -203,7 +203,8 @@ struct rev_info {\n \t\t\tuse_terminator:1,\n \t\t\tmissing_newline:1,\n \t\t\tdate_mode_explicit:1,\n-\t\t\tpreserve_subject:1;\n+\t\t\tpreserve_subject:1,\n+\t\t\tencode_headers:1;\n \tunsigned int\tdisable_stdin:1;\n \t/* --show-linear-break */\n \tunsigned int\ttrack_linear:1,\ndiff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh\nindex b653dd7d44..d9c0fe7a45 100755\n--- a/t/t4014-format-patch.sh\n+++ b/t/t4014-format-patch.sh\n@@ -1160,6 +1160,59 @@ test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '\n \tcheck_author \"Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar\"\n '\n \n+cat >expect <<'EOF'\n+From: Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar\n+ Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo\n+ Bar Foo Bar Foo Bar Foo Bar <author@example.com>\n+EOF\n+test_expect_success 'format-patch wraps extremely long from-header (non-ASCII without Q-encoding)' '\n+\techo content >>file &&\n+\tgit add file &&\n+\tGIT_AUTHOR_NAME=\"Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar\" \\\n+\tgit commit -m author-check &&\n+\tgit format-patch --no-encode-headers --stdout -1 >patch &&\n+\tsed -n \"/^From: /p; /^ /p; /^$/q\" patch >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n+Subject: [PATCH] Foö\n+EOF\n+test_expect_success 'subject lines are unencoded with --no-encode-headers' '\n+\techo content >>file &&\n+\tgit add file &&\n+\tgit commit -m \"Foö\" &&\n+\tgit format-patch --no-encode-headers -1 --stdout >patch &&\n+\tgrep ^Subject: patch >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n+Subject: [PATCH] Foö\n+EOF\n+test_expect_success 'subject lines are unencoded with format.encodeHeaders=false' '\n+\techo content >>file &&\n+\tgit add file &&\n+\tgit commit -m \"Foö\" &&\n+\tgit config format.encodeHeaders false &&\n+\tgit format-patch -1 --stdout >patch &&\n+\tgrep ^Subject: patch >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n+Subject: [PATCH] =?UTF-8?q?Fo=C3=B6?=\n+EOF\n+test_expect_success '--encode-headers overrides format.encodeHeaders' '\n+\techo content >>file &&\n+\tgit add file &&\n+\tgit commit -m \"Foö\" &&\n+\tgit config format.encodeHeaders false &&\n+\tgit format-patch --encode-headers -1 --stdout >patch &&\n+\tgrep ^Subject: patch >actual &&\n+\ttest_cmp expect actual\n+'\n+\n cat >expect <<'EOF'\n Subject: header with . in it\n EOF\n"},{"id":"394818","messageId":"20200406030444.GG6369@camp.crustytoothpaste.net","threadId":"53167","inReplyTo":"20200405231109.8249-1-me@pluvano.com","subject":"Re: [PATCH] format-patch: teach --no-encode-headers","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2020-04-06T03:04:44Z","receivedAt":"2020-04-06T03:04:54Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2020-04-05 at 23:11:09, Emma Brooks wrote:\n> When commit subjects or authors have non-ASCII characters, git\n> format-patch Q-encodes them so they can be safely sent over email.\n> However, if the patch transfer method is something other than email (web\n> review tools, sneakernet), this only serves to make the patch metadata\n> harder to read without first applying it (unless you can decode RFC 2047\n> in your head). git am as well as some email software supports\n> non-Q-encoded mail as described in RFC 6531.\n\nDo we always output UTF-8 in this case, or do we sometimes output other\nencodings if the user has specified one for the commit message?  Do we\nknow how git send-email handles such a message if it receives one?\n\nI know it isn't your intention to work with git send-email in this\npatch, but it would be nice to know whether there's additional value in\nsomeone sending a followup patch to make git send-email use SMTPUTF8 if\nthat's necessary.\n-- \nbrian m. carlson: Houston, Texas, US\nOpenPGP: https://keybase.io/bk2204\n"},{"id":"394819","messageId":"xmqqd08lwatm.fsf@gitster.c.googlers.com","threadId":"53167","inReplyTo":"20200405231109.8249-1-me@pluvano.com","subject":"Re: [PATCH] format-patch: teach --no-encode-headers","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-04-06T03:29:57Z","receivedAt":"2020-04-06T03:30:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emma Brooks <me@pluvano.com> writes:\n\n> When commit subjects or authors have non-ASCII characters, git\n> format-patch Q-encodes them so they can be safely sent over email.\n> However, if the patch transfer method is something other than email (web\n> review tools, sneakernet), this only serves to make the patch metadata\n> harder to read without first applying it (unless you can decode RFC 2047\n> in your head). git am as well as some email software supports\n> non-Q-encoded mail as described in RFC 6531.\n>\n> Add --[no-]encode-headers and format.encodeHeaders to let the user\n> control this behavior.\n\nThis would be immensely useful.  I often find the in-body headers\nthat are Q-encoded too ugly to live.\n\nIs the RFC2047 the only thing we do to message headers?  What I am\ntrying is to figure out if \"encode-headers - yes/no?\" would be a\nstable (iow, would we be gaining other kinds of encoding over time?)\nand well-defined (iow, is there a case where one kind of 'encoding'\nis still desirable while disabling other kinds of 'encoding' is\nwanted?) question.  If there is any doubt in your answers to the\nabove question, we may have to make sure the name of the option\nmakes it clear to users what kind of encoding we're talking about.\n\n> +format.encodeHeaders::\n> +\tEncode email headers that have non-ASCII characters with\n> +\t\"Q-encoding\" for email transmission. Defaults to true.\n\nOK.\n\n>  \n> +--[no-]encode-headers::\n\nI think we'd want to standadize on writing these out, i.e.\n\n        --encode-headers::\n        --no-encode-headers::\n\nso let's follow that when adding a new option.\n\n> +\tEncode email headers that have non-ASCII characters with\n> +\t\"Q-encoding\", instead of outputting the headers verbatim. The\n\nI wonder if calling RFC2047 out helps readers here, when they wonder\nwhat Q is and how they can decipher it.\n\n> +\tdefault is `--encode-headers` unless the `format.encodeHeaders`\n> +\tconfiguration variable is set.\n\nI am wondering if we can go even shorter, e.g.\n\n\tThe default is set to the value of `format.encodeHeaders`\n\tconfiguration variable.\n\n> -\t\tif (needs_rfc2047_encoding(namebuf, namelen)) {\n> +\t\tif (pp->encode_headers &&\n> +\t\t\t\tneeds_rfc2047_encoding(namebuf, namelen)) {\n\nDon't overly indent the second line like this.  The same comment\napplies to the next hunk (not quoted).\n\nThanks.\n"},{"id":"394830","messageId":"20200406133040.GB1276@coredump.intra.peff.net","threadId":"53167","inReplyTo":"20200406030444.GG6369@camp.crustytoothpaste.net","subject":"Re: [PATCH] format-patch: teach --no-encode-headers","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2020-04-06T13:30:40Z","receivedAt":"2020-04-06T13:30:44Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Apr 06, 2020 at 03:04:44AM +0000, brian m. carlson wrote:\n\n> On 2020-04-05 at 23:11:09, Emma Brooks wrote:\n> > When commit subjects or authors have non-ASCII characters, git\n> > format-patch Q-encodes them so they can be safely sent over email.\n> > However, if the patch transfer method is something other than email (web\n> > review tools, sneakernet), this only serves to make the patch metadata\n> > harder to read without first applying it (unless you can decode RFC 2047\n> > in your head). git am as well as some email software supports\n> > non-Q-encoded mail as described in RFC 6531.\n> \n> Do we always output UTF-8 in this case, or do we sometimes output other\n> encodings if the user has specified one for the commit message?\n\nThat was my first question, too. But I think even without this option,\nwe always respect i18n.logOutputEncoding before we even hit the email\npretty-printing code. So by default it would always be utf8 (and\notherwise whatever the user has asked us to output).\n\nThat would obviously be disastrous for an output encoding that isn't an\nASCII superset, but that's already true for any of our output formats.\n\n> Do we know how git send-email handles such a message if it receives\n> one?\n> \n> I know it isn't your intention to work with git send-email in this\n> patch, but it would be nice to know whether there's additional value in\n> someone sending a followup patch to make git send-email use SMTPUTF8 if\n> that's necessary.\n\nI suspect this is mostly orthogonal, as that deals only with the\nSMTP-level addresses, which include only the actual email part (not the\nname) and aren't RFC2047-encoded anyway. It looks like we already leave\ncharacters in addresses untouched (I'm not even 100% sure that RFC2047\nallows modifying within the local part of an addr):\n\n  $echo foo >file\n  $ git add file\n  $ git -c user.email=péff@peff.net commit -m foo\n  $ git format-patch -1 --stdout | grep From:\n  From: Jeff King <péff@peff.net>\n\nI did wonder if there are any standards around 8bit headers. Certainly\nthe de facto standard for local tools (e.g., mutt reading a message\nyou've edited in vim) is that they can be treated like a stream of\nASCII-compatible bytes, and that works pretty well in practice. But if\nthere's an IETF-endorsed method for 8bit headers, it would be nice to\nuse it. For 8bit bodies, we're able to give a content-transfer-encoding\nand a content-type with the charset. But I don't know of an equivalent\nfor headers.\n\n-Peff\n"},{"id":"394844","messageId":"20200406151734.GH6369@camp.crustytoothpaste.net","threadId":"53167","inReplyTo":"20200406133040.GB1276@coredump.intra.peff.net","subject":"Re: [PATCH] format-patch: teach --no-encode-headers","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2020-04-06T15:17:34Z","receivedAt":"2020-04-06T15:17:42Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2020-04-06 at 13:30:40, Jeff King wrote:\n> I suspect this is mostly orthogonal, as that deals only with the\n> SMTP-level addresses, which include only the actual email part (not the\n> name) and aren't RFC2047-encoded anyway. It looks like we already leave\n> characters in addresses untouched (I'm not even 100% sure that RFC2047\n> allows modifying within the local part of an addr):\n> \n>   $echo foo >file\n>   $ git add file\n>   $ git -c user.email=péff@peff.net commit -m foo\n>   $ git format-patch -1 --stdout | grep From:\n>   From: Jeff King <péff@peff.net>\n> \n> I did wonder if there are any standards around 8bit headers. Certainly\n> the de facto standard for local tools (e.g., mutt reading a message\n> you've edited in vim) is that they can be treated like a stream of\n> ASCII-compatible bytes, and that works pretty well in practice. But if\n> there's an IETF-endorsed method for 8bit headers, it would be nice to\n> use it. For 8bit bodies, we're able to give a content-transfer-encoding\n> and a content-type with the charset. But I don't know of an equivalent\n> for headers.\n\nThat's RFC 6532, Internationalized Email Headers, the companion document\nto RFC 6531.  (The RFC editor has cleverly kept the last digits in sync\nbetween the RFC 532x and 653x series).\n\nThe basic summary is that header field names are not internationalized,\nbut the field values do allow UTF-8 if they contain unstructured text\n(e.g., Subject), anything using atoms (e.g., Message-ID), quoted strings\n(e.g., local-parts of an email address), domains, and a few other\nconstructs.  RFC 2047 (MIME encoded words) is allowed \"only in a subset\nof the places allowed by\" RFC 6532, so just not encoding should be safe\nhere, as long as it's UTF-8.\n-- \nbrian m. carlson: Houston, Texas, US\nOpenPGP: https://keybase.io/bk2204\n"},{"id":"394847","messageId":"20200406153028.GA14775@coredump.intra.peff.net","threadId":"53167","inReplyTo":"20200406151734.GH6369@camp.crustytoothpaste.net","subject":"Re: [PATCH] format-patch: teach --no-encode-headers","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2020-04-06T15:30:28Z","receivedAt":"2020-04-06T15:30:32Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Apr 06, 2020 at 03:17:34PM +0000, brian m. carlson wrote:\n\n> > I did wonder if there are any standards around 8bit headers. Certainly\n> > the de facto standard for local tools (e.g., mutt reading a message\n> > you've edited in vim) is that they can be treated like a stream of\n> > ASCII-compatible bytes, and that works pretty well in practice. But if\n> > there's an IETF-endorsed method for 8bit headers, it would be nice to\n> > use it. For 8bit bodies, we're able to give a content-transfer-encoding\n> > and a content-type with the charset. But I don't know of an equivalent\n> > for headers.\n> \n> That's RFC 6532, Internationalized Email Headers, the companion document\n> to RFC 6531.  (The RFC editor has cleverly kept the last digits in sync\n> between the RFC 532x and 653x series).\n\nAh, thanks, that's exactly what I was looking for.\n\n> The basic summary is that header field names are not internationalized,\n> but the field values do allow UTF-8 if they contain unstructured text\n> (e.g., Subject), anything using atoms (e.g., Message-ID), quoted strings\n> (e.g., local-parts of an email address), domains, and a few other\n> constructs.  RFC 2047 (MIME encoded words) is allowed \"only in a subset\n> of the places allowed by\" RFC 6532, so just not encoding should be safe\n> here, as long as it's UTF-8.\n\nThat makes sense. It looks like such messages are technically\nmessage/global rather than message/rfc822. But since there's no\ncontent-type given for the outermost message of an mbox, I guess that\njust becomes implied.\n\nThe utf8 thing means that doing:\n\n  git format-patch --encoding=iso8859-1 --no-encode-headers\n\nviolates the standard. But I think that's OK. If you really prefer that\ncharset for your local use, it does what you want. And if you try to\nsend it over SMTP and somebody complains, I think that falls under \"if\nit hurts, don't do that\".\n\n-Peff\n"},{"id":"394904","messageId":"20200407034622.GA42812@pluvano.com","threadId":"53167","inReplyTo":"xmqqd08lwatm.fsf@gitster.c.googlers.com","subject":"Re: [PATCH] format-patch: teach --no-encode-headers","fromName":"Emma Brooks","fromEmail":"me@pluvano.com","sentAt":"2020-04-07T03:46:22Z","receivedAt":"2020-04-07T03:46:49Z","isPatch":true,"sender":{"key":"me@pluvano.com","avatar":"https://avatars.githubusercontent.com/u/50312486?v=4"},"body":"On 2020-04-05 20:29:57-0700, Junio C Hamano wrote:\n> Is the RFC2047 the only thing we do to message headers?  What I am\n> trying is to figure out if \"encode-headers - yes/no?\" would be a\n> stable (iow, would we be gaining other kinds of encoding over time?)\n> and well-defined (iow, is there a case where one kind of 'encoding'\n> is still desirable while disabling other kinds of 'encoding' is\n> wanted?) question.  If there is any doubt in your answers to the\n> above question, we may have to make sure the name of the option\n> makes it clear to users what kind of encoding we're talking about.\n\nIt's also too vague and it's not entirely clear from the option itself\nwhat sort of encoding it refers to. I will change it to\n--[no-]q-encode-headers and format.qEncodeHeaders in v2 unless there are\nother suggestions.\n\n> > +--[no-]encode-headers::\n> \n> I think we'd want to standadize on writing these out, i.e.\n> \n>         --encode-headers::\n>         --no-encode-headers::\n> \n> so let's follow that when adding a new option.\n\nOK.\n\n> > +\tEncode email headers that have non-ASCII characters with\n> > +\t\"Q-encoding\", instead of outputting the headers verbatim. The\n> \n> I wonder if calling RFC2047 out helps readers here, when they wonder\n> what Q is and how they can decipher it.\n\nI'll reference the RFC directly in v2.\n\n> > +\tdefault is `--encode-headers` unless the `format.encodeHeaders`\n> > +\tconfiguration variable is set.\n> \n> I am wondering if we can go even shorter, e.g.\n> \n> \tThe default is set to the value of `format.encodeHeaders`\n> \tconfiguration variable.\n\nOK, I'll go with that.\n\n> > -\t\tif (needs_rfc2047_encoding(namebuf, namelen)) {\n> > +\t\tif (pp->encode_headers &&\n> > +\t\t\t\tneeds_rfc2047_encoding(namebuf, namelen)) {\n> \n> Don't overly indent the second line like this.  The same comment\n> applies to the next hunk (not quoted).\n> \n> Thanks.\n\nOK.\n"},{"id":"394906","messageId":"20200407051745.44390-1-me@pluvano.com","threadId":"53167","inReplyTo":"20200405231109.8249-1-me@pluvano.com","subject":"[PATCH v2] format-patch: teach --no-q-encode-headers","fromName":"Emma Brooks","fromEmail":"me@pluvano.com","sentAt":"2020-04-07T05:17:45Z","receivedAt":"2020-04-07T05:18:56Z","isPatch":true,"sender":{"key":"me@pluvano.com","avatar":"https://avatars.githubusercontent.com/u/50312486?v=4"},"body":"When commit subjects or authors have non-ASCII characters, git\nformat-patch Q-encodes them so they can be safely sent over email.\nHowever, if the patch transfer method is something other than email (web\nreview tools, sneakernet), this only serves to make the patch metadata\nharder to read without first applying it (unless you can decode RFC 2047\nin your head). git am as well as some email software supports\nnon-Q-encoded mail as described in RFC 6531.\n\nAdd --[no-]q-encode-headers and format.qEncodeHeaders to let the user\ncontrol this behavior.\n\nSigned-off-by: Emma Brooks <me@pluvano.com>\n---\n\nChanges since v1:\n\n- Rename --encode-headers to --q-encode-headers\n- Rename format.encodeHeaders to format.qEncodeHeaders\n- Simplify language in docs\n- Reel in over-indented lines\n\n Documentation/config/format.txt    |  4 +++\n Documentation/git-format-patch.txt |  8 +++++\n builtin/log.c                      |  7 ++++\n log-tree.c                         |  1 +\n pretty.c                           |  6 ++--\n pretty.h                           |  1 +\n revision.c                         |  4 +++\n revision.h                         |  3 +-\n t/t4014-format-patch.sh            | 53 ++++++++++++++++++++++++++++++\n 9 files changed, 84 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config/format.txt b/Documentation/config/format.txt\nindex 45c7bd5a8f..9b0d665d27 100644\n--- a/Documentation/config/format.txt\n+++ b/Documentation/config/format.txt\n@@ -57,6 +57,10 @@ format.suffix::\n \t`.patch`. Use this variable to change that suffix (make sure to\n \tinclude the dot if you want it).\n \n+format.qEncodeHeaders::\n+\tEncode email headers that have non-ASCII characters with\n+\t\"Q-encoding\" for email transmission. Defaults to true.\n+\n format.pretty::\n \tThe default pretty format for log/show/whatchanged command,\n \tSee linkgit:git-log[1], linkgit:git-show[1],\ndiff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\nindex 0d4f8951bb..13de39a27c 100644\n--- a/Documentation/git-format-patch.txt\n+++ b/Documentation/git-format-patch.txt\n@@ -24,6 +24,7 @@ SYNOPSIS\n \t\t   [(--reroll-count|-v) <n>]\n \t\t   [--to=<email>] [--cc=<email>]\n \t\t   [--[no-]cover-letter] [--quiet]\n+\t\t   [--[no-]q-encode-headers]\n \t\t   [--no-notes | --notes[=<ref>]]\n \t\t   [--interdiff=<previous>]\n \t\t   [--range-diff=<previous> [--creation-factor=<percent>]]\n@@ -253,6 +254,13 @@ feeding the result to `git send-email`.\n \tcontaining the branch description, shortlog and the overall diffstat.  You can\n \tfill in a description in the file before sending it out.\n \n+--q-encode-headers::\n+--no-q-encode-headers::\n+\tEncode email headers that have non-ASCII characters with\n+\t\"Q-encoding\" (described in RFC 2047), instead of outputting the\n+\theaders verbatim. The default is set to the value of the\n+\t`format.qEncodeHeaders` configuration variable.\n+\n --interdiff=<previous>::\n \tAs a reviewer aid, insert an interdiff into the cover letter,\n \tor as commentary of the lone patch of a 1-patch series, showing\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 83a4a6188e..ea63902b82 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -46,6 +46,7 @@ static int default_abbrev_commit;\n static int default_show_root = 1;\n static int default_follow;\n static int default_show_signature;\n+static int default_q_encode_headers = 1;\n static int decoration_style;\n static int decoration_given;\n static int use_mailmap_config = 1;\n@@ -151,6 +152,7 @@ static void cmd_log_init_defaults(struct rev_info *rev)\n \trev->show_root_diff = default_show_root;\n \trev->subject_prefix = fmt_patch_subject_prefix;\n \trev->show_signature = default_show_signature;\n+\trev->q_encode_headers = default_q_encode_headers;\n \trev->diffopt.flags.allow_textconv = 1;\n \n \tif (default_date_mode)\n@@ -438,6 +440,10 @@ static int git_log_config(const char *var, const char *value, void *cb)\n \t\treturn git_config_string(&fmt_pretty, var, value);\n \tif (!strcmp(var, \"format.subjectprefix\"))\n \t\treturn git_config_string(&fmt_patch_subject_prefix, var, value);\n+\tif (!strcmp(var, \"format.qencodeheaders\")) {\n+\t\tdefault_q_encode_headers = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n \tif (!strcmp(var, \"log.abbrevcommit\")) {\n \t\tdefault_abbrev_commit = git_config_bool(var, value);\n \t\treturn 0;\n@@ -1719,6 +1725,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \trev.show_notes = show_notes;\n \tmemcpy(&rev.notes_opt, &notes_opt, sizeof(notes_opt));\n \trev.commit_format = CMIT_FMT_EMAIL;\n+\trev.q_encode_headers = default_q_encode_headers;\n \trev.expand_tabs_in_log_default = 0;\n \trev.verbose_header = 1;\n \trev.diff = 1;\ndiff --git a/log-tree.c b/log-tree.c\nindex 897a90233e..fb37149854 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -693,6 +693,7 @@ void show_log(struct rev_info *opt)\n \tctx.abbrev = opt->diffopt.abbrev;\n \tctx.after_subject = extra_headers;\n \tctx.preserve_subject = opt->preserve_subject;\n+\tctx.q_encode_headers = opt->q_encode_headers;\n \tctx.reflog_info = opt->reflog_info;\n \tctx.fmt = opt->commit_format;\n \tctx.mailmap = opt->mailmap;\ndiff --git a/pretty.c b/pretty.c\nindex 28afc701b6..3ae52cc9db 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -474,7 +474,8 @@ void pp_user_info(struct pretty_print_context *pp,\n \t\t}\n \n \t\tstrbuf_addstr(sb, \"From: \");\n-\t\tif (needs_rfc2047_encoding(namebuf, namelen)) {\n+\t\tif (pp->q_encode_headers &&\n+\t\t    needs_rfc2047_encoding(namebuf, namelen)) {\n \t\t\tadd_rfc2047(sb, namebuf, namelen,\n \t\t\t\t    encoding, RFC2047_ADDRESS);\n \t\t\tmax_length = 76; /* per rfc2047 */\n@@ -1767,7 +1768,8 @@ void pp_title_line(struct pretty_print_context *pp,\n \tif (pp->print_email_subject) {\n \t\tif (pp->rev)\n \t\t\tfmt_output_email_subject(sb, pp->rev);\n-\t\tif (needs_rfc2047_encoding(title.buf, title.len))\n+\t\tif (pp->q_encode_headers &&\n+\t\t    needs_rfc2047_encoding(title.buf, title.len))\n \t\t\tadd_rfc2047(sb, title.buf, title.len,\n \t\t\t\t\t\tencoding, RFC2047_SUBJECT);\n \t\telse\ndiff --git a/pretty.h b/pretty.h\nindex 4ad1fc31ff..e40b6d3e83 100644\n--- a/pretty.h\n+++ b/pretty.h\n@@ -43,6 +43,7 @@ struct pretty_print_context {\n \tstruct string_list *mailmap;\n \tint color;\n \tstruct ident_split *from_ident;\n+\tunsigned q_encode_headers:1;\n \n \t/*\n \t * Fields below here are manipulated internally by pp_* functions and\ndiff --git a/revision.c b/revision.c\nindex 8136929e23..51d3e8a558 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -2241,6 +2241,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg\n \t\trevs->topo_order = 1;\n \t\trevs->rewrite_parents = 1;\n \t\trevs->graph = graph_init(revs);\n+\t} else if (!strcmp(arg, \"--q-encode-headers\")) {\n+\t\trevs->q_encode_headers = 1;\n+\t} else if (!strcmp(arg, \"--no-q-encode-headers\")) {\n+\t\trevs->q_encode_headers = 0;\n \t} else if (!strcmp(arg, \"--root\")) {\n \t\trevs->show_root_diff = 1;\n \t} else if (!strcmp(arg, \"--no-commit-id\")) {\ndiff --git a/revision.h b/revision.h\nindex 475f048fb6..4794aa4742 100644\n--- a/revision.h\n+++ b/revision.h\n@@ -203,7 +203,8 @@ struct rev_info {\n \t\t\tuse_terminator:1,\n \t\t\tmissing_newline:1,\n \t\t\tdate_mode_explicit:1,\n-\t\t\tpreserve_subject:1;\n+\t\t\tpreserve_subject:1,\n+\t\t\tq_encode_headers:1;\n \tunsigned int\tdisable_stdin:1;\n \t/* --show-linear-break */\n \tunsigned int\ttrack_linear:1,\ndiff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh\nindex b653dd7d44..9f780b8fe8 100755\n--- a/t/t4014-format-patch.sh\n+++ b/t/t4014-format-patch.sh\n@@ -1160,6 +1160,59 @@ test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '\n \tcheck_author \"Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar\"\n '\n \n+cat >expect <<'EOF'\n+From: Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar\n+ Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo\n+ Bar Foo Bar Foo Bar Foo Bar <author@example.com>\n+EOF\n+test_expect_success 'format-patch wraps extremely long from-header (non-ASCII without Q-encoding)' '\n+\techo content >>file &&\n+\tgit add file &&\n+\tGIT_AUTHOR_NAME=\"Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar\" \\\n+\tgit commit -m author-check &&\n+\tgit format-patch --no-q-encode-headers --stdout -1 >patch &&\n+\tsed -n \"/^From: /p; /^ /p; /^$/q\" patch >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n+Subject: [PATCH] Foö\n+EOF\n+test_expect_success 'subject lines are unencoded with --no-q-encode-headers' '\n+\techo content >>file &&\n+\tgit add file &&\n+\tgit commit -m \"Foö\" &&\n+\tgit format-patch --no-q-encode-headers -1 --stdout >patch &&\n+\tgrep ^Subject: patch >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n+Subject: [PATCH] Foö\n+EOF\n+test_expect_success 'subject lines are unencoded with format.qEncodeHeaders=false' '\n+\techo content >>file &&\n+\tgit add file &&\n+\tgit commit -m \"Foö\" &&\n+\tgit config format.qEncodeHeaders false &&\n+\tgit format-patch -1 --stdout >patch &&\n+\tgrep ^Subject: patch >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n+Subject: [PATCH] =?UTF-8?q?Fo=C3=B6?=\n+EOF\n+test_expect_success '--q-encode-headers overrides format.qEncodeHeaders' '\n+\techo content >>file &&\n+\tgit add file &&\n+\tgit commit -m \"Foö\" &&\n+\tgit config format.qEncodeHeaders false &&\n+\tgit format-patch --q-encode-headers -1 --stdout >patch &&\n+\tgrep ^Subject: patch >actual &&\n+\ttest_cmp expect actual\n+'\n+\n cat >expect <<'EOF'\n Subject: header with . in it\n EOF\n"},{"id":"394908","messageId":"20200407074031.GA20612@danh.dev","threadId":"53167","inReplyTo":"20200407051745.44390-1-me@pluvano.com","subject":"Re: [PATCH v2] format-patch: teach --no-q-encode-headers","fromName":"Danh Doan","fromEmail":"congdanhqx@gmail.com","sentAt":"2020-04-07T07:40:31Z","receivedAt":"2020-04-07T07:40:38Z","isPatch":true,"sender":{"key":"congdanhqx@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42673067?v=4"},"body":"On 2020-04-07 05:17:45+0000, Emma Brooks <me@pluvano.com> wrote:\n> When commit subjects or authors have non-ASCII characters, git\n> format-patch Q-encodes them so they can be safely sent over email.\n> However, if the patch transfer method is something other than email (web\n> review tools, sneakernet), this only serves to make the patch metadata\n> harder to read without first applying it (unless you can decode RFC 2047\n> in your head). git am as well as some email software supports\n> non-Q-encoded mail as described in RFC 6531.\n> \n> Add --[no-]q-encode-headers and format.qEncodeHeaders to let the user\n> control this behavior.\n> \n> Signed-off-by: Emma Brooks <me@pluvano.com>\n> ---\n> \n> Changes since v1:\n> \n> - Rename --encode-headers to --q-encode-headers\n> - Rename format.encodeHeaders to format.qEncodeHeaders\n> - Simplify language in docs\n> - Reel in over-indented lines\n> \n>  Documentation/config/format.txt    |  4 +++\n>  Documentation/git-format-patch.txt |  8 +++++\n>  builtin/log.c                      |  7 ++++\n>  log-tree.c                         |  1 +\n>  pretty.c                           |  6 ++--\n>  pretty.h                           |  1 +\n>  revision.c                         |  4 +++\n>  revision.h                         |  3 +-\n>  t/t4014-format-patch.sh            | 53 ++++++++++++++++++++++++++++++\n>  9 files changed, 84 insertions(+), 3 deletions(-)\n> \n> diff --git a/Documentation/config/format.txt b/Documentation/config/format.txt\n> index 45c7bd5a8f..9b0d665d27 100644\n> --- a/Documentation/config/format.txt\n> +++ b/Documentation/config/format.txt\n> @@ -57,6 +57,10 @@ format.suffix::\n>  \t`.patch`. Use this variable to change that suffix (make sure to\n>  \tinclude the dot if you want it).\n>  \n> +format.qEncodeHeaders::\n> +\tEncode email headers that have non-ASCII characters with\n> +\t\"Q-encoding\" for email transmission. Defaults to true.\n\nI think have (described in RFC 2047) as same as\n--[no]-q-encode-headers belows would be better.\n\n> +\n>  format.pretty::\n>  \tThe default pretty format for log/show/whatchanged command,\n>  \tSee linkgit:git-log[1], linkgit:git-show[1],\n> diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\n> index 0d4f8951bb..13de39a27c 100644\n> --- a/Documentation/git-format-patch.txt\n> +++ b/Documentation/git-format-patch.txt\n> @@ -24,6 +24,7 @@ SYNOPSIS\n>  \t\t   [(--reroll-count|-v) <n>]\n>  \t\t   [--to=<email>] [--cc=<email>]\n>  \t\t   [--[no-]cover-letter] [--quiet]\n> +\t\t   [--[no-]q-encode-headers]\n>  \t\t   [--no-notes | --notes[=<ref>]]\n>  \t\t   [--interdiff=<previous>]\n>  \t\t   [--range-diff=<previous> [--creation-factor=<percent>]]\n> @@ -253,6 +254,13 @@ feeding the result to `git send-email`.\n>  \tcontaining the branch description, shortlog and the overall diffstat.  You can\n>  \tfill in a description in the file before sending it out.\n>  \n> +--q-encode-headers::\n> +--no-q-encode-headers::\n> +\tEncode email headers that have non-ASCII characters with\n> +\t\"Q-encoding\" (described in RFC 2047), instead of outputting the\n> +\theaders verbatim. The default is set to the value of the\n> +\t`format.qEncodeHeaders` configuration variable.\n\nI find this paragraph hard to understand.\nI think:\n\n\tIf this option is omited, set to value of of ...\n\nis easier to understand (to me, at least).\n\n> +\n>  --interdiff=<previous>::\n>  \tAs a reviewer aid, insert an interdiff into the cover letter,\n>  \tor as commentary of the lone patch of a 1-patch series, showing\n> diff --git a/builtin/log.c b/builtin/log.c\n> index 83a4a6188e..ea63902b82 100644\n> --- a/builtin/log.c\n> +++ b/builtin/log.c\n> @@ -46,6 +46,7 @@ static int default_abbrev_commit;\n>  static int default_show_root = 1;\n>  static int default_follow;\n>  static int default_show_signature;\n> +static int default_q_encode_headers = 1;\n>  static int decoration_style;\n>  static int decoration_given;\n>  static int use_mailmap_config = 1;\n> @@ -151,6 +152,7 @@ static void cmd_log_init_defaults(struct rev_info *rev)\n>  \trev->show_root_diff = default_show_root;\n>  \trev->subject_prefix = fmt_patch_subject_prefix;\n>  \trev->show_signature = default_show_signature;\n> +\trev->q_encode_headers = default_q_encode_headers;\n>  \trev->diffopt.flags.allow_textconv = 1;\n>  \n>  \tif (default_date_mode)\n> @@ -438,6 +440,10 @@ static int git_log_config(const char *var, const char *value, void *cb)\n>  \t\treturn git_config_string(&fmt_pretty, var, value);\n>  \tif (!strcmp(var, \"format.subjectprefix\"))\n>  \t\treturn git_config_string(&fmt_patch_subject_prefix, var, value);\n> +\tif (!strcmp(var, \"format.qencodeheaders\")) {\n> +\t\tdefault_q_encode_headers = git_config_bool(var, value);\n> +\t\treturn 0;\n> +\t}\n>  \tif (!strcmp(var, \"log.abbrevcommit\")) {\n>  \t\tdefault_abbrev_commit = git_config_bool(var, value);\n>  \t\treturn 0;\n> @@ -1719,6 +1725,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n>  \trev.show_notes = show_notes;\n>  \tmemcpy(&rev.notes_opt, &notes_opt, sizeof(notes_opt));\n>  \trev.commit_format = CMIT_FMT_EMAIL;\n> +\trev.q_encode_headers = default_q_encode_headers;\n>  \trev.expand_tabs_in_log_default = 0;\n>  \trev.verbose_header = 1;\n>  \trev.diff = 1;\n> diff --git a/log-tree.c b/log-tree.c\n> index 897a90233e..fb37149854 100644\n> --- a/log-tree.c\n> +++ b/log-tree.c\n> @@ -693,6 +693,7 @@ void show_log(struct rev_info *opt)\n>  \tctx.abbrev = opt->diffopt.abbrev;\n>  \tctx.after_subject = extra_headers;\n>  \tctx.preserve_subject = opt->preserve_subject;\n> +\tctx.q_encode_headers = opt->q_encode_headers;\n>  \tctx.reflog_info = opt->reflog_info;\n>  \tctx.fmt = opt->commit_format;\n>  \tctx.mailmap = opt->mailmap;\n> diff --git a/pretty.c b/pretty.c\n> index 28afc701b6..3ae52cc9db 100644\n> --- a/pretty.c\n> +++ b/pretty.c\n> @@ -474,7 +474,8 @@ void pp_user_info(struct pretty_print_context *pp,\n>  \t\t}\n>  \n>  \t\tstrbuf_addstr(sb, \"From: \");\n> -\t\tif (needs_rfc2047_encoding(namebuf, namelen)) {\n> +\t\tif (pp->q_encode_headers &&\n> +\t\t    needs_rfc2047_encoding(namebuf, namelen)) {\n>  \t\t\tadd_rfc2047(sb, namebuf, namelen,\n>  \t\t\t\t    encoding, RFC2047_ADDRESS);\n>  \t\t\tmax_length = 76; /* per rfc2047 */\n> @@ -1767,7 +1768,8 @@ void pp_title_line(struct pretty_print_context *pp,\n>  \tif (pp->print_email_subject) {\n>  \t\tif (pp->rev)\n>  \t\t\tfmt_output_email_subject(sb, pp->rev);\n> -\t\tif (needs_rfc2047_encoding(title.buf, title.len))\n> +\t\tif (pp->q_encode_headers &&\n> +\t\t    needs_rfc2047_encoding(title.buf, title.len))\n>  \t\t\tadd_rfc2047(sb, title.buf, title.len,\n>  \t\t\t\t\t\tencoding, RFC2047_SUBJECT);\n>  \t\telse\n> diff --git a/pretty.h b/pretty.h\n> index 4ad1fc31ff..e40b6d3e83 100644\n> --- a/pretty.h\n> +++ b/pretty.h\n> @@ -43,6 +43,7 @@ struct pretty_print_context {\n>  \tstruct string_list *mailmap;\n>  \tint color;\n>  \tstruct ident_split *from_ident;\n> +\tunsigned q_encode_headers:1;\n>  \n>  \t/*\n>  \t * Fields below here are manipulated internally by pp_* functions and\n> diff --git a/revision.c b/revision.c\n> index 8136929e23..51d3e8a558 100644\n> --- a/revision.c\n> +++ b/revision.c\n> @@ -2241,6 +2241,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg\n>  \t\trevs->topo_order = 1;\n>  \t\trevs->rewrite_parents = 1;\n>  \t\trevs->graph = graph_init(revs);\n> +\t} else if (!strcmp(arg, \"--q-encode-headers\")) {\n> +\t\trevs->q_encode_headers = 1;\n> +\t} else if (!strcmp(arg, \"--no-q-encode-headers\")) {\n> +\t\trevs->q_encode_headers = 0;\n>  \t} else if (!strcmp(arg, \"--root\")) {\n>  \t\trevs->show_root_diff = 1;\n>  \t} else if (!strcmp(arg, \"--no-commit-id\")) {\n> diff --git a/revision.h b/revision.h\n> index 475f048fb6..4794aa4742 100644\n> --- a/revision.h\n> +++ b/revision.h\n> @@ -203,7 +203,8 @@ struct rev_info {\n>  \t\t\tuse_terminator:1,\n>  \t\t\tmissing_newline:1,\n>  \t\t\tdate_mode_explicit:1,\n> -\t\t\tpreserve_subject:1;\n> +\t\t\tpreserve_subject:1,\n> +\t\t\tq_encode_headers:1;\n>  \tunsigned int\tdisable_stdin:1;\n>  \t/* --show-linear-break */\n>  \tunsigned int\ttrack_linear:1,\n> diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh\n> index b653dd7d44..9f780b8fe8 100755\n> --- a/t/t4014-format-patch.sh\n> +++ b/t/t4014-format-patch.sh\n> @@ -1160,6 +1160,59 @@ test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '\n>  \tcheck_author \"Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar\"\n>  '\n>  \n> +cat >expect <<'EOF'\n> +From: Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar\n> + Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo\n> + Bar Foo Bar Foo Bar Foo Bar <author@example.com>\n> +EOF\n> +test_expect_success 'format-patch wraps extremely long from-header (non-ASCII without Q-encoding)' '\n> +\techo content >>file &&\n> +\tgit add file &&\n> +\tGIT_AUTHOR_NAME=\"Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar\" \\\n> +\tgit commit -m author-check &&\n> +\tgit format-patch --no-q-encode-headers --stdout -1 >patch &&\n> +\tsed -n \"/^From: /p; /^ /p; /^$/q\" patch >actual &&\n> +\ttest_cmp expect actual\n> +'\n> +\n> +cat >expect <<'EOF'\n> +Subject: [PATCH] Foö\n> +EOF\n\nIn most of tests, we use this here doc inside the test instead of\nglobal scope.\n\nOnly in this file and a minority others, this style is used.\n\nI'm not sure which one is prefered,\nmaybe Junio can decide.\n\n> +test_expect_success 'subject lines are unencoded with --no-q-encode-headers' '\n> +\techo content >>file &&\n> +\tgit add file &&\n> +\tgit commit -m \"Foö\" &&\n\nIIUC, test_commit is prefered to those above 3 lines.\n\n> +\tgit format-patch --no-q-encode-headers -1 --stdout >patch &&\n> +\tgrep ^Subject: patch >actual &&\n> +\ttest_cmp expect actual\n> +'\n> +\n> +cat >expect <<'EOF'\n> +Subject: [PATCH] Foö\n> +EOF\n> +test_expect_success 'subject lines are unencoded with format.qEncodeHeaders=false' '\n> +\techo content >>file &&\n> +\tgit add file &&\n> +\tgit commit -m \"Foö\" &&\n> +\tgit config format.qEncodeHeaders false &&\n> +\tgit format-patch -1 --stdout >patch &&\n> +\tgrep ^Subject: patch >actual &&\n> +\ttest_cmp expect actual\n> +'\n> +\n> +cat >expect <<'EOF'\n> +Subject: [PATCH] =?UTF-8?q?Fo=C3=B6?=\n> +EOF\n> +test_expect_success '--q-encode-headers overrides format.qEncodeHeaders' '\n> +\techo content >>file &&\n> +\tgit add file &&\n> +\tgit commit -m \"Foö\" &&\n> +\tgit config format.qEncodeHeaders false &&\n> +\tgit format-patch --q-encode-headers -1 --stdout >patch &&\n> +\tgrep ^Subject: patch >actual &&\n> +\ttest_cmp expect actual\n> +'\n> +\n>  cat >expect <<'EOF'\n>  Subject: header with . in it\n>  EOF\n\n-- \nDanh\n"},{"id":"394998","messageId":"xmqq8sj7t7d0.fsf@gitster.c.googlers.com","threadId":"53167","inReplyTo":"20200407034622.GA42812@pluvano.com","subject":"Re: [PATCH] format-patch: teach --no-encode-headers","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-04-07T19:37:31Z","receivedAt":"2020-04-07T19:37:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emma Brooks <me@pluvano.com> writes:\n\n> It's also too vague and it's not entirely clear from the option itself\n> what sort of encoding it refers to. I will change it to\n> --[no-]q-encode-headers and format.qEncodeHeaders in v2 unless there are\n> other suggestions.\n\nI actually did not mean to push you into that direction.  We can,\nand do want to, keep the most generic \"--[no-]encode-headers\" if we\ndo not anticipate us wanting to special case the Q encoding.  A\nsample question to ask is \"would it make sense to disable q-encoding\nbut still perform other parts of 'encode headers'?\"  I haven't\nthought deeply about such questions, but as a proposer of this\ntopic, you would certainly have, and I was hoping that you'd say\nthings like \"Q-encoding is the only thing that we do to munge\nheaders, so there aren't any 'other parts of encoding headers' we\nneed to worry about\", \"there are things like X, Y and Z that we do\nto the headers when we enable Q-encoding, but they all are what we\ndo not want when we do not want the Q-encoding\", which would be a\nvery good sign that assures us that \"--[no-]encode-headers\" is a\ngood name.\n\nThanks.\n"},{"id":"395005","messageId":"20200407203111.GA1936475@coredump.intra.peff.net","threadId":"53167","inReplyTo":"xmqq8sj7t7d0.fsf@gitster.c.googlers.com","subject":"Re: [PATCH] format-patch: teach --no-encode-headers","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2020-04-07T20:31:11Z","receivedAt":"2020-04-07T20:31:15Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Apr 07, 2020 at 12:37:31PM -0700, Junio C Hamano wrote:\n\n> Emma Brooks <me@pluvano.com> writes:\n> \n> > It's also too vague and it's not entirely clear from the option itself\n> > what sort of encoding it refers to. I will change it to\n> > --[no-]q-encode-headers and format.qEncodeHeaders in v2 unless there are\n> > other suggestions.\n> \n> I actually did not mean to push you into that direction.  We can,\n> and do want to, keep the most generic \"--[no-]encode-headers\" if we\n> do not anticipate us wanting to special case the Q encoding.  A\n> sample question to ask is \"would it make sense to disable q-encoding\n> but still perform other parts of 'encode headers'?\"  I haven't\n> thought deeply about such questions, but as a proposer of this\n> topic, you would certainly have, and I was hoping that you'd say\n> things like \"Q-encoding is the only thing that we do to munge\n> headers, so there aren't any 'other parts of encoding headers' we\n> need to worry about\", \"there are things like X, Y and Z that we do\n> to the headers when we enable Q-encoding, but they all are what we\n> do not want when we do not want the Q-encoding\", which would be a\n> very good sign that assures us that \"--[no-]encode-headers\" is a\n> good name.\n\nI thought we might b-encode some headers, but couldn't find any code to\ndo so (after about 5 minutes of looking).\n\nHowever, this new option isn't just for format-patch. It is available\nfor all revision walkers (as it should be; I can say \"log\n--format=email\" and I might want to use it there). And there \"headers\"\nis less clear that we are talking about email headers, and not other\nobject headers (e.g., that you might see with --format=raw).\n\nSaying \"--no-rfc2047-encoding\" would be more descriptive to _me_, but I\nwonder if people not so familiar with the standards would find it a bit\nobscure. Another option is to invert it to \"--8bit-email-headers\" or\nsomething.\n\n-Peff\n"},{"id":"395018","messageId":"xmqq8sj7rl85.fsf@gitster.c.googlers.com","threadId":"53167","inReplyTo":"20200407203111.GA1936475@coredump.intra.peff.net","subject":"Re: [PATCH] format-patch: teach --no-encode-headers","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-04-07T22:20:58Z","receivedAt":"2020-04-07T22:21:07Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> Saying \"--no-rfc2047-encoding\" would be more descriptive to _me_, but I\n> wonder if people not so familiar with the standards would find it a bit\n> obscure. Another option is to invert it to \"--8bit-email-headers\" or\n> something.\n\nYup, having \"rfc2047\" in the name of the option was one of the\nthings I considered suggesting, but I didn't for the same reason.  I\nam OK with \"--[no-]8bit-email-headers\" (when --8bit, rfc2047 is\nskipped).  Or \"--[no-]email-header-encoding\".\n\nThanks.\n"},{"id":"395043","messageId":"20200408035720.GA25740@pluvano.com","threadId":"53167","inReplyTo":"20200407074031.GA20612@danh.dev","subject":"Re: [PATCH v2] format-patch: teach --no-q-encode-headers","fromName":"Emma Brooks","fromEmail":"me@pluvano.com","sentAt":"2020-04-08T03:57:20Z","receivedAt":"2020-04-08T03:57:49Z","isPatch":true,"sender":{"key":"me@pluvano.com","avatar":"https://avatars.githubusercontent.com/u/50312486?v=4"},"body":"On 2020-04-07 14:40:31+0700, Danh Doan wrote:\n> > +format.qEncodeHeaders::\n> > +\tEncode email headers that have non-ASCII characters with\n> > +\t\"Q-encoding\" for email transmission. Defaults to true.\n> \n> I think have (described in RFC 2047) as same as\n> --[no]-q-encode-headers belows would be better.\n\nAgreed. I will reference it there as well.\n\n> > +--q-encode-headers::\n> > +--no-q-encode-headers::\n> > +\tEncode email headers that have non-ASCII characters with\n> > +\t\"Q-encoding\" (described in RFC 2047), instead of outputting the\n> > +\theaders verbatim. The default is set to the value of the\n> > +\t`format.qEncodeHeaders` configuration variable.\n> \n> I find this paragraph hard to understand.\n> I think:\n> \n> \tIf this option is omited, set to value of of ...\n> \n> is easier to understand (to me, at least).\n\nOK, I will simplify the language in v3.\n"},{"id":"395059","messageId":"20200408040746.GA41187@pluvano.com","threadId":"53167","inReplyTo":"xmqq8sj7t7d0.fsf@gitster.c.googlers.com","subject":"Re: [PATCH] format-patch: teach --no-encode-headers","fromName":"Emma Brooks","fromEmail":"me@pluvano.com","sentAt":"2020-04-08T04:08:04Z","receivedAt":"2020-04-08T04:08:34Z","isPatch":true,"sender":{"key":"me@pluvano.com","avatar":"https://avatars.githubusercontent.com/u/50312486?v=4"},"body":"On 2020-04-07 12:37:31-0700, Junio C Hamano wrote:\n> Emma Brooks <me@pluvano.com> writes:\n> \n> > It's also too vague and it's not entirely clear from the option itself\n> > what sort of encoding it refers to. I will change it to\n> > --[no-]q-encode-headers and format.qEncodeHeaders in v2 unless there are\n> > other suggestions.\n> \n> I actually did not mean to push you into that direction.  We can,\n> and do want to, keep the most generic \"--[no-]encode-headers\" if we\n> do not anticipate us wanting to special case the Q encoding.  A\n> sample question to ask is \"would it make sense to disable q-encoding\n> but still perform other parts of 'encode headers'?\"  I haven't\n> thought deeply about such questions, but as a proposer of this\n> topic, you would certainly have, and I was hoping that you'd say\n> things like \"Q-encoding is the only thing that we do to munge\n> headers, so there aren't any 'other parts of encoding headers' we\n> need to worry about\", \"there are things like X, Y and Z that we do\n> to the headers when we enable Q-encoding, but they all are what we\n> do not want when we do not want the Q-encoding\", which would be a\n> very good sign that assures us that \"--[no-]encode-headers\" is a\n> good name.\n\nAh. I don't think there are any cases where we do other sorts of\nencoding, or want to enable one \"part\" of encoding and disable another.\nI do think the name need to be more obviously about *email* headers as\nJeff pointed out, though.\n"},{"id":"395060","messageId":"20200408043138.42226-1-me@pluvano.com","threadId":"53167","inReplyTo":"20200407051745.44390-1-me@pluvano.com","subject":"[PATCH v3] format-patch: teach --no-encode-email-headers","fromName":"Emma Brooks","fromEmail":"me@pluvano.com","sentAt":"2020-04-08T04:31:38Z","receivedAt":"2020-04-08T04:34:05Z","isPatch":true,"sender":{"key":"me@pluvano.com","avatar":"https://avatars.githubusercontent.com/u/50312486?v=4"},"body":"When commit subjects or authors have non-ASCII characters, git\nformat-patch Q-encodes them so they can be safely sent over email.\nHowever, if the patch transfer method is something other than email (web\nreview tools, sneakernet), this only serves to make the patch metadata\nharder to read without first applying it (unless you can decode RFC 2047\nin your head). git am as well as some email software supports\nnon-Q-encoded mail as described in RFC 6531.\n\nAdd --[no-]encode-email-headers and format.encodeEmailHeaders to let the\nuser control this behavior.\n\nSigned-off-by: Emma Brooks <me@pluvano.com>\n---\n\nChanges since v2:\n\n- Rename options to to --[no-]encode-email-headers /\n  format.encodeEmailHeaders so it's clear they refer to email headers.\n- Reference RFC 2047 in config docs too\n- Simplify language in docs more\n\n Documentation/config/format.txt    |  5 +++\n Documentation/git-format-patch.txt |  8 +++++\n builtin/log.c                      |  7 ++++\n log-tree.c                         |  1 +\n pretty.c                           |  6 ++--\n pretty.h                           |  1 +\n revision.c                         |  4 +++\n revision.h                         |  3 +-\n t/t4014-format-patch.sh            | 53 ++++++++++++++++++++++++++++++\n 9 files changed, 85 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/config/format.txt b/Documentation/config/format.txt\nindex 45c7bd5a8f..564e8091ba 100644\n--- a/Documentation/config/format.txt\n+++ b/Documentation/config/format.txt\n@@ -57,6 +57,11 @@ format.suffix::\n \t`.patch`. Use this variable to change that suffix (make sure to\n \tinclude the dot if you want it).\n \n+format.encodeEmailHeaders::\n+\tEncode email headers that have non-ASCII characters with\n+\t\"Q-encoding\" (described in RFC 2047) for email transmission.\n+\tDefaults to true.\n+\n format.pretty::\n \tThe default pretty format for log/show/whatchanged command,\n \tSee linkgit:git-log[1], linkgit:git-show[1],\ndiff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt\nindex 0d4f8951bb..0f81d0437b 100644\n--- a/Documentation/git-format-patch.txt\n+++ b/Documentation/git-format-patch.txt\n@@ -24,6 +24,7 @@ SYNOPSIS\n \t\t   [(--reroll-count|-v) <n>]\n \t\t   [--to=<email>] [--cc=<email>]\n \t\t   [--[no-]cover-letter] [--quiet]\n+\t\t   [--[no-]encode-email-headers]\n \t\t   [--no-notes | --notes[=<ref>]]\n \t\t   [--interdiff=<previous>]\n \t\t   [--range-diff=<previous> [--creation-factor=<percent>]]\n@@ -253,6 +254,13 @@ feeding the result to `git send-email`.\n \tcontaining the branch description, shortlog and the overall diffstat.  You can\n \tfill in a description in the file before sending it out.\n \n+--encode-email-headers::\n+--no-encode-email-headers::\n+\tEncode email headers that have non-ASCII characters with\n+\t\"Q-encoding\" (described in RFC 2047), instead of outputting the\n+\theaders verbatim. Defaults to the value of the\n+\t`format.encodeEmailHeaders` configuration variable.\n+\n --interdiff=<previous>::\n \tAs a reviewer aid, insert an interdiff into the cover letter,\n \tor as commentary of the lone patch of a 1-patch series, showing\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 83a4a6188e..a5c3ace9a0 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -46,6 +46,7 @@ static int default_abbrev_commit;\n static int default_show_root = 1;\n static int default_follow;\n static int default_show_signature;\n+static int default_encode_email_headers = 1;\n static int decoration_style;\n static int decoration_given;\n static int use_mailmap_config = 1;\n@@ -151,6 +152,7 @@ static void cmd_log_init_defaults(struct rev_info *rev)\n \trev->show_root_diff = default_show_root;\n \trev->subject_prefix = fmt_patch_subject_prefix;\n \trev->show_signature = default_show_signature;\n+\trev->encode_email_headers = default_encode_email_headers;\n \trev->diffopt.flags.allow_textconv = 1;\n \n \tif (default_date_mode)\n@@ -438,6 +440,10 @@ static int git_log_config(const char *var, const char *value, void *cb)\n \t\treturn git_config_string(&fmt_pretty, var, value);\n \tif (!strcmp(var, \"format.subjectprefix\"))\n \t\treturn git_config_string(&fmt_patch_subject_prefix, var, value);\n+\tif (!strcmp(var, \"format.encodeemailheaders\")) {\n+\t\tdefault_encode_email_headers = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n \tif (!strcmp(var, \"log.abbrevcommit\")) {\n \t\tdefault_abbrev_commit = git_config_bool(var, value);\n \t\treturn 0;\n@@ -1719,6 +1725,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \trev.show_notes = show_notes;\n \tmemcpy(&rev.notes_opt, &notes_opt, sizeof(notes_opt));\n \trev.commit_format = CMIT_FMT_EMAIL;\n+\trev.encode_email_headers = default_encode_email_headers;\n \trev.expand_tabs_in_log_default = 0;\n \trev.verbose_header = 1;\n \trev.diff = 1;\ndiff --git a/log-tree.c b/log-tree.c\nindex 897a90233e..0064788b25 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -693,6 +693,7 @@ void show_log(struct rev_info *opt)\n \tctx.abbrev = opt->diffopt.abbrev;\n \tctx.after_subject = extra_headers;\n \tctx.preserve_subject = opt->preserve_subject;\n+\tctx.encode_email_headers = opt->encode_email_headers;\n \tctx.reflog_info = opt->reflog_info;\n \tctx.fmt = opt->commit_format;\n \tctx.mailmap = opt->mailmap;\ndiff --git a/pretty.c b/pretty.c\nindex 28afc701b6..2a3d46bf42 100644\n--- a/pretty.c\n+++ b/pretty.c\n@@ -474,7 +474,8 @@ void pp_user_info(struct pretty_print_context *pp,\n \t\t}\n \n \t\tstrbuf_addstr(sb, \"From: \");\n-\t\tif (needs_rfc2047_encoding(namebuf, namelen)) {\n+\t\tif (pp->encode_email_headers &&\n+\t\t    needs_rfc2047_encoding(namebuf, namelen)) {\n \t\t\tadd_rfc2047(sb, namebuf, namelen,\n \t\t\t\t    encoding, RFC2047_ADDRESS);\n \t\t\tmax_length = 76; /* per rfc2047 */\n@@ -1767,7 +1768,8 @@ void pp_title_line(struct pretty_print_context *pp,\n \tif (pp->print_email_subject) {\n \t\tif (pp->rev)\n \t\t\tfmt_output_email_subject(sb, pp->rev);\n-\t\tif (needs_rfc2047_encoding(title.buf, title.len))\n+\t\tif (pp->encode_email_headers &&\n+\t\t    needs_rfc2047_encoding(title.buf, title.len))\n \t\t\tadd_rfc2047(sb, title.buf, title.len,\n \t\t\t\t\t\tencoding, RFC2047_SUBJECT);\n \t\telse\ndiff --git a/pretty.h b/pretty.h\nindex 4ad1fc31ff..071f2fb8e4 100644\n--- a/pretty.h\n+++ b/pretty.h\n@@ -43,6 +43,7 @@ struct pretty_print_context {\n \tstruct string_list *mailmap;\n \tint color;\n \tstruct ident_split *from_ident;\n+\tunsigned encode_email_headers:1;\n \n \t/*\n \t * Fields below here are manipulated internally by pp_* functions and\ndiff --git a/revision.c b/revision.c\nindex 8136929e23..58f5826df0 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -2241,6 +2241,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg\n \t\trevs->topo_order = 1;\n \t\trevs->rewrite_parents = 1;\n \t\trevs->graph = graph_init(revs);\n+\t} else if (!strcmp(arg, \"--encode-email-headers\")) {\n+\t\trevs->encode_email_headers = 1;\n+\t} else if (!strcmp(arg, \"--no-encode-email-headers\")) {\n+\t\trevs->encode_email_headers = 0;\n \t} else if (!strcmp(arg, \"--root\")) {\n \t\trevs->show_root_diff = 1;\n \t} else if (!strcmp(arg, \"--no-commit-id\")) {\ndiff --git a/revision.h b/revision.h\nindex 475f048fb6..0f962e4e17 100644\n--- a/revision.h\n+++ b/revision.h\n@@ -203,7 +203,8 @@ struct rev_info {\n \t\t\tuse_terminator:1,\n \t\t\tmissing_newline:1,\n \t\t\tdate_mode_explicit:1,\n-\t\t\tpreserve_subject:1;\n+\t\t\tpreserve_subject:1,\n+\t\t\tencode_email_headers:1;\n \tunsigned int\tdisable_stdin:1;\n \t/* --show-linear-break */\n \tunsigned int\ttrack_linear:1,\ndiff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh\nindex b653dd7d44..db7e733af9 100755\n--- a/t/t4014-format-patch.sh\n+++ b/t/t4014-format-patch.sh\n@@ -1160,6 +1160,59 @@ test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '\n \tcheck_author \"Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar\"\n '\n \n+cat >expect <<'EOF'\n+From: Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar\n+ Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo\n+ Bar Foo Bar Foo Bar Foo Bar <author@example.com>\n+EOF\n+test_expect_success 'format-patch wraps extremely long from-header (non-ASCII without Q-encoding)' '\n+\techo content >>file &&\n+\tgit add file &&\n+\tGIT_AUTHOR_NAME=\"Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar\" \\\n+\tgit commit -m author-check &&\n+\tgit format-patch --no-encode-email-headers --stdout -1 >patch &&\n+\tsed -n \"/^From: /p; /^ /p; /^$/q\" patch >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n+Subject: [PATCH] Foö\n+EOF\n+test_expect_success 'subject lines are unencoded with --no-encode-email-headers' '\n+\techo content >>file &&\n+\tgit add file &&\n+\tgit commit -m \"Foö\" &&\n+\tgit format-patch --no-encode-email-headers -1 --stdout >patch &&\n+\tgrep ^Subject: patch >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n+Subject: [PATCH] Foö\n+EOF\n+test_expect_success 'subject lines are unencoded with format.encodeEmailHeaders=false' '\n+\techo content >>file &&\n+\tgit add file &&\n+\tgit commit -m \"Foö\" &&\n+\tgit config format.encodeEmailHeaders false &&\n+\tgit format-patch -1 --stdout >patch &&\n+\tgrep ^Subject: patch >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+cat >expect <<'EOF'\n+Subject: [PATCH] =?UTF-8?q?Fo=C3=B6?=\n+EOF\n+test_expect_success '--encode-email-headers overrides format.encodeEmailHeaders' '\n+\techo content >>file &&\n+\tgit add file &&\n+\tgit commit -m \"Foö\" &&\n+\tgit config format.encodeEmailHeaders false &&\n+\tgit format-patch --encode-email-headers -1 --stdout >patch &&\n+\tgrep ^Subject: patch >actual &&\n+\ttest_cmp expect actual\n+'\n+\n cat >expect <<'EOF'\n Subject: header with . in it\n EOF\n"}]}