mailinfo: allow squelching quoted CRLF warning

In previous change, Git starts to warn for quoted CRLF in decoded
base64/QP email. Despite those warnings are usually helpful,
quoted CRLF could be part of some users' workflow.

Let's give them an option to turn off the warning completely.

Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Đoàn Trần Công Danh 2021-05-10 00:12:11 +07:00 committed by Junio C Hamano
parent 0b689562ca
commit f1aa299443
5 changed files with 62 additions and 3 deletions

View File

@ -9,7 +9,9 @@ git-mailinfo - Extracts patch and authorship from a single e-mail message
SYNOPSIS SYNOPSIS
-------- --------
[verse] [verse]
'git mailinfo' [-k|-b] [-u | --encoding=<encoding> | -n] [--[no-]scissors] <msg> <patch> 'git mailinfo' [-k|-b] [-u | --encoding=<encoding> | -n]
[--[no-]scissors] [--quoted-cr=<action>]
<msg> <patch>
DESCRIPTION DESCRIPTION
@ -89,6 +91,22 @@ This can be enabled by default with the configuration option mailinfo.scissors.
--no-scissors:: --no-scissors::
Ignore scissors lines. Useful for overriding mailinfo.scissors settings. Ignore scissors lines. Useful for overriding mailinfo.scissors settings.
--quoted-cr=<action>::
Action when processes email messages sent with base64 or
quoted-printable encoding, and the decoded lines end with a CRLF
instead of a simple LF.
+
The valid actions are:
+
--
* `nowarn`: Git will do nothing when such a CRLF is found.
* `warn`: Git will issue a warning for each message if such a CRLF is
found.
--
+
The default action could be set by configuration option `mailinfo.quotedCR`.
If no such configuration option has been set, `warn` will be used.
<msg>:: <msg>::
The commit log message extracted from e-mail, usually The commit log message extracted from e-mail, usually
except the title line which comes from e-mail Subject. except the title line which comes from e-mail Subject.

View File

@ -38,6 +38,15 @@ static int parse_opt_explicit_encoding(const struct option *opt,
return 0; return 0;
} }
static int parse_opt_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;
}
int cmd_mailinfo(int argc, const char **argv, const char *prefix) int cmd_mailinfo(int argc, const char **argv, const char *prefix)
{ {
struct metainfo_charset meta_charset; struct metainfo_charset meta_charset;
@ -61,6 +70,9 @@ int cmd_mailinfo(int argc, const char **argv, const char *prefix)
N_("re-code metadata to this encoding"), N_("re-code metadata to this encoding"),
PARSE_OPT_NONEG, parse_opt_explicit_encoding), PARSE_OPT_NONEG, parse_opt_explicit_encoding),
OPT_BOOL(0, "scissors", &mi.use_scissors, N_("use scissors")), OPT_BOOL(0, "scissors", &mi.use_scissors, N_("use scissors")),
OPT_CALLBACK_F(0, "quoted-cr", &mi.quoted_cr, N_("<action>"),
N_("action when quoted CR is found"),
PARSE_OPT_NONEG, parse_opt_quoted_cr),
OPT_HIDDEN_BOOL(0, "inbody-headers", &mi.use_inbody_headers, OPT_HIDDEN_BOOL(0, "inbody-headers", &mi.use_inbody_headers,
N_("use headers in message's body")), N_("use headers in message's body")),
OPT_END() OPT_END()

View File

@ -1040,7 +1040,8 @@ static void handle_filter_flowed(struct mailinfo *mi, struct strbuf *line,
static void summarize_quoted_cr(struct mailinfo *mi) static void summarize_quoted_cr(struct mailinfo *mi)
{ {
if (mi->have_quoted_cr) if (mi->have_quoted_cr &&
mi->quoted_cr == quoted_cr_warn)
warning(_("quoted CRLF detected")); warning(_("quoted CRLF detected"));
} }
@ -1220,6 +1221,17 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)
return mi->input_error; return mi->input_error;
} }
int mailinfo_parse_quoted_cr_action(const char *actionstr, int *action)
{
if (!strcmp(actionstr, "nowarn"))
*action = quoted_cr_nowarn;
else if (!strcmp(actionstr, "warn"))
*action = quoted_cr_warn;
else
return -1;
return 0;
}
static int git_mailinfo_config(const char *var, const char *value, void *mi_) static int git_mailinfo_config(const char *var, const char *value, void *mi_)
{ {
struct mailinfo *mi = mi_; struct mailinfo *mi = mi_;
@ -1230,6 +1242,11 @@ static int git_mailinfo_config(const char *var, const char *value, void *mi_)
mi->use_scissors = git_config_bool(var, value); mi->use_scissors = git_config_bool(var, value);
return 0; return 0;
} }
if (!strcmp(var, "mailinfo.quotedcr")) {
if (mailinfo_parse_quoted_cr_action(value, &mi->quoted_cr) != 0)
return error(_("bad action '%s' for '%s'"), value, var);
return 0;
}
/* perhaps others here */ /* perhaps others here */
return 0; return 0;
} }
@ -1242,6 +1259,7 @@ void setup_mailinfo(struct mailinfo *mi)
strbuf_init(&mi->charset, 0); strbuf_init(&mi->charset, 0);
strbuf_init(&mi->log_message, 0); strbuf_init(&mi->log_message, 0);
strbuf_init(&mi->inbody_header_accum, 0); strbuf_init(&mi->inbody_header_accum, 0);
mi->quoted_cr = quoted_cr_warn;
mi->header_stage = 1; mi->header_stage = 1;
mi->use_inbody_headers = 1; mi->use_inbody_headers = 1;
mi->content_top = mi->content; mi->content_top = mi->content;

View File

@ -5,6 +5,11 @@
#define MAX_BOUNDARIES 5 #define MAX_BOUNDARIES 5
enum quoted_cr_action {
quoted_cr_nowarn,
quoted_cr_warn,
};
struct mailinfo { struct mailinfo {
FILE *input; FILE *input;
FILE *output; FILE *output;
@ -14,6 +19,7 @@ struct mailinfo {
struct strbuf email; struct strbuf email;
int keep_subject; int keep_subject;
int keep_non_patch_brackets_in_subject; int keep_non_patch_brackets_in_subject;
int quoted_cr; /* enum quoted_cr_action */
int add_message_id; int add_message_id;
int use_scissors; int use_scissors;
int use_inbody_headers; int use_inbody_headers;
@ -40,6 +46,7 @@ struct mailinfo {
int input_error; int input_error;
}; };
int mailinfo_parse_quoted_cr_action(const char *actionstr, int *action);
void setup_mailinfo(struct mailinfo *); void setup_mailinfo(struct mailinfo *);
int mailinfo(struct mailinfo *, const char *msg, const char *patch); int mailinfo(struct mailinfo *, const char *msg, const char *patch);
void clear_mailinfo(struct mailinfo *); void clear_mailinfo(struct mailinfo *);

View File

@ -255,7 +255,11 @@ test_expect_success 'mailinfo warn CR in base64 encoded email' '
check_quoted_cr_mail quoted-cr/0001 && check_quoted_cr_mail quoted-cr/0001 &&
test_must_be_empty quoted-cr/0001.err && test_must_be_empty quoted-cr/0001.err &&
check_quoted_cr_mail quoted-cr/0002 && check_quoted_cr_mail quoted-cr/0002 &&
grep "quoted CRLF detected" quoted-cr/0002.err grep "quoted CRLF detected" quoted-cr/0002.err &&
check_quoted_cr_mail quoted-cr/0001 --quoted-cr=nowarn &&
test_must_be_empty quoted-cr/0001.err &&
check_quoted_cr_mail quoted-cr/0002 --quoted-cr=nowarn &&
test_must_be_empty quoted-cr/0002.err
' '
test_done test_done