]> git.ipfire.org Git - thirdparty/git.git/commitdiff
am: learn to process quoted lines that ends with CRLF
authorĐoàn Trần Công Danh <congdanhqx@gmail.com>
Sun, 9 May 2021 17:12:13 +0000 (00:12 +0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 10 May 2021 06:06:22 +0000 (15:06 +0900)
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 <congdanhqx@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-am.txt
builtin/am.c
contrib/completion/git-completion.bash
mailinfo.h
t/t4258-am-quoted-cr.sh [new file with mode: 0755]
t/t4258/mbox [new file with mode: 0644]

index decd8ae12278cac8f3ea5e7dc9f1fb15b95629bd..8714dfcb76220e8c409f3a15042b1d05debd9d9c 100644 (file)
@@ -15,6 +15,7 @@ SYNOPSIS
         [--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>]
         [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet]
         [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>]
+        [--quoted-cr=<action>]
         [(<mbox> | <Maildir>)...]
 'git am' (--continue | --skip | --abort | --quit | --show-current-patch[=(diff|raw)])
 
@@ -59,6 +60,9 @@ OPTIONS
 --no-scissors::
        Ignore scissors lines (see linkgit:git-mailinfo[1]).
 
+--quoted-cr=<action>::
+       This flag will be passed down to 'git mailinfo' (see linkgit:git-mailinfo[1]).
+
 -m::
 --message-id::
        Pass the `-m` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]),
index 8355e3566ff27e7f5e5899c14752bc80ac08ccb2..0b2d886c81b775d4b36cd575669808b8fc98868a 100644 (file)
@@ -116,6 +116,7 @@ struct am_state {
        int keep; /* enum keep_type */
        int message_id;
        int scissors; /* enum scissors_type */
+       int quoted_cr; /* enum quoted_cr_action */
        struct strvec git_apply_opts;
        const char *resolvemsg;
        int committer_date_is_author_date;
@@ -145,6 +146,7 @@ static void am_state_init(struct am_state *state)
        git_config_get_bool("am.messageid", &state->message_id);
 
        state->scissors = SCISSORS_UNSET;
+       state->quoted_cr = quoted_cr_unset;
 
        strvec_init(&state->git_apply_opts);
 
@@ -165,6 +167,16 @@ static void am_state_release(struct am_state *state)
        strvec_clear(&state->git_apply_opts);
 }
 
+static int am_option_parse_quoted_cr(const struct option *opt,
+                                    const char *arg, int unset)
+{
+       BUG_ON_OPT_NEG(unset);
+
+       if (mailinfo_parse_quoted_cr_action(arg, opt->value) != 0)
+               return error(_("bad action '%s' for '%s'"), arg, "--quoted-cr");
+       return 0;
+}
+
 /**
  * Returns path relative to the am_state directory.
  */
@@ -397,6 +409,12 @@ static void am_load(struct am_state *state)
        else
                state->scissors = SCISSORS_UNSET;
 
+       read_state_file(&sb, state, "quoted-cr", 1);
+       if (!*sb.buf)
+               state->quoted_cr = quoted_cr_unset;
+       else if (mailinfo_parse_quoted_cr_action(sb.buf, &state->quoted_cr) != 0)
+               die(_("could not parse %s"), am_path(state, "quoted-cr"));
+
        read_state_file(&sb, state, "apply-opt", 1);
        strvec_clear(&state->git_apply_opts);
        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,
        }
        write_state_text(state, "scissors", str);
 
+       switch (state->quoted_cr) {
+       case quoted_cr_unset:
+               str = "";
+               break;
+       case quoted_cr_nowarn:
+               str = "nowarn";
+               break;
+       case quoted_cr_warn:
+               str = "warn";
+               break;
+       case quoted_cr_strip:
+               str = "strip";
+               break;
+       default:
+               BUG("invalid value for state->quoted_cr");
+       }
+       write_state_text(state, "quoted-cr", str);
+
        sq_quote_argv(&sb, state->git_apply_opts.v);
        write_state_text(state, "apply-opt", sb.buf);
 
@@ -1162,6 +1198,18 @@ static int parse_mail(struct am_state *state, const char *mail)
                BUG("invalid value for state->scissors");
        }
 
+       switch (state->quoted_cr) {
+       case quoted_cr_unset:
+               break;
+       case quoted_cr_nowarn:
+       case quoted_cr_warn:
+       case quoted_cr_strip:
+               mi.quoted_cr = state->quoted_cr;
+               break;
+       default:
+               BUG("invalid value for state->quoted_cr");
+       }
+
        mi.input = xfopen(mail, "r");
        mi.output = xfopen(am_path(state, "info"), "w");
        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)
                        0, PARSE_OPT_NONEG),
                OPT_BOOL('c', "scissors", &state.scissors,
                        N_("strip everything before a scissors line")),
+               OPT_CALLBACK_F(0, "quoted-cr", &state.quoted_cr, N_("action"),
+                              N_("pass it through git-mailinfo"),
+                              PARSE_OPT_NONEG, am_option_parse_quoted_cr),
                OPT_PASSTHRU_ARGV(0, "whitespace", &state.git_apply_opts, N_("action"),
                        N_("pass it through git-apply"),
                        0),
index 49e76e9d08cd7de5f9e608e9ee7afff9f5fbc6bd..edf635095e1c953bb43c9f809c55412c2ccd6afe 100644 (file)
@@ -1333,6 +1333,7 @@ __git_whitespacelist="nowarn warn error error-all fix"
 __git_patchformat="mbox stgit stgit-series hg mboxrd"
 __git_showcurrentpatch="diff raw"
 __git_am_inprogress_options="--skip --continue --resolved --abort --quit --show-current-patch"
+__git_quoted_cr="nowarn warn strip"
 
 _git_am ()
 {
@@ -1354,6 +1355,10 @@ _git_am ()
                __gitcomp "$__git_showcurrentpatch" "" "${cur##--show-current-patch=}"
                return
                ;;
+       --quoted-cr=*)
+               __gitcomp "$__git_quoted_cr" "" "${cur##--quoted-cr=}"
+               return
+               ;;
        --*)
                __gitcomp_builtin am "" \
                        "$__git_am_inprogress_options"
index 2ddf8be90ffa61b1de9ee2d0ee89f783f40d2f91..f2ffd0349e8007256f5b2118d41faf35a53edf0d 100644 (file)
@@ -6,6 +6,7 @@
 #define MAX_BOUNDARIES 5
 
 enum quoted_cr_action {
+       quoted_cr_unset = -1,
        quoted_cr_nowarn,
        quoted_cr_warn,
        quoted_cr_strip,
diff --git a/t/t4258-am-quoted-cr.sh b/t/t4258-am-quoted-cr.sh
new file mode 100755 (executable)
index 0000000..fb5071f
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+test_description='test am --quoted-cr=<action>'
+
+. ./test-lib.sh
+
+DATA="$TEST_DIRECTORY/t4258"
+
+test_expect_success 'setup' '
+       test_write_lines one two three >text &&
+       test_commit one text &&
+       test_write_lines one owt three >text &&
+       test_commit two text
+'
+
+test_expect_success 'am warn if quoted-cr is found' '
+       git reset --hard one &&
+       test_must_fail git am "$DATA/mbox" 2>err &&
+       grep "quoted CRLF detected" err
+'
+
+test_expect_success 'am --quoted-cr=strip' '
+       test_might_fail git am --abort &&
+       git reset --hard one &&
+       git am --quoted-cr=strip "$DATA/mbox" &&
+       git diff --exit-code HEAD two
+'
+
+test_expect_success 'am with config mailinfo.quotecr=strip' '
+       test_might_fail git am --abort &&
+       git reset --hard one &&
+       test_config mailinfo.quotedCr strip &&
+       git am "$DATA/mbox" &&
+       git diff --exit-code HEAD two
+'
+
+test_done
diff --git a/t/t4258/mbox b/t/t4258/mbox
new file mode 100644 (file)
index 0000000..c62819f
--- /dev/null
@@ -0,0 +1,12 @@
+From: A U Thor <mail@example.com>
+To: list@example.org
+Subject: [PATCH v2] sample
+Date: Mon,  3 Aug 2020 22:40:55 +0700
+Message-Id: <msg-id@example.com>
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: base64
+
+VGhpcyBpcyBjb21taXQgbWVzc2FnZS4NCi0tLQ0KIHRleHQgfCAyICstDQogMSBmaWxlIGNoYW5n
+ZWQsIDEgaW5zZXJ0aW9uKCspLCAxIGRlbGV0aW9uKC0pDQoNCmRpZmYgLS1naXQgYS90ZXh0IGIv
+dGV4dA0KaW5kZXggNTYyNmFiZi4uZjcxOWVmZCAxMDA2NDQNCi0tLSBhL3RleHQNCisrKyBiL3Rl
+eHQNCkBAIC0xICsxIEBADQotb25lDQordHdvDQotLSANCjIuMzEuMQoK