diff options
Diffstat (limited to 't/t1450-fsck.sh')
-rwxr-xr-x | t/t1450-fsck.sh | 199 |
1 files changed, 160 insertions, 39 deletions
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 02478bc..ab7f31f 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -3,13 +3,12 @@ test_description='git fsck random collection of tests * (HEAD) B -* (master) A +* (main) A ' . ./test-lib.sh test_expect_success setup ' - test_oid_init && git config gc.auto 0 && git config i18n.commitencoding ISO-8859-1 && test_commit A fileA one && @@ -41,36 +40,78 @@ test_expect_success 'HEAD is part of refs, valid objects appear valid' ' # 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 hash mismatch' ' + git init --bare hash-mismatch && + ( + cd hash-mismatch && + + oid=$(echo blob | git hash-object -w --stdin) && + oldoid=$oid && + old=$(test_oid_to_path "$oid") && + new=$(dirname $old)/$(test_oid ff_2) && + oid="$(dirname $new)$(basename $new)" && + + mv objects/$old objects/$new && + git update-index --add --cacheinfo 100644 $oid foo && + tree=$(git write-tree) && + cmt=$(echo bogus | git commit-tree $tree) && + git update-ref refs/heads/bogus $cmt && + + test_must_fail git fsck 2>out && + grep "$oldoid: hash-path mismatch, found at: .*$new" out + ) ' -test_expect_success 'object with bad sha1' ' - sha=$(echo blob | git hash-object -w --stdin) && - old=$(test_oid_to_path "$sha") && - new=$(dirname $old)/$(test_oid ff_2) && - sha="$(dirname $new)$(basename $new)" && - mv .git/objects/$old .git/objects/$new && - test_when_finished "remove_object $sha" && - git update-index --add --cacheinfo 100644 $sha foo && - test_when_finished "git read-tree -u --reset HEAD" && - tree=$(git write-tree) && - test_when_finished "remove_object $tree" && - cmt=$(echo bogus | git commit-tree $tree) && - test_when_finished "remove_object $cmt" && - git update-ref refs/heads/bogus $cmt && - test_when_finished "git update-ref -d refs/heads/bogus" && +test_expect_success 'object with hash and type mismatch' ' + git init --bare hash-type-mismatch && + ( + cd hash-type-mismatch && - test_must_fail git fsck 2>out && - test_i18ngrep "$sha.*corrupt" out + oid=$(echo blob | git hash-object -w --stdin -t garbage --literally) && + oldoid=$oid && + old=$(test_oid_to_path "$oid") && + new=$(dirname $old)/$(test_oid ff_2) && + oid="$(dirname $new)$(basename $new)" && + + mv objects/$old objects/$new && + git update-index --add --cacheinfo 100644 $oid foo && + tree=$(git write-tree) && + cmt=$(echo bogus | git commit-tree $tree) && + git update-ref refs/heads/bogus $cmt && + + + test_must_fail git fsck 2>out && + grep "^error: $oldoid: hash-path mismatch, found at: .*$new" out && + grep "^error: $oldoid: object is of unknown type '"'"'garbage'"'"'" out + ) +' + +test_expect_success 'zlib corrupt loose object output ' ' + git init --bare corrupt-loose-output && + ( + cd corrupt-loose-output && + oid=$(git hash-object -w --stdin --literally </dev/null) && + oidf=objects/$(test_oid_to_path "$oid") && + chmod +w $oidf && + echo extra garbage >>$oidf && + + cat >expect.error <<-EOF && + error: garbage at end of loose object '\''$oid'\'' + error: unable to unpack contents of ./$oidf + error: $oid: object corrupt or missing: ./$oidf + EOF + test_must_fail git fsck 2>actual && + grep ^error: actual >error && + test_cmp expect.error error + ) ' test_expect_success 'branch pointing to non-commit' ' @@ -133,6 +174,30 @@ test_expect_success 'other worktree HEAD link pointing at a funny place' ' test_i18ngrep "worktrees/other/HEAD points to something strange" out ' +test_expect_success 'commit with multiple signatures is okay' ' + git cat-file commit HEAD >basis && + cat >sigs <<-EOF && + gpgsig -----BEGIN PGP SIGNATURE----- + VGhpcyBpcyBub3QgcmVhbGx5IGEgc2lnbmF0dXJlLg== + -----END PGP SIGNATURE----- + gpgsig-sha256 -----BEGIN PGP SIGNATURE----- + VGhpcyBpcyBub3QgcmVhbGx5IGEgc2lnbmF0dXJlLg== + -----END PGP SIGNATURE----- + EOF + sed -e "/^committer/q" basis >okay && + cat sigs >>okay && + echo >>okay && + sed -e "1,/^$/d" basis >>okay && + cat okay && + new=$(git hash-object -t commit -w --stdin <okay) && + test_when_finished "remove_object $new" && + git update-ref refs/heads/bogus "$new" && + test_when_finished "git update-ref -d refs/heads/bogus" && + git fsck 2>out && + cat out && + ! grep "commit $new" out +' + test_expect_success 'email without @ is okay' ' git cat-file commit HEAD >basis && sed "s/@/AT/" basis >okay && @@ -141,7 +206,6 @@ test_expect_success 'email without @ is okay' ' git update-ref refs/heads/bogus "$new" && test_when_finished "git update-ref -d refs/heads/bogus" && git fsck 2>out && - cat out && ! grep "commit $new" out ' @@ -234,6 +298,35 @@ test_expect_success 'tree object with duplicate entries' ' test_i18ngrep "error in tree .*contains duplicate file entries" out ' +check_duplicate_names () { + expect=$1 && + shift && + names=$@ && + test_expect_$expect "tree object with duplicate names: $names" ' + test_when_finished "remove_object \$blob" && + test_when_finished "remove_object \$tree" && + test_when_finished "remove_object \$badtree" && + blob=$(echo blob | git hash-object -w --stdin) && + printf "100644 blob %s\t%s\n" $blob x.2 >tree && + tree=$(git mktree <tree) && + for name in $names + do + case "$name" in + */) printf "040000 tree %s\t%s\n" $tree "${name%/}" ;; + *) printf "100644 blob %s\t%s\n" $blob "$name" ;; + esac + done >badtree && + badtree=$(git mktree <badtree) && + test_must_fail git fsck 2>out && + test_i18ngrep "$badtree" out && + test_i18ngrep "error in tree .*contains duplicate file entries" out + ' +} + +check_duplicate_names success x x.1 x/ +check_duplicate_names success x x.1.2 x.1/ x/ +check_duplicate_names success x x.1 x.1.2 x/ + test_expect_success 'unparseable tree object' ' test_oid_cache <<-\EOF && junk sha1:twenty-bytes-of-junk @@ -329,7 +422,7 @@ test_expect_success 'tag with incorrect tag name & missing tagger' ' warning in tag $tag: badTagName: invalid '\''tag'\'' name: wrong name format warning in tag $tag: missingTaggerEntry: invalid format - expected '\''tagger'\'' line EOF - test_i18ncmp expect out + test_cmp expect out ' test_expect_success 'tag with bad tagger' ' @@ -611,13 +704,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 ) ' @@ -662,7 +757,7 @@ test_expect_success 'fsck fails on corrupt packfile' ' # at least one of which is not zero, so setting the first byte to 0 is # sufficient.) chmod a+w .git/objects/pack/pack-$pack.pack && - printf '\0' | dd of=.git/objects/pack/pack-$pack.pack bs=1 conv=notrunc seek=12 && + printf "\0" | dd of=.git/objects/pack/pack-$pack.pack bs=1 conv=notrunc seek=12 && test_when_finished "rm -f .git/objects/pack/pack-$pack.*" && remove_object $hsh && @@ -679,10 +774,19 @@ test_expect_success 'fsck finds problems in duplicate loose objects' ' # no "-d" here, so we end up with duplicates git repack && # now corrupt the loose copy - file=$(sha1_file "$(git rev-parse HEAD)") && + oid="$(git rev-parse HEAD)" && + file=$(sha1_file "$oid") && rm "$file" && echo broken >"$file" && - test_must_fail git fsck + test_must_fail git fsck 2>err && + + cat >expect <<-EOF && + error: inflate: data stream error (incorrect header check) + error: unable to unpack header of $file + error: $oid: object corrupt or missing: $file + EOF + grep "^error: " err >actual && + test_cmp expect actual ) ' @@ -755,7 +859,7 @@ test_expect_success 'fsck notices dangling objects' ' git fsck >actual && # the output order is non-deterministic, as it comes from a hash sort <actual >actual.sorted && - test_i18ncmp expect actual.sorted + test_cmp expect actual.sorted ) ' @@ -765,7 +869,7 @@ test_expect_success 'fsck --connectivity-only notices dangling objects' ' git fsck --connectivity-only >actual && # the output order is non-deterministic, as it comes from a hash sort <actual >actual.sorted && - test_i18ncmp expect actual.sorted + test_cmp expect actual.sorted ) ' @@ -816,4 +920,21 @@ test_expect_success 'detect corrupt index file in fsck' ' test_i18ngrep "bad index file" errors ' +test_expect_success 'fsck error and recovery on invalid object type' ' + git init --bare garbage-type && + ( + cd garbage-type && + + garbage_blob=$(git hash-object --stdin -w -t garbage --literally </dev/null) && + + cat >err.expect <<-\EOF && + fatal: invalid object type + EOF + test_must_fail git fsck >out 2>err && + grep -e "^error" -e "^fatal" err >errors && + test_line_count = 1 errors && + grep "$garbage_blob: object is of unknown type '"'"'garbage'"'"':" err + ) +' + test_done |