Merge branch 'js/fsck-opt'
authorJunio C Hamano <gitster@pobox.com>
Mon, 3 Aug 2015 18:01:18 +0000 (11:01 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 3 Aug 2015 18:01:18 +0000 (11:01 -0700)
Allow ignoring fsck errors on specific set of known-to-be-bad
objects, and also tweaking warning level of various kinds of non
critical breakages reported.

* js/fsck-opt:
  fsck: support ignoring objects in `git fsck` via fsck.skiplist
  fsck: git receive-pack: support excluding objects from fsck'ing
  fsck: introduce `git fsck --connectivity-only`
  fsck: support demoting errors to warnings
  fsck: document the new receive.fsck.<msg-id> options
  fsck: allow upgrading fsck warnings to errors
  fsck: optionally ignore specific fsck issues completely
  fsck: disallow demoting grave fsck errors to warnings
  fsck: add a simple test for receive.fsck.<msg-id>
  fsck: make fsck_tag() warn-friendly
  fsck: handle multiple authors in commits specially
  fsck: make fsck_commit() warn-friendly
  fsck: make fsck_ident() warn-friendly
  fsck: report the ID of the error/warning
  fsck (receive-pack): allow demoting errors to warnings
  fsck: offer a function to demote fsck errors to warnings
  fsck: provide a function to parse fsck message IDs
  fsck: introduce identifiers for fsck messages
  fsck: introduce fsck options

1  2 
Documentation/config.txt
builtin/fsck.c
builtin/index-pack.c
fsck.c

Simple merge
diff --cc builtin/fsck.c
Simple merge
Simple merge
diff --cc fsck.c
--- 1/fsck.c
--- 2/fsck.c
+++ b/fsck.c
@@@ -241,8 -527,8 +527,8 @@@ static int fsck_tree(struct tree *item
        return retval;
  }
  
 -static int require_end_of_header(const void *data, unsigned long size,
 -      struct object *obj, struct fsck_options *options)
 +static int verify_headers(const void *data, unsigned long size,
-                         struct object *obj, fsck_error error_func)
++                        struct object *obj, struct fsck_options *options)
  {
        const char *buffer = (const char *)data;
        unsigned long i;
                }
        }
  
-       return error_func(obj, FSCK_ERROR, "unterminated header");
 +      /*
 +       * We did not find double-LF that separates the header
 +       * and the body.  Not having a body is not a crime but
 +       * we do want to see the terminating LF for the last header
 +       * line.
 +       */
 +      if (size && buffer[size - 1] == '\n')
 +              return 0;
 +
+       return report(options, obj,
+               FSCK_MSG_UNTERMINATED_HEADER, "unterminated header");
  }
  
- static int fsck_ident(const char **ident, struct object *obj, fsck_error error_func)
+ static int fsck_ident(const char **ident, struct object *obj, struct fsck_options *options)
  {
+       const char *p = *ident;
        char *end;
  
-       if (**ident == '<')
-               return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
-       *ident += strcspn(*ident, "<>\n");
-       if (**ident == '>')
-               return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad name");
-       if (**ident != '<')
-               return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing email");
-       if ((*ident)[-1] != ' ')
-               return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
-       (*ident)++;
-       *ident += strcspn(*ident, "<>\n");
-       if (**ident != '>')
-               return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad email");
-       (*ident)++;
-       if (**ident != ' ')
-               return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before date");
-       (*ident)++;
-       if (**ident == '0' && (*ident)[1] != ' ')
-               return error_func(obj, FSCK_ERROR, "invalid author/committer line - zero-padded date");
-       if (date_overflows(strtoul(*ident, &end, 10)))
-               return error_func(obj, FSCK_ERROR, "invalid author/committer line - date causes integer overflow");
-       if (end == *ident || *end != ' ')
-               return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad date");
-       *ident = end + 1;
-       if ((**ident != '+' && **ident != '-') ||
-           !isdigit((*ident)[1]) ||
-           !isdigit((*ident)[2]) ||
-           !isdigit((*ident)[3]) ||
-           !isdigit((*ident)[4]) ||
-           ((*ident)[5] != '\n'))
-               return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad time zone");
-       (*ident) += 6;
+       *ident = strchrnul(*ident, '\n');
+       if (**ident == '\n')
+               (*ident)++;
+       if (*p == '<')
+               return report(options, obj, FSCK_MSG_MISSING_NAME_BEFORE_EMAIL, "invalid author/committer line - missing space before email");
+       p += strcspn(p, "<>\n");
+       if (*p == '>')
+               return report(options, obj, FSCK_MSG_BAD_NAME, "invalid author/committer line - bad name");
+       if (*p != '<')
+               return report(options, obj, FSCK_MSG_MISSING_EMAIL, "invalid author/committer line - missing email");
+       if (p[-1] != ' ')
+               return report(options, obj, FSCK_MSG_MISSING_SPACE_BEFORE_EMAIL, "invalid author/committer line - missing space before email");
+       p++;
+       p += strcspn(p, "<>\n");
+       if (*p != '>')
+               return report(options, obj, FSCK_MSG_BAD_EMAIL, "invalid author/committer line - bad email");
+       p++;
+       if (*p != ' ')
+               return report(options, obj, FSCK_MSG_MISSING_SPACE_BEFORE_DATE, "invalid author/committer line - missing space before date");
+       p++;
+       if (*p == '0' && p[1] != ' ')
+               return report(options, obj, FSCK_MSG_ZERO_PADDED_DATE, "invalid author/committer line - zero-padded date");
+       if (date_overflows(strtoul(p, &end, 10)))
+               return report(options, obj, FSCK_MSG_BAD_DATE_OVERFLOW, "invalid author/committer line - date causes integer overflow");
+       if ((end == p || *end != ' '))
+               return report(options, obj, FSCK_MSG_BAD_DATE, "invalid author/committer line - bad date");
+       p = end + 1;
+       if ((*p != '+' && *p != '-') ||
+           !isdigit(p[1]) ||
+           !isdigit(p[2]) ||
+           !isdigit(p[3]) ||
+           !isdigit(p[4]) ||
+           (p[5] != '\n'))
+               return report(options, obj, FSCK_MSG_BAD_TIMEZONE, "invalid author/committer line - bad time zone");
+       p += 6;
        return 0;
  }
  
@@@ -314,10 -598,10 +607,10 @@@ static int fsck_commit_buffer(struct co
  {
        unsigned char tree_sha1[20], sha1[20];
        struct commit_graft *graft;
-       unsigned parent_count, parent_line_count = 0;
+       unsigned parent_count, parent_line_count = 0, author_count;
        int err;
  
-       if (verify_headers(buffer, size, &commit->object, error_func))
 -      if (require_end_of_header(buffer, size, &commit->object, options))
++      if (verify_headers(buffer, size, &commit->object, options))
                return -1;
  
        if (!skip_prefix(buffer, "tree ", &buffer))
@@@ -396,7 -702,7 +711,7 @@@ static int fsck_tag_buffer(struct tag *
                }
        }
  
-       if (verify_headers(buffer, size, &tag->object, error_func))
 -      if (require_end_of_header(buffer, size, &tag->object, options))
++      if (verify_headers(buffer, size, &tag->object, options))
                goto done;
  
        if (!skip_prefix(buffer, "object ", &buffer)) {