@matheusbsbs / matheus-bagliano / commits / 19d097e3d7
Fork 0

format-patch: teach --no-encode-email-headers

When commit subjects or authors have non-ASCII characters, git format-patch Q-encodes them so they can be safely sent over email. However, if the patch transfer method is something other than email (web review tools, sneakernet), this only serves to make the patch metadata harder to read without first applying it (unless you can decode RFC 2047 in your head). git am as well as some email software supports non-Q-encoded mail as described in RFC 6531. Add --[no-]encode-email-headers and format.encodeEmailHeaders to let the user control this behavior. Signed-off-by: Emma Brooks <me@pluvano.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Emma Brooks committed Apr 8, 2020 at 04:31 UTC 19d097e3d73b4d3635bbe0e8735b2f059d59f29a
9 files changed +85 -3
Documentation/config/format.txt
+5
@@ -57,6 +57,11 @@ format.suffix::
57 `.patch`. Use this variable to change that suffix (make sure to
58 include the dot if you want it).
59
60 +format.encodeEmailHeaders::
61 + Encode email headers that have non-ASCII characters with
62 + "Q-encoding" (described in RFC 2047) for email transmission.
63 + Defaults to true.
64 +
65 format.pretty::
66 The default pretty format for log/show/whatchanged command,
67 See linkgit:git-log[1], linkgit:git-show[1],
Documentation/git-format-patch.txt
+8
@@ -24,6 +24,7 @@ SYNOPSIS
24 [(--reroll-count|-v) <n>]
25 [--to=<email>] [--cc=<email>]
26 [--[no-]cover-letter] [--quiet]
27 + [--[no-]encode-email-headers]
28 [--no-notes | --notes[=<ref>]]
29 [--interdiff=<previous>]
30 [--range-diff=<previous> [--creation-factor=<percent>]]
@@ -253,6 +254,13 @@ feeding the result to `git send-email`.
254 containing the branch description, shortlog and the overall diffstat. You can
255 fill in a description in the file before sending it out.
256
257 +--encode-email-headers::
258 +--no-encode-email-headers::
259 + Encode email headers that have non-ASCII characters with
260 + "Q-encoding" (described in RFC 2047), instead of outputting the
261 + headers verbatim. Defaults to the value of the
262 + `format.encodeEmailHeaders` configuration variable.
263 +
264 --interdiff=<previous>::
265 As a reviewer aid, insert an interdiff into the cover letter,
266 or as commentary of the lone patch of a 1-patch series, showing
builtin/log.c
+7
@@ -46,6 +46,7 @@ static int default_abbrev_commit;
46 static int default_show_root = 1;
47 static int default_follow;
48 static int default_show_signature;
49 +static int default_encode_email_headers = 1;
50 static int decoration_style;
51 static int decoration_given;
52 static int use_mailmap_config = 1;
@@ -151,6 +152,7 @@ static void cmd_log_init_defaults(struct rev_info *rev)
152 rev->show_root_diff = default_show_root;
153 rev->subject_prefix = fmt_patch_subject_prefix;
154 rev->show_signature = default_show_signature;
155 + rev->encode_email_headers = default_encode_email_headers;
156 rev->diffopt.flags.allow_textconv = 1;
157
158 if (default_date_mode)
@@ -438,6 +440,10 @@ static int git_log_config(const char *var, const char *value, void *cb)
440 return git_config_string(&fmt_pretty, var, value);
441 if (!strcmp(var, "format.subjectprefix"))
442 return git_config_string(&fmt_patch_subject_prefix, var, value);
443 + if (!strcmp(var, "format.encodeemailheaders")) {
444 + default_encode_email_headers = git_config_bool(var, value);
445 + return 0;
446 + }
447 if (!strcmp(var, "log.abbrevcommit")) {
448 default_abbrev_commit = git_config_bool(var, value);
449 return 0;
@@ -1719,6 +1725,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
1725 rev.show_notes = show_notes;
1726 memcpy(&rev.notes_opt, &notes_opt, sizeof(notes_opt));
1727 rev.commit_format = CMIT_FMT_EMAIL;
1728 + rev.encode_email_headers = default_encode_email_headers;
1729 rev.expand_tabs_in_log_default = 0;
1730 rev.verbose_header = 1;
1731 rev.diff = 1;
log-tree.c
+1
@@ -693,6 +693,7 @@ void show_log(struct rev_info *opt)
693 ctx.abbrev = opt->diffopt.abbrev;
694 ctx.after_subject = extra_headers;
695 ctx.preserve_subject = opt->preserve_subject;
696 + ctx.encode_email_headers = opt->encode_email_headers;
697 ctx.reflog_info = opt->reflog_info;
698 ctx.fmt = opt->commit_format;
699 ctx.mailmap = opt->mailmap;
pretty.c
+4 -2
@@ -474,7 +474,8 @@ void pp_user_info(struct pretty_print_context *pp,
474 }
475
476 strbuf_addstr(sb, "From: ");
477 - if (needs_rfc2047_encoding(namebuf, namelen)) {
477 + if (pp->encode_email_headers &&
478 + needs_rfc2047_encoding(namebuf, namelen)) {
479 add_rfc2047(sb, namebuf, namelen,
480 encoding, RFC2047_ADDRESS);
481 max_length = 76; /* per rfc2047 */
@@ -1767,7 +1768,8 @@ void pp_title_line(struct pretty_print_context *pp,
1768 if (pp->print_email_subject) {
1769 if (pp->rev)
1770 fmt_output_email_subject(sb, pp->rev);
1770 - if (needs_rfc2047_encoding(title.buf, title.len))
1771 + if (pp->encode_email_headers &&
1772 + needs_rfc2047_encoding(title.buf, title.len))
1773 add_rfc2047(sb, title.buf, title.len,
1774 encoding, RFC2047_SUBJECT);
1775 else
pretty.h
+1
@@ -43,6 +43,7 @@ struct pretty_print_context {
43 struct string_list *mailmap;
44 int color;
45 struct ident_split *from_ident;
46 + unsigned encode_email_headers:1;
47
48 /*
49 * Fields below here are manipulated internally by pp_* functions and
revision.c
+4
@@ -2241,6 +2241,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
2241 revs->topo_order = 1;
2242 revs->rewrite_parents = 1;
2243 revs->graph = graph_init(revs);
2244 + } else if (!strcmp(arg, "--encode-email-headers")) {
2245 + revs->encode_email_headers = 1;
2246 + } else if (!strcmp(arg, "--no-encode-email-headers")) {
2247 + revs->encode_email_headers = 0;
2248 } else if (!strcmp(arg, "--root")) {
2249 revs->show_root_diff = 1;
2250 } else if (!strcmp(arg, "--no-commit-id")) {
revision.h
+2 -1
@@ -203,7 +203,8 @@ struct rev_info {
203 use_terminator:1,
204 missing_newline:1,
205 date_mode_explicit:1,
206 - preserve_subject:1;
206 + preserve_subject:1,
207 + encode_email_headers:1;
208 unsigned int disable_stdin:1;
209 /* --show-linear-break */
210 unsigned int track_linear:1,
t/t4014-format-patch.sh
+53
@@ -1160,6 +1160,59 @@ test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
1160 check_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"
1161 '
1162
1163 +cat >expect <<'EOF'
1164 +From: Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
1165 + Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
1166 + Bar Foo Bar Foo Bar Foo Bar <author@example.com>
1167 +EOF
1168 +test_expect_success 'format-patch wraps extremely long from-header (non-ASCII without Q-encoding)' '
1169 + echo content >>file &&
1170 + git add file &&
1171 + GIT_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" \
1172 + git commit -m author-check &&
1173 + git format-patch --no-encode-email-headers --stdout -1 >patch &&
1174 + sed -n "/^From: /p; /^ /p; /^$/q" patch >actual &&
1175 + test_cmp expect actual
1176 +'
1177 +
1178 +cat >expect <<'EOF'
1179 +Subject: [PATCH] Foö
1180 +EOF
1181 +test_expect_success 'subject lines are unencoded with --no-encode-email-headers' '
1182 + echo content >>file &&
1183 + git add file &&
1184 + git commit -m "Foö" &&
1185 + git format-patch --no-encode-email-headers -1 --stdout >patch &&
1186 + grep ^Subject: patch >actual &&
1187 + test_cmp expect actual
1188 +'
1189 +
1190 +cat >expect <<'EOF'
1191 +Subject: [PATCH] Foö
1192 +EOF
1193 +test_expect_success 'subject lines are unencoded with format.encodeEmailHeaders=false' '
1194 + echo content >>file &&
1195 + git add file &&
1196 + git commit -m "Foö" &&
1197 + git config format.encodeEmailHeaders false &&
1198 + git format-patch -1 --stdout >patch &&
1199 + grep ^Subject: patch >actual &&
1200 + test_cmp expect actual
1201 +'
1202 +
1203 +cat >expect <<'EOF'
1204 +Subject: [PATCH] =?UTF-8?q?Fo=C3=B6?=
1205 +EOF
1206 +test_expect_success '--encode-email-headers overrides format.encodeEmailHeaders' '
1207 + echo content >>file &&
1208 + git add file &&
1209 + git commit -m "Foö" &&
1210 + git config format.encodeEmailHeaders false &&
1211 + git format-patch --encode-email-headers -1 --stdout >patch &&
1212 + grep ^Subject: patch >actual &&
1213 + test_cmp expect actual
1214 +'
1215 +
1216 cat >expect <<'EOF'
1217 Subject: header with . in it
1218 EOF