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, ¬es_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