diff options
Diffstat (limited to 't/t1450-fsck.sh')
-rwxr-xr-x | t/t1450-fsck.sh | 146 |
1 files changed, 94 insertions, 52 deletions
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 82d128292e..5071ac63a5 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -3,7 +3,7 @@ test_description='git fsck random collection of tests * (HEAD) B -* (master) A +* (main) A ' . ./test-lib.sh @@ -40,22 +40,18 @@ 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 bad sha1' ' sha=$(echo blob | git hash-object -w --stdin) && - old=$(echo $sha | sed "s+^..+&/+") && - new=$(dirname $old)/ffffffffffffffffffffffffffffffffffffff && + 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" && @@ -69,7 +65,6 @@ test_expect_success 'object with bad sha1' ' test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "$sha.*corrupt" out ' @@ -77,17 +72,15 @@ test_expect_success 'branch pointing to non-commit' ' git rev-parse HEAD^{tree} >.git/refs/heads/invalid && test_when_finished "git update-ref -d refs/heads/invalid" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "not a commit" out ' test_expect_success 'HEAD link pointing at a funny object' ' test_when_finished "mv .git/SAVED_HEAD .git/HEAD" && mv .git/HEAD .git/SAVED_HEAD && - echo 0000000000000000000000000000000000000000 >.git/HEAD && + echo $ZERO_OID >.git/HEAD && # avoid corrupt/broken HEAD from interfering with repo discovery test_must_fail env GIT_DIR=.git git fsck 2>out && - cat out && test_i18ngrep "detached HEAD points" out ' @@ -97,7 +90,6 @@ test_expect_success 'HEAD link pointing at a funny place' ' echo "ref: refs/funny/place" >.git/HEAD && # avoid corrupt/broken HEAD from interfering with repo discovery test_must_fail env GIT_DIR=.git git fsck 2>out && - cat out && test_i18ngrep "HEAD points to something strange" out ' @@ -136,6 +128,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 && @@ -144,7 +160,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 ' @@ -156,7 +171,6 @@ test_expect_success 'email with embedded > is not okay' ' git update-ref refs/heads/bogus "$new" && test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "error in commit $new" out ' @@ -168,7 +182,6 @@ test_expect_success 'missing < email delimiter is reported nicely' ' git update-ref refs/heads/bogus "$new" && test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "error in commit $new.* - bad name" out ' @@ -180,7 +193,6 @@ test_expect_success 'missing email is reported nicely' ' git update-ref refs/heads/bogus "$new" && test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "error in commit $new.* - missing email" out ' @@ -192,7 +204,6 @@ test_expect_success '> in name is reported' ' git update-ref refs/heads/bogus "$new" && test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "error in commit $new" out ' @@ -206,7 +217,6 @@ test_expect_success 'integer overflow in timestamps is reported' ' git update-ref refs/heads/bogus "$new" && test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "error in commit $new.*integer overflow" out ' @@ -218,7 +228,6 @@ test_expect_success 'commit with NUL in header' ' git update-ref refs/heads/bogus "$new" && test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "error in commit $new.*unterminated header: NUL at offset" out ' @@ -243,11 +252,46 @@ 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 + junk sha256:twenty-bytes-of-junk-twelve-more + EOF + 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) && + junk=$(test_oid junk) && + tree_sha1=$(printf "100644 \0$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 && @@ -275,8 +319,9 @@ test_expect_success 'tree entry with type mismatch' ' ' test_expect_success 'tag pointing to nonexistent' ' - cat >invalid-tag <<-\EOF && - object ffffffffffffffffffffffffffffffffffffffff + badoid=$(test_oid deadbeef) && + cat >invalid-tag <<-EOF && + object $badoid type commit tag invalid tagger T A Gger <tagger@example.com> 1234567890 -0000 @@ -289,7 +334,6 @@ test_expect_success 'tag pointing to nonexistent' ' echo $tag >.git/refs/tags/invalid && test_when_finished "git update-ref -d refs/tags/invalid" && test_must_fail git fsck --tags >out && - cat out && test_i18ngrep "broken link" out ' @@ -332,7 +376,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' ' @@ -370,7 +414,6 @@ test_expect_success 'tag with NUL in header' ' echo $tag >.git/refs/tags/wrong && test_when_finished "git update-ref -d refs/tags/wrong" && test_must_fail git fsck --tags 2>out && - cat out && test_i18ngrep "error in tag $tag.*unterminated header: NUL at offset" out ' @@ -386,8 +429,8 @@ test_expect_success 'rev-list --verify-objects' ' test_expect_success 'rev-list --verify-objects with bad sha1' ' sha=$(echo blob | git hash-object -w --stdin) && - old=$(echo $sha | sed "s+^..+&/+") && - new=$(dirname $old)/ffffffffffffffffffffffffffffffffffffff && + 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" && @@ -401,8 +444,7 @@ test_expect_success 'rev-list --verify-objects with bad sha1' ' test_when_finished "git update-ref -d refs/heads/bogus" && test_might_fail git rev-list --verify-objects refs/heads/bogus >/dev/null 2>out && - cat out && - test_i18ngrep -q "error: hash mismatch 63ffffffffffffffffffffffffffffffffffffff" out + test_i18ngrep -q "error: hash mismatch $(dirname $new)$(test_oid ff_2)" out ' test_expect_success 'force fsck to ignore double author' ' @@ -417,16 +459,14 @@ test_expect_success 'force fsck to ignore double author' ' ' _bz='\0' -_bz5="$_bz$_bz$_bz$_bz$_bz" -_bz20="$_bz5$_bz5$_bz5$_bz5" +_bzoid=$(printf $ZERO_OID | sed -e 's/00/\\0/g') test_expect_success 'fsck notices blob entry pointing to null sha1' ' (git init null-blob && cd null-blob && - sha=$(printf "100644 file$_bz$_bz20" | + sha=$(printf "100644 file$_bz$_bzoid" | git hash-object -w --stdin -t tree) && git fsck 2>out && - cat out && test_i18ngrep "warning.*null sha1" out ) ' @@ -434,10 +474,9 @@ test_expect_success 'fsck notices blob entry pointing to null sha1' ' test_expect_success 'fsck notices submodule entry pointing to null sha1' ' (git init null-commit && cd null-commit && - sha=$(printf "160000 submodule$_bz$_bz20" | + sha=$(printf "160000 submodule$_bz$_bzoid" | git hash-object -w --stdin -t tree) && git fsck 2>out && - cat out && test_i18ngrep "warning.*null sha1" out ) ' @@ -459,7 +498,6 @@ while read name path pretty; do printf "$mode $type %s\t%s" "$value" "$path" >bad && bad_tree=$(git mktree <bad) && git fsck 2>out && - cat out && test_i18ngrep "warning.*tree $bad_tree" out )' done <<-\EOF @@ -587,7 +625,7 @@ test_expect_success 'fsck --connectivity-only' ' # its type. That lets us see that --connectivity-only is # not actually looking at the contents, but leaves it # free to examine the type if it chooses. - empty=.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 && + empty=.git/objects/$(test_oid_to_path $EMPTY_BLOB) && blob=$(echo unrelated | git hash-object -w --stdin) && mv -f $(sha1_file $blob) $empty && @@ -620,22 +658,26 @@ 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 -E "$tree \((refs/heads/master|HEAD)@\{[0-9]*\}:" out + git tag -d julius && + test_must_fail git fsck --name-objects >out && + test_i18ngrep "$tree (refs/tags/augustus44\\^:" out ) ' test_expect_success 'alternate objects are correctly blamed' ' test_when_finished "rm -rf alt.git .git/objects/info/alternates" && + name=$(test_oid numeric) && + path=$(test_oid_to_path "$name") && git init --bare alt.git && echo "../../alt.git/objects" >.git/objects/info/alternates && - mkdir alt.git/objects/12 && - >alt.git/objects/12/34567890123456789012345678901234567890 && + mkdir alt.git/objects/$(dirname $path) && + >alt.git/objects/$(dirname $path)/$(basename $path) && test_must_fail git fsck >out 2>&1 && test_i18ngrep alt.git out ' @@ -669,7 +711,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 && @@ -762,7 +804,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 ) ' @@ -772,7 +814,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 ) ' |