Skip to content

Commit 59b519a

Browse files
sgngitster
authored andcommitted
am: learn to process quoted lines that ends with CRLF
In previous changes, mailinfo has learnt to process lines that decoded from base64 or quoted-printable, and ends with CRLF. Let's teach "am" that new trick, too. Signed-off-by: Đoàn Trần Công Danh <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 133a4fd commit 59b519a

File tree

6 files changed

+110
-0
lines changed

6 files changed

+110
-0
lines changed

Documentation/git-am.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ SYNOPSIS
1515
[--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
1616
[--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet]
1717
[--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>]
18+
[--quoted-cr=<action>]
1819
[(<mbox> | <Maildir>)...]
1920
'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
2021

@@ -59,6 +60,9 @@ OPTIONS
5960
--no-scissors::
6061
Ignore scissors lines (see linkgit:git-mailinfo[1]).
6162

63+
--quoted-cr=<action>::
64+
This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).
65+
6266
-m::
6367
--message-id::
6468
Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),

builtin/am.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ struct am_state {
116116
int keep; /* enum keep_type */
117117
int message_id;
118118
int scissors; /* enum scissors_type */
119+
int quoted_cr; /* enum quoted_cr_action */
119120
struct strvec git_apply_opts;
120121
const char *resolvemsg;
121122
int committer_date_is_author_date;
@@ -145,6 +146,7 @@ static void am_state_init(struct am_state *state)
145146
git_config_get_bool("am.messageid", &state->message_id);
146147

147148
state->scissors = SCISSORS_UNSET;
149+
state->quoted_cr = quoted_cr_unset;
148150

149151
strvec_init(&state->git_apply_opts);
150152

@@ -165,6 +167,16 @@ static void am_state_release(struct am_state *state)
165167
strvec_clear(&state->git_apply_opts);
166168
}
167169

170+
static int am_option_parse_quoted_cr(const struct option *opt,
171+
const char *arg, int unset)
172+
{
173+
BUG_ON_OPT_NEG(unset);
174+
175+
if (mailinfo_parse_quoted_cr_action(arg, opt->value) != 0)
176+
return error(_("bad action '%s' for '%s'"), arg, "--quoted-cr");
177+
return 0;
178+
}
179+
168180
/**
169181
* Returns path relative to the am_state directory.
170182
*/
@@ -397,6 +409,12 @@ static void am_load(struct am_state *state)
397409
else
398410
state->scissors = SCISSORS_UNSET;
399411

412+
read_state_file(&sb, state, "quoted-cr", 1);
413+
if (!*sb.buf)
414+
state->quoted_cr = quoted_cr_unset;
415+
else if (mailinfo_parse_quoted_cr_action(sb.buf, &state->quoted_cr) != 0)
416+
die(_("could not parse %s"), am_path(state, "quoted-cr"));
417+
400418
read_state_file(&sb, state, "apply-opt", 1);
401419
strvec_clear(&state->git_apply_opts);
402420
if (sq_dequote_to_strvec(sb.buf, &state->git_apply_opts) < 0)
@@ -1002,6 +1020,24 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
10021020
}
10031021
write_state_text(state, "scissors", str);
10041022

1023+
switch (state->quoted_cr) {
1024+
case quoted_cr_unset:
1025+
str = "";
1026+
break;
1027+
case quoted_cr_nowarn:
1028+
str = "nowarn";
1029+
break;
1030+
case quoted_cr_warn:
1031+
str = "warn";
1032+
break;
1033+
case quoted_cr_strip:
1034+
str = "strip";
1035+
break;
1036+
default:
1037+
BUG("invalid value for state->quoted_cr");
1038+
}
1039+
write_state_text(state, "quoted-cr", str);
1040+
10051041
sq_quote_argv(&sb, state->git_apply_opts.v);
10061042
write_state_text(state, "apply-opt", sb.buf);
10071043

@@ -1162,6 +1198,18 @@ static int parse_mail(struct am_state *state, const char *mail)
11621198
BUG("invalid value for state->scissors");
11631199
}
11641200

1201+
switch (state->quoted_cr) {
1202+
case quoted_cr_unset:
1203+
break;
1204+
case quoted_cr_nowarn:
1205+
case quoted_cr_warn:
1206+
case quoted_cr_strip:
1207+
mi.quoted_cr = state->quoted_cr;
1208+
break;
1209+
default:
1210+
BUG("invalid value for state->quoted_cr");
1211+
}
1212+
11651213
mi.input = xfopen(mail, "r");
11661214
mi.output = xfopen(am_path(state, "info"), "w");
11671215
if (mailinfo(&mi, am_path(state, "msg"), am_path(state, "patch")))
@@ -2242,6 +2290,9 @@ int cmd_am(int argc, const char **argv, const char *prefix)
22422290
0, PARSE_OPT_NONEG),
22432291
OPT_BOOL('c', "scissors", &state.scissors,
22442292
N_("strip everything before a scissors line")),
2293+
OPT_CALLBACK_F(0, "quoted-cr", &state.quoted_cr, N_("action"),
2294+
N_("pass it through git-mailinfo"),
2295+
PARSE_OPT_NONEG, am_option_parse_quoted_cr),
22452296
OPT_PASSTHRU_ARGV(0, "whitespace", &state.git_apply_opts, N_("action"),
22462297
N_("pass it through git-apply"),
22472298
0),

contrib/completion/git-completion.bash

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,6 +1333,7 @@ __git_whitespacelist="nowarn warn error error-all fix"
13331333
__git_patchformat="mbox stgit stgit-series hg mboxrd"
13341334
__git_showcurrentpatch="diff raw"
13351335
__git_am_inprogress_options="--skip --continue --resolved --abort --quit --show-current-patch"
1336+
__git_quoted_cr="nowarn warn strip"
13361337

13371338
_git_am ()
13381339
{
@@ -1354,6 +1355,10 @@ _git_am ()
13541355
__gitcomp "$__git_showcurrentpatch" "" "${cur##--show-current-patch=}"
13551356
return
13561357
;;
1358+
--quoted-cr=*)
1359+
__gitcomp "$__git_quoted_cr" "" "${cur##--quoted-cr=}"
1360+
return
1361+
;;
13571362
--*)
13581363
__gitcomp_builtin am "" \
13591364
"$__git_am_inprogress_options"

mailinfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define MAX_BOUNDARIES 5
77

88
enum quoted_cr_action {
9+
quoted_cr_unset = -1,
910
quoted_cr_nowarn,
1011
quoted_cr_warn,
1112
quoted_cr_strip,

t/t4258-am-quoted-cr.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/sh
2+
3+
test_description='test am --quoted-cr=<action>'
4+
5+
. ./test-lib.sh
6+
7+
DATA="$TEST_DIRECTORY/t4258"
8+
9+
test_expect_success 'setup' '
10+
test_write_lines one two three >text &&
11+
test_commit one text &&
12+
test_write_lines one owt three >text &&
13+
test_commit two text
14+
'
15+
16+
test_expect_success 'am warn if quoted-cr is found' '
17+
git reset --hard one &&
18+
test_must_fail git am "$DATA/mbox" 2>err &&
19+
grep "quoted CRLF detected" err
20+
'
21+
22+
test_expect_success 'am --quoted-cr=strip' '
23+
test_might_fail git am --abort &&
24+
git reset --hard one &&
25+
git am --quoted-cr=strip "$DATA/mbox" &&
26+
git diff --exit-code HEAD two
27+
'
28+
29+
test_expect_success 'am with config mailinfo.quotecr=strip' '
30+
test_might_fail git am --abort &&
31+
git reset --hard one &&
32+
test_config mailinfo.quotedCr strip &&
33+
git am "$DATA/mbox" &&
34+
git diff --exit-code HEAD two
35+
'
36+
37+
test_done

t/t4258/mbox

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
From: A U Thor <[email protected]>
2+
3+
Subject: [PATCH v2] sample
4+
Date: Mon, 3 Aug 2020 22:40:55 +0700
5+
Message-Id: <[email protected]>
6+
Content-Type: text/plain; charset="utf-8"
7+
Content-Transfer-Encoding: base64
8+
9+
VGhpcyBpcyBjb21taXQgbWVzc2FnZS4NCi0tLQ0KIHRleHQgfCAyICstDQogMSBmaWxlIGNoYW5n
10+
ZWQsIDEgaW5zZXJ0aW9uKCspLCAxIGRlbGV0aW9uKC0pDQoNCmRpZmYgLS1naXQgYS90ZXh0IGIv
11+
dGV4dA0KaW5kZXggNTYyNmFiZi4uZjcxOWVmZCAxMDA2NDQNCi0tLSBhL3RleHQNCisrKyBiL3Rl
12+
eHQNCkBAIC0xICsxIEBADQotb25lDQordHdvDQotLSANCjIuMzEuMQoK

0 commit comments

Comments
 (0)