Merge branch 'jk/clear-delta-base-cache-fix'
[gitweb.git] / t / t1450-fsck.sh
index 8f52da2771c0a26c08b943cf7b9596c5e14afb7d..8975b4d1bcc4675be4d1869783ee4b7cc17c750f 100755 (executable)
@@ -43,13 +43,13 @@ test_expect_success 'HEAD is part of refs, valid objects appear valid' '
 
 test_expect_success 'setup: helpers for corruption tests' '
        sha1_file() {
-               echo "$*" | sed "s#..#.git/objects/&/#"
+               remainder=${1#??} &&
+               firsttwo=${1%$remainder} &&
+               echo ".git/objects/$firsttwo/$remainder"
        } &&
 
        remove_object() {
-               file=$(sha1_file "$*") &&
-               test -e "$file" &&
-               rm -f "$file"
+               rm "$(sha1_file "$1")"
        }
 '
 
@@ -188,8 +188,7 @@ test_expect_success 'commit with NUL in header' '
        grep "error in commit $new.*unterminated header: NUL at offset" out
 '
 
-test_expect_success 'malformatted tree object' '
-       test_when_finished "git update-ref -d refs/tags/wrong" &&
+test_expect_success 'tree object with duplicate entries' '
        test_when_finished "remove_object \$T" &&
        T=$(
                GIT_INDEX_FILE=test-index &&
@@ -208,6 +207,19 @@ test_expect_success 'malformatted tree object' '
        grep "error in tree .*contains duplicate file entries" out
 '
 
+test_expect_success 'unparseable tree object' '
+       test_when_finished "git update-ref -d refs/heads/wrong" &&
+       test_when_finished "remove_object \$tree_sha1" &&
+       test_when_finished "remove_object \$commit_sha1" &&
+       tree_sha1=$(printf "100644 \0twenty-bytes-of-junk" | git hash-object -t tree --stdin -w --literally) &&
+       commit_sha1=$(git commit-tree $tree_sha1) &&
+       git update-ref refs/heads/wrong $commit_sha1 &&
+       test_must_fail git fsck 2>out &&
+       test_i18ngrep "error: empty filename in tree entry" out &&
+       test_i18ngrep "$tree_sha1" out &&
+       test_i18ngrep ! "fatal: empty filename in tree entry" out
+'
+
 test_expect_success 'tag pointing to nonexistent' '
        cat >invalid-tag <<-\EOF &&
        object ffffffffffffffffffffffffffffffffffffffff
@@ -523,13 +535,6 @@ test_expect_success 'fsck --connectivity-only' '
        )
 '
 
-remove_loose_object () {
-       sha1="$(git rev-parse "$1")" &&
-       remainder=${sha1#??} &&
-       firsttwo=${sha1%$remainder} &&
-       rm .git/objects/$firsttwo/$remainder
-}
-
 test_expect_success 'fsck --name-objects' '
        rm -rf name-objects &&
        git init name-objects &&
@@ -538,11 +543,80 @@ test_expect_success 'fsck --name-objects' '
                test_commit julius caesar.t &&
                test_commit augustus &&
                test_commit caesar &&
-               remove_loose_object $(git rev-parse julius:caesar.t) &&
+               remove_object $(git rev-parse julius:caesar.t) &&
                test_must_fail git fsck --name-objects >out &&
                tree=$(git rev-parse --verify julius:) &&
                grep "$tree (\(refs/heads/master\|HEAD\)@{[0-9]*}:" out
        )
 '
 
+test_expect_success 'alternate objects are correctly blamed' '
+       test_when_finished "rm -rf alt.git .git/objects/info/alternates" &&
+       git init --bare alt.git &&
+       echo "../../alt.git/objects" >.git/objects/info/alternates &&
+       mkdir alt.git/objects/12 &&
+       >alt.git/objects/12/34567890123456789012345678901234567890 &&
+       test_must_fail git fsck >out 2>&1 &&
+       grep alt.git out
+'
+
+test_expect_success 'fsck errors in packed objects' '
+       git cat-file commit HEAD >basis &&
+       sed "s/</one/" basis >one &&
+       sed "s/</foo/" basis >two &&
+       one=$(git hash-object -t commit -w one) &&
+       two=$(git hash-object -t commit -w two) &&
+       pack=$(
+               {
+                       echo $one &&
+                       echo $two
+               } | git pack-objects .git/objects/pack/pack
+       ) &&
+       test_when_finished "rm -f .git/objects/pack/pack-$pack.*" &&
+       remove_object $one &&
+       remove_object $two &&
+       test_must_fail git fsck 2>out &&
+       grep "error in commit $one.* - bad name" out &&
+       grep "error in commit $two.* - bad name" out &&
+       ! grep corrupt out
+'
+
+test_expect_success 'fsck finds problems in duplicate loose objects' '
+       rm -rf broken-duplicate &&
+       git init broken-duplicate &&
+       (
+               cd broken-duplicate &&
+               test_commit duplicate &&
+               # no "-d" here, so we end up with duplicates
+               git repack &&
+               # now corrupt the loose copy
+               file=$(sha1_file "$(git rev-parse HEAD)") &&
+               rm "$file" &&
+               echo broken >"$file" &&
+               test_must_fail git fsck
+       )
+'
+
+test_expect_success 'fsck detects trailing loose garbage (commit)' '
+       git cat-file commit HEAD >basis &&
+       echo bump-commit-sha1 >>basis &&
+       commit=$(git hash-object -w -t commit basis) &&
+       file=$(sha1_file $commit) &&
+       test_when_finished "remove_object $commit" &&
+       chmod +w "$file" &&
+       echo garbage >>"$file" &&
+       test_must_fail git fsck 2>out &&
+       test_i18ngrep "garbage.*$commit" out
+'
+
+test_expect_success 'fsck detects trailing loose garbage (blob)' '
+       blob=$(echo trailing | git hash-object -w --stdin) &&
+       file=$(sha1_file $blob) &&
+       test_when_finished "remove_object $blob" &&
+       chmod +w "$file" &&
+       echo garbage >>"$file" &&
+       test_must_fail git fsck 2>out &&
+       test_i18ngrep "garbage.*$blob" out
+'
+
 test_done