fsck (receive-pack): allow demoting errors to warnings
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Mon, 22 Jun 2015 15:25:31 +0000 (17:25 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 23 Jun 2015 21:27:34 +0000 (14:27 -0700)
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>
builtin/index-pack.c
builtin/receive-pack.c
builtin/unpack-objects.c
fsck.c
fsck.h

index 627eb3f..67b4bef 100644 (file)
@@ -1633,6 +1633,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
                        } else if (!strcmp(arg, "--strict")) {
                                strict = 1;
                                do_fsck_object = 1;
+                       } else if (skip_prefix(arg, "--strict=", &arg)) {
+                               strict = 1;
+                               do_fsck_object = 1;
+                               fsck_set_msg_types(&fsck_options, arg);
                        } else if (!strcmp(arg, "--check-self-contained-and-connected")) {
                                strict = 1;
                                check_self_contained_and_connected = 1;
index 94d0571..3afe8f8 100644 (file)
@@ -19,6 +19,7 @@
 #include "tag.h"
 #include "gpg-interface.h"
 #include "sigchain.h"
+#include "fsck.h"
 
 static const char receive_pack_usage[] = "git receive-pack <git-dir>";
 
@@ -36,6 +37,7 @@ static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
 static enum deny_action deny_delete_current = DENY_UNCONFIGURED;
 static int receive_fsck_objects = -1;
 static int transfer_fsck_objects = -1;
+static struct strbuf fsck_msg_types = STRBUF_INIT;
 static int receive_unpack_limit = -1;
 static int transfer_unpack_limit = -1;
 static int advertise_atomic_push = 1;
@@ -115,6 +117,15 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
                return 0;
        }
 
+       if (skip_prefix(var, "receive.fsck.", &var)) {
+               if (is_valid_msg_type(var, value))
+                       strbuf_addf(&fsck_msg_types, "%c%s=%s",
+                               fsck_msg_types.len ? ',' : '=', var, value);
+               else
+                       warning("Skipping unknown msg id '%s'", var);
+               return 0;
+       }
+
        if (strcmp(var, "receive.fsckobjects") == 0) {
                receive_fsck_objects = git_config_bool(var, value);
                return 0;
@@ -1490,7 +1501,8 @@ static const char *unpack(int err_fd, struct shallow_info *si)
                if (quiet)
                        argv_array_push(&child.args, "-q");
                if (fsck_objects)
-                       argv_array_push(&child.args, "--strict");
+                       argv_array_pushf(&child.args, "--strict%s",
+                               fsck_msg_types.buf);
                child.no_stdout = 1;
                child.err = err_fd;
                child.git_cmd = 1;
@@ -1508,7 +1520,8 @@ static const char *unpack(int err_fd, struct shallow_info *si)
                argv_array_pushl(&child.args, "index-pack",
                                 "--stdin", hdr_arg, keep_arg, NULL);
                if (fsck_objects)
-                       argv_array_push(&child.args, "--strict");
+                       argv_array_pushf(&child.args, "--strict%s",
+                               fsck_msg_types.buf);
                if (fix_thin)
                        argv_array_push(&child.args, "--fix-thin");
                child.out = -1;
index 6d17040..7cc086f 100644 (file)
@@ -530,6 +530,11 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix)
                                strict = 1;
                                continue;
                        }
+                       if (skip_prefix(arg, "--strict=", &arg)) {
+                               strict = 1;
+                               fsck_set_msg_types(&fsck_options, arg);
+                               continue;
+                       }
                        if (starts_with(arg, "--pack_header=")) {
                                struct pack_header *hdr;
                                char *c;
diff --git a/fsck.c b/fsck.c
index 41208a4..e6e8dc4 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -131,6 +131,14 @@ static int parse_msg_type(const char *str)
                die("Unknown fsck message type: '%s'", str);
 }
 
+int is_valid_msg_type(const char *msg_id, const char *msg_type)
+{
+       if (parse_msg_id(msg_id) < 0)
+               return 0;
+       parse_msg_type(msg_type);
+       return 1;
+}
+
 void fsck_set_msg_type(struct fsck_options *options,
                const char *msg_id, const char *msg_type)
 {
diff --git a/fsck.h b/fsck.h
index af3c84e..3ef92a3 100644 (file)
--- a/fsck.h
+++ b/fsck.h
@@ -9,6 +9,7 @@ struct fsck_options;
 void fsck_set_msg_type(struct fsck_options *options,
                const char *msg_id, const char *msg_type);
 void fsck_set_msg_types(struct fsck_options *options, const char *values);
+int is_valid_msg_type(const char *msg_id, const char *msg_type);
 
 /*
  * callback function for fsck_walk