Skip to content

Commit 19d097e

Browse files
pluvanogitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9fadedd commit 19d097e

File tree

9 files changed

+85
-3
lines changed

9 files changed

+85
-3
lines changed

Documentation/config/format.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ format.suffix::
5757
`.patch`. Use this variable to change that suffix (make sure to
5858
include the dot if you want it).
5959

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+
6065
format.pretty::
6166
The default pretty format for log/show/whatchanged command,
6267
See linkgit:git-log[1], linkgit:git-show[1],

Documentation/git-format-patch.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ SYNOPSIS
2424
[(--reroll-count|-v) <n>]
2525
[--to=<email>] [--cc=<email>]
2626
[--[no-]cover-letter] [--quiet]
27+
[--[no-]encode-email-headers]
2728
[--no-notes | --notes[=<ref>]]
2829
[--interdiff=<previous>]
2930
[--range-diff=<previous> [--creation-factor=<percent>]]
@@ -253,6 +254,13 @@ feeding the result to `git send-email`.
253254
containing the branch description, shortlog and the overall diffstat. You can
254255
fill in a description in the file before sending it out.
255256

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+
256264
--interdiff=<previous>::
257265
As a reviewer aid, insert an interdiff into the cover letter,
258266
or as commentary of the lone patch of a 1-patch series, showing

builtin/log.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static int default_abbrev_commit;
4646
static int default_show_root = 1;
4747
static int default_follow;
4848
static int default_show_signature;
49+
static int default_encode_email_headers = 1;
4950
static int decoration_style;
5051
static int decoration_given;
5152
static int use_mailmap_config = 1;
@@ -151,6 +152,7 @@ static void cmd_log_init_defaults(struct rev_info *rev)
151152
rev->show_root_diff = default_show_root;
152153
rev->subject_prefix = fmt_patch_subject_prefix;
153154
rev->show_signature = default_show_signature;
155+
rev->encode_email_headers = default_encode_email_headers;
154156
rev->diffopt.flags.allow_textconv = 1;
155157

156158
if (default_date_mode)
@@ -438,6 +440,10 @@ static int git_log_config(const char *var, const char *value, void *cb)
438440
return git_config_string(&fmt_pretty, var, value);
439441
if (!strcmp(var, "format.subjectprefix"))
440442
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+
}
441447
if (!strcmp(var, "log.abbrevcommit")) {
442448
default_abbrev_commit = git_config_bool(var, value);
443449
return 0;
@@ -1719,6 +1725,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
17191725
rev.show_notes = show_notes;
17201726
memcpy(&rev.notes_opt, &notes_opt, sizeof(notes_opt));
17211727
rev.commit_format = CMIT_FMT_EMAIL;
1728+
rev.encode_email_headers = default_encode_email_headers;
17221729
rev.expand_tabs_in_log_default = 0;
17231730
rev.verbose_header = 1;
17241731
rev.diff = 1;

log-tree.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,7 @@ void show_log(struct rev_info *opt)
693693
ctx.abbrev = opt->diffopt.abbrev;
694694
ctx.after_subject = extra_headers;
695695
ctx.preserve_subject = opt->preserve_subject;
696+
ctx.encode_email_headers = opt->encode_email_headers;
696697
ctx.reflog_info = opt->reflog_info;
697698
ctx.fmt = opt->commit_format;
698699
ctx.mailmap = opt->mailmap;

pretty.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,8 @@ void pp_user_info(struct pretty_print_context *pp,
474474
}
475475

476476
strbuf_addstr(sb, "From: ");
477-
if (needs_rfc2047_encoding(namebuf, namelen)) {
477+
if (pp->encode_email_headers &&
478+
needs_rfc2047_encoding(namebuf, namelen)) {
478479
add_rfc2047(sb, namebuf, namelen,
479480
encoding, RFC2047_ADDRESS);
480481
max_length = 76; /* per rfc2047 */
@@ -1767,7 +1768,8 @@ void pp_title_line(struct pretty_print_context *pp,
17671768
if (pp->print_email_subject) {
17681769
if (pp->rev)
17691770
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))
17711773
add_rfc2047(sb, title.buf, title.len,
17721774
encoding, RFC2047_SUBJECT);
17731775
else

pretty.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ struct pretty_print_context {
4343
struct string_list *mailmap;
4444
int color;
4545
struct ident_split *from_ident;
46+
unsigned encode_email_headers:1;
4647

4748
/*
4849
* Fields below here are manipulated internally by pp_* functions and

revision.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,6 +2241,10 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
22412241
revs->topo_order = 1;
22422242
revs->rewrite_parents = 1;
22432243
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;
22442248
} else if (!strcmp(arg, "--root")) {
22452249
revs->show_root_diff = 1;
22462250
} else if (!strcmp(arg, "--no-commit-id")) {

revision.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ struct rev_info {
203203
use_terminator:1,
204204
missing_newline:1,
205205
date_mode_explicit:1,
206-
preserve_subject:1;
206+
preserve_subject:1,
207+
encode_email_headers:1;
207208
unsigned int disable_stdin:1;
208209
/* --show-linear-break */
209210
unsigned int track_linear:1,

t/t4014-format-patch.sh

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,59 @@ test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
11601160
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"
11611161
'
11621162

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 <[email protected]>
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+
11631216
cat >expect <<'EOF'
11641217
Subject: header with . in it
11651218
EOF

0 commit comments

Comments
 (0)