fsck (receive-pack): allow demoting errors to warnings

For example, missing emails in commit and tag objects can be demoted to mere warnings with git config receive.fsck.missingemail=warn The value is actually a comma-separated list. In case that the same key is listed in multiple receive.fsck.<msg-id> lines in the config, the latter configuration wins (this can happen for example when both $HOME/.gitconfig and .git/config contain message type settings). As git receive-pack does not actually perform the checks, it hands off the setting to index-pack or unpack-objects in the form of an optional argument to the --strict option. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Jun 22, 2015 at 17:25 UTC 5d477a334a68698709f07ebda4999c10997ef6f7
5 files changed +33 -2
builtin/index-pack.c
+4
@@ -1633,6 +1633,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
1633 } else if (!strcmp(arg, "--strict")) {
1634 strict = 1;
1635 do_fsck_object = 1;
1636 + } else if (skip_prefix(arg, "--strict=", &arg)) {
1637 + strict = 1;
1638 + do_fsck_object = 1;
1639 + fsck_set_msg_types(&fsck_options, arg);
1640 } else if (!strcmp(arg, "--check-self-contained-and-connected")) {
1641 strict = 1;
1642 check_self_contained_and_connected = 1;
builtin/receive-pack.c
+15 -2
@@ -19,6 +19,7 @@
19 #include "tag.h"
20 #include "gpg-interface.h"
21 #include "sigchain.h"
22 +#include "fsck.h"
23
24 static const char receive_pack_usage[] = "git receive-pack <git-dir>";
25
@@ -36,6 +37,7 @@ static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
37 static enum deny_action deny_delete_current = DENY_UNCONFIGURED;
38 static int receive_fsck_objects = -1;
39 static int transfer_fsck_objects = -1;
40 +static struct strbuf fsck_msg_types = STRBUF_INIT;
41 static int receive_unpack_limit = -1;
42 static int transfer_unpack_limit = -1;
43 static int advertise_atomic_push = 1;
@@ -115,6 +117,15 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
117 return 0;
118 }
119
120 + if (skip_prefix(var, "receive.fsck.", &var)) {
121 + if (is_valid_msg_type(var, value))
122 + strbuf_addf(&fsck_msg_types, "%c%s=%s",
123 + fsck_msg_types.len ? ',' : '=', var, value);
124 + else
125 + warning("Skipping unknown msg id '%s'", var);
126 + return 0;
127 + }
128 +
129 if (strcmp(var, "receive.fsckobjects") == 0) {
130 receive_fsck_objects = git_config_bool(var, value);
131 return 0;
@@ -1490,7 +1501,8 @@ static const char *unpack(int err_fd, struct shallow_info *si)
1501 if (quiet)
1502 argv_array_push(&child.args, "-q");
1503 if (fsck_objects)
1493 - argv_array_push(&child.args, "--strict");
1504 + argv_array_pushf(&child.args, "--strict%s",
1505 + fsck_msg_types.buf);
1506 child.no_stdout = 1;
1507 child.err = err_fd;
1508 child.git_cmd = 1;
@@ -1508,7 +1520,8 @@ static const char *unpack(int err_fd, struct shallow_info *si)
1520 argv_array_pushl(&child.args, "index-pack",
1521 "--stdin", hdr_arg, keep_arg, NULL);
1522 if (fsck_objects)
1511 - argv_array_push(&child.args, "--strict");
1523 + argv_array_pushf(&child.args, "--strict%s",
1524 + fsck_msg_types.buf);
1525 if (fix_thin)
1526 argv_array_push(&child.args, "--fix-thin");
1527 child.out = -1;
builtin/unpack-objects.c
+5
@@ -530,6 +530,11 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
530 strict = 1;
531 continue;
532 }
533 + if (skip_prefix(arg, "--strict=", &arg)) {
534 + strict = 1;
535 + fsck_set_msg_types(&fsck_options, arg);
536 + continue;
537 + }
538 if (starts_with(arg, "--pack_header=")) {
539 struct pack_header *hdr;
540 char *c;
fsck.c
+8
@@ -131,6 +131,14 @@ static int parse_msg_type(const char *str)
131 die("Unknown fsck message type: '%s'", str);
132 }
133
134 +int is_valid_msg_type(const char *msg_id, const char *msg_type)
135 +{
136 + if (parse_msg_id(msg_id) < 0)
137 + return 0;
138 + parse_msg_type(msg_type);
139 + return 1;
140 +}
141 +
142 void fsck_set_msg_type(struct fsck_options *options,
143 const char *msg_id, const char *msg_type)
144 {
fsck.h
+1
@@ -9,6 +9,7 @@ struct fsck_options;
9 void fsck_set_msg_type(struct fsck_options *options,
10 const char *msg_id, const char *msg_type);
11 void fsck_set_msg_types(struct fsck_options *options, const char *values);
12 +int is_valid_msg_type(const char *msg_id, const char *msg_type);
13
14 /*
15 * callback function for fsck_walk