]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'js/fsck-name-objects-fix'
authorJunio C Hamano <gitster@pobox.com>
Thu, 18 Feb 2021 01:21:42 +0000 (17:21 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 18 Feb 2021 01:21:42 +0000 (17:21 -0800)
Fix "git fsck --name-objects" which apparently has not been used by
anybody who is motivated enough to report breakage.

* js/fsck-name-objects-fix:
  fsck --name-objects: be more careful parsing generation numbers
  t1450: robustify `remove_object()`

1  2 
fsck.c
t/t1450-fsck.sh

diff --combined fsck.c
index 4b7f0b73d73c3aec8342b9bcb4023ec6f0d300a0,293c1a2ef5dcb91514f617f874917af303ac25f2..71134fdefaa561ced0cfa3659eaa34155e9be5ce
--- 1/fsck.c
--- 2/fsck.c
+++ b/fsck.c
@@@ -80,9 -80,7 +80,9 @@@ static struct oidset gitmodules_done = 
        /* infos (reported as warnings, but ignored by default) */ \
        FUNC(GITMODULES_PARSE, INFO) \
        FUNC(BAD_TAG_NAME, INFO) \
 -      FUNC(MISSING_TAGGER_ENTRY, INFO)
 +      FUNC(MISSING_TAGGER_ENTRY, INFO) \
 +      /* ignored (elevated when requested) */ \
 +      FUNC(EXTRA_HEADER_ENTRY, IGNORE)
  
  #define MSG_ID(id, msg_type) FSCK_MSG_##id,
  enum fsck_msg_id {
@@@ -463,6 -461,11 +463,11 @@@ static int fsck_walk_commit(struct comm
                                generation += power * (name[--len] - '0');
                        if (power > 1 && len && name[len - 1] == '~')
                                name_prefix_len = len - 1;
+                       else {
+                               /* Maybe a non-first parent, e.g. HEAD^2 */
+                               generation = 0;
+                               name_prefix_len = len;
+                       }
                }
        }
  
@@@ -913,16 -916,6 +918,16 @@@ static int fsck_tag(const struct object
                    unsigned long size, struct fsck_options *options)
  {
        struct object_id tagged_oid;
 +      int tagged_type;
 +      return fsck_tag_standalone(oid, buffer, size, options, &tagged_oid,
 +                                 &tagged_type);
 +}
 +
 +int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
 +                      unsigned long size, struct fsck_options *options,
 +                      struct object_id *tagged_oid,
 +                      int *tagged_type)
 +{
        int ret = 0;
        char *eol;
        struct strbuf sb = STRBUF_INIT;
                ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_OBJECT, "invalid format - expected 'object' line");
                goto done;
        }
 -      if (parse_oid_hex(buffer, &tagged_oid, &p) || *p != '\n') {
 +      if (parse_oid_hex(buffer, tagged_oid, &p) || *p != '\n') {
                ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_OBJECT_SHA1, "invalid 'object' line format - bad sha1");
                if (ret)
                        goto done;
                ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TYPE, "invalid format - unexpected end after 'type' line");
                goto done;
        }
 -      if (type_from_string_gently(buffer, eol - buffer, 1) < 0)
 +      *tagged_type = type_from_string_gently(buffer, eol - buffer, 1);
 +      if (*tagged_type < 0)
                ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_TYPE, "invalid 'type' value");
        if (ret)
                goto done;
        }
        else
                ret = fsck_ident(&buffer, oid, OBJ_TAG, options);
 +      if (!*buffer)
 +              goto done;
 +
 +      if (!starts_with(buffer, "\n")) {
 +              /*
 +               * The verify_headers() check will allow
 +               * e.g. "[...]tagger <tagger>\nsome
 +               * garbage\n\nmessage" to pass, thinking "some
 +               * garbage" could be a custom header. E.g. "mktag"
 +               * doesn't want any unknown headers.
 +               */
 +              ret = report(options, oid, OBJ_TAG, FSCK_MSG_EXTRA_HEADER_ENTRY, "invalid format - extra header(s) after 'tagger'");
 +              if (ret)
 +                      goto done;
 +      }
  
  done:
        strbuf_release(&sb);
@@@ -1312,27 -1289,3 +1317,27 @@@ int fsck_finish(struct fsck_options *op
        oidset_clear(&gitmodules_done);
        return ret;
  }
 +
 +int fsck_config_internal(const char *var, const char *value, void *cb,
 +                       struct fsck_options *options)
 +{
 +      if (strcmp(var, "fsck.skiplist") == 0) {
 +              const char *path;
 +              struct strbuf sb = STRBUF_INIT;
 +
 +              if (git_config_pathname(&path, var, value))
 +                      return 1;
 +              strbuf_addf(&sb, "skiplist=%s", path);
 +              free((char *)path);
 +              fsck_set_msg_types(options, sb.buf);
 +              strbuf_release(&sb);
 +              return 0;
 +      }
 +
 +      if (skip_prefix(var, "fsck.", &var)) {
 +              fsck_set_msg_type(options, var, value);
 +              return 0;
 +      }
 +
 +      return git_default_config(var, value, cb);
 +}
diff --combined t/t1450-fsck.sh
index a30fc5f74a95063da9d60703f09b4c6de88f5d52,d3a3d2722b94afce6dc69eaa1e49465efeb1f5a3..231243152b2e128b54a7facdb4983009f36df603
@@@ -3,7 -3,7 +3,7 @@@
  test_description='git fsck random collection of tests
  
  * (HEAD) B
 -* (master) A
 +* (main) A
  '
  
  . ./test-lib.sh
@@@ -40,17 -40,13 +40,13 @@@ test_expect_success 'HEAD is part of re
  # specific corruption you test afterwards, lest a later test trip over
  # it.
  
- test_expect_success 'setup: helpers for corruption tests' '
-       sha1_file() {
-               remainder=${1#??} &&
-               firsttwo=${1%$remainder} &&
-               echo ".git/objects/$firsttwo/$remainder"
-       } &&
+ sha1_file () {
+       git rev-parse --git-path objects/$(test_oid_to_path "$1")
+ }
  
-       remove_object() {
-               rm "$(sha1_file "$1")"
-       }
- '
+ remove_object () {
+       rm "$(sha1_file "$1")"
+ }
  
  test_expect_success 'object with bad sha1' '
        sha=$(echo blob | git hash-object -w --stdin) &&
@@@ -662,13 -658,15 +658,15 @@@ test_expect_success 'fsck --name-object
        git init name-objects &&
        (
                cd name-objects &&
+               git config core.logAllRefUpdates false &&
                test_commit julius caesar.t &&
-               test_commit augustus &&
-               test_commit caesar &&
+               test_commit augustus44 &&
+               test_commit caesar  &&
                remove_object $(git rev-parse julius:caesar.t) &&
-               test_must_fail git fsck --name-objects >out &&
                tree=$(git rev-parse --verify julius:) &&
-               test_i18ngrep "$tree (refs/tags/julius:" out
+               git tag -d julius &&
+               test_must_fail git fsck --name-objects >out &&
+               test_i18ngrep "$tree (refs/tags/augustus44\\^:" out
        )
  '