]> git.ipfire.org Git - thirdparty/git.git/commitdiff
fsck --name-objects: be more careful parsing generation numbers
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Wed, 10 Feb 2021 18:01:30 +0000 (18:01 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 10 Feb 2021 20:38:05 +0000 (12:38 -0800)
In 7b35efd734e (fsck_walk(): optionally name objects on the go,
2016-07-17), the `fsck` machinery learned to optionally name the
objects, so that it is easier to see what part of the repository is in a
bad shape, say, when objects are missing.

To save on complexity, this machinery uses a parser to determine the
name of a parent given a commit's name: any `~<n>` suffix is parsed and
the parent's name is formed from the prefix together with `~<n+1>`.

However, this parser has a bug: if it finds a suffix `<n>` that is _not_
`~<n>`, it will mistake the empty string for the prefix and `<n>` for
the generation number. In other words, it will generate a name of the
form `~<bogus-number>`.

Let's fix this.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
fsck.c
t/t1450-fsck.sh

diff --git a/fsck.c b/fsck.c
index 5e282b3b6b25d514d2e82bdd6b29c9c17da580a5..293c1a2ef5dcb91514f617f874917af303ac25f2 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -461,6 +461,11 @@ static int fsck_walk_commit(struct commit *commit, void *data, struct fsck_optio
                                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;
+                       }
                }
        }
 
index 0c58cb349b6ee75214843ae2534bf9533f9831e7..d3a3d2722b94afce6dc69eaa1e49465efeb1f5a3 100755 (executable)
@@ -658,13 +658,15 @@ test_expect_success 'fsck --name-objects' '
        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
        )
 '