(command.CommandList children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:test_description) op: assign_op.Equal rhs: { (SQ <'git fsck random collection of tests\n'> <'\n'> <'* (HEAD) B\n'> <'* (master) A\n'>) } spids: [4] ) ] ) (C {<.>} {<'./test-lib.sh'>}) (C {<test_expect_success>} {<setup>} { (SQ <'\n'> <'\tgit config gc.auto 0 &&\n'> <'\tgit config i18n.commitencoding ISO-8859-1 &&\n'> <'\ttest_commit A fileA one &&\n'> <'\tgit config --unset i18n.commitencoding &&\n'> <'\tgit checkout HEAD^0 &&\n'> <'\ttest_commit B fileB two &&\n'> <'\tgit tag -d A B &&\n'> <'\tgit reflog expire --expire=now --all &&\n'> <'\t>empty\n'> ) } ) (C {<test_expect_success>} {(SQ <'loose objects borrowed from alternate are not missing'>)} { (SQ <'\n'> <'\tmkdir another &&\n'> <'\t(\n'> <'\t\tcd another &&\n'> <'\t\tgit init &&\n'> <'\t\techo ../../../.git/objects >.git/objects/info/alternates &&\n'> <'\t\ttest_commit C fileC one &&\n'> <'\t\tgit fsck --no-dangling >../actual 2>&1\n'> <'\t) &&\n'> <'\ttest_cmp empty actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'HEAD is part of refs, valid objects appear valid'>)} {(SQ <'\n'> <'\tgit fsck >actual 2>&1 &&\n'> <'\ttest_cmp empty actual\n'>)} ) (C {<test_expect_success>} {(SQ <'setup: helpers for corruption tests'>)} { (SQ <'\n'> <'\tsha1_file() {\n'> <'\t\techo "$*" | sed "s#..#.git/objects/&/#"\n'> <'\t} &&\n'> <'\n'> <'\tremove_object() {\n'> <'\t\tfile=$(sha1_file "$*") &&\n'> <'\t\ttest -e "$file" &&\n'> <'\t\trm -f "$file"\n'> <'\t}\n'> ) } ) (C {<test_expect_success>} {(SQ <'object with bad sha1'>)} { (SQ <'\n'> <'\tsha=$(echo blob | git hash-object -w --stdin) &&\n'> <'\told=$(echo $sha | sed "s+^..+&/+") &&\n'> <'\tnew=$(dirname $old)/ffffffffffffffffffffffffffffffffffffff &&\n'> <'\tsha="$(dirname $new)$(basename $new)" &&\n'> <'\tmv .git/objects/$old .git/objects/$new &&\n'> <'\ttest_when_finished "remove_object $sha" &&\n'> <'\tgit update-index --add --cacheinfo 100644 $sha foo &&\n'> <'\ttest_when_finished "git read-tree -u --reset HEAD" &&\n'> <'\ttree=$(git write-tree) &&\n'> <'\ttest_when_finished "remove_object $tree" &&\n'> <'\tcmt=$(echo bogus | git commit-tree $tree) &&\n'> <'\ttest_when_finished "remove_object $cmt" &&\n'> <'\tgit update-ref refs/heads/bogus $cmt &&\n'> <'\ttest_when_finished "git update-ref -d refs/heads/bogus" &&\n'> <'\n'> <'\ttest_must_fail git fsck 2>out &&\n'> <'\tcat out &&\n'> <'\tgrep "$sha.*corrupt" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'branch pointing to non-commit'>)} { (SQ <'\n'> <'\tgit rev-parse HEAD^{tree} >.git/refs/heads/invalid &&\n'> <'\ttest_when_finished "git update-ref -d refs/heads/invalid" &&\n'> <'\ttest_must_fail git fsck 2>out &&\n'> <'\tcat out &&\n'> <'\tgrep "not a commit" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'HEAD link pointing at a funny object'>)} { (SQ <'\n'> <'\ttest_when_finished "mv .git/SAVED_HEAD .git/HEAD" &&\n'> <'\tmv .git/HEAD .git/SAVED_HEAD &&\n'> <'\techo 0000000000000000000000000000000000000000 >.git/HEAD &&\n'> <'\t# avoid corrupt/broken HEAD from interfering with repo discovery\n'> <'\ttest_must_fail env GIT_DIR=.git git fsck 2>out &&\n'> <'\tcat out &&\n'> <'\tgrep "detached HEAD points" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'HEAD link pointing at a funny place'>)} { (SQ <'\n'> <'\ttest_when_finished "mv .git/SAVED_HEAD .git/HEAD" &&\n'> <'\tmv .git/HEAD .git/SAVED_HEAD &&\n'> <'\techo "ref: refs/funny/place" >.git/HEAD &&\n'> <'\t# avoid corrupt/broken HEAD from interfering with repo discovery\n'> <'\ttest_must_fail env GIT_DIR=.git git fsck 2>out &&\n'> <'\tcat out &&\n'> <'\tgrep "HEAD points to something strange" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'email without @ is okay'>)} { (SQ <'\n'> <'\tgit cat-file commit HEAD >basis &&\n'> <'\tsed "s/@/AT/" basis >okay &&\n'> <'\tnew=$(git hash-object -t commit -w --stdin <okay) &&\n'> <'\ttest_when_finished "remove_object $new" &&\n'> <'\tgit update-ref refs/heads/bogus "$new" &&\n'> <'\ttest_when_finished "git update-ref -d refs/heads/bogus" &&\n'> <'\tgit fsck 2>out &&\n'> <'\tcat out &&\n'> <'\t! grep "commit $new" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'email with embedded > is not okay'>)} { (SQ <'\n'> <'\tgit cat-file commit HEAD >basis &&\n'> <'\tsed "s/@[a-z]/&>/" basis >bad-email &&\n'> <'\tnew=$(git hash-object -t commit -w --stdin <bad-email) &&\n'> <'\ttest_when_finished "remove_object $new" &&\n'> <'\tgit update-ref refs/heads/bogus "$new" &&\n'> <'\ttest_when_finished "git update-ref -d refs/heads/bogus" &&\n'> <'\ttest_must_fail git fsck 2>out &&\n'> <'\tcat out &&\n'> <'\tgrep "error in commit $new" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'missing < email delimiter is reported nicely'>)} { (SQ <'\n'> <'\tgit cat-file commit HEAD >basis &&\n'> <'\tsed "s/<//" basis >bad-email-2 &&\n'> <'\tnew=$(git hash-object -t commit -w --stdin <bad-email-2) &&\n'> <'\ttest_when_finished "remove_object $new" &&\n'> <'\tgit update-ref refs/heads/bogus "$new" &&\n'> <'\ttest_when_finished "git update-ref -d refs/heads/bogus" &&\n'> <'\ttest_must_fail git fsck 2>out &&\n'> <'\tcat out &&\n'> <'\tgrep "error in commit $new.* - bad name" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'missing email is reported nicely'>)} { (SQ <'\n'> <'\tgit cat-file commit HEAD >basis &&\n'> <'\tsed "s/[a-z]* <[^>]*>//" basis >bad-email-3 &&\n'> <'\tnew=$(git hash-object -t commit -w --stdin <bad-email-3) &&\n'> <'\ttest_when_finished "remove_object $new" &&\n'> <'\tgit update-ref refs/heads/bogus "$new" &&\n'> <'\ttest_when_finished "git update-ref -d refs/heads/bogus" &&\n'> <'\ttest_must_fail git fsck 2>out &&\n'> <'\tcat out &&\n'> <'\tgrep "error in commit $new.* - missing email" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'> in name is reported'>)} { (SQ <'\n'> <'\tgit cat-file commit HEAD >basis &&\n'> <'\tsed "s/ </> </" basis >bad-email-4 &&\n'> <'\tnew=$(git hash-object -t commit -w --stdin <bad-email-4) &&\n'> <'\ttest_when_finished "remove_object $new" &&\n'> <'\tgit update-ref refs/heads/bogus "$new" &&\n'> <'\ttest_when_finished "git update-ref -d refs/heads/bogus" &&\n'> <'\ttest_must_fail git fsck 2>out &&\n'> <'\tcat out &&\n'> <'\tgrep "error in commit $new" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'integer overflow in timestamps is reported'>)} { (SQ <'\n'> <'\tgit cat-file commit HEAD >basis &&\n'> <'\tsed "s/^\\\\(author .*>\\\\) [0-9]*/\\\\1 18446744073709551617/" \\\n'> <'\t\t<basis >bad-timestamp &&\n'> <'\tnew=$(git hash-object -t commit -w --stdin <bad-timestamp) &&\n'> <'\ttest_when_finished "remove_object $new" &&\n'> <'\tgit update-ref refs/heads/bogus "$new" &&\n'> <'\ttest_when_finished "git update-ref -d refs/heads/bogus" &&\n'> <'\ttest_must_fail git fsck 2>out &&\n'> <'\tcat out &&\n'> <'\tgrep "error in commit $new.*integer overflow" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'commit with NUL in header'>)} { (SQ <'\n'> <'\tgit cat-file commit HEAD >basis &&\n'> <'\tsed "s/author ./author Q/" <basis | q_to_nul >commit-NUL-header &&\n'> <'\tnew=$(git hash-object -t commit -w --stdin <commit-NUL-header) &&\n'> <'\ttest_when_finished "remove_object $new" &&\n'> <'\tgit update-ref refs/heads/bogus "$new" &&\n'> <'\ttest_when_finished "git update-ref -d refs/heads/bogus" &&\n'> <'\ttest_must_fail git fsck 2>out &&\n'> <'\tcat out &&\n'> <'\tgrep "error in commit $new.*unterminated header: NUL at offset" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'tree object with duplicate entries'>)} { (SQ <'\n'> <'\ttest_when_finished "remove_object \\$T" &&\n'> <'\tT=$(\n'> <'\t\tGIT_INDEX_FILE=test-index &&\n'> <'\t\texport GIT_INDEX_FILE &&\n'> <'\t\trm -f test-index &&\n'> <'\t\t>x &&\n'> <'\t\tgit add x &&\n'> <'\t\tT=$(git write-tree) &&\n'> <'\t\t(\n'> <'\t\t\tgit cat-file tree $T &&\n'> <'\t\t\tgit cat-file tree $T\n'> <'\t\t) |\n'> <'\t\tgit hash-object -w -t tree --stdin\n'> <'\t) &&\n'> <'\ttest_must_fail git fsck 2>out &&\n'> <'\tgrep "error in tree .*contains duplicate file entries" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'unparseable tree object'>)} { (SQ <'\n'> <'\ttest_when_finished "git update-ref -d refs/heads/wrong" &&\n'> <'\ttest_when_finished "remove_object \\$tree_sha1" &&\n'> <'\ttest_when_finished "remove_object \\$commit_sha1" &&\n'> < '\ttree_sha1=$(printf "100644 \\0twenty-bytes-of-junk" | git hash-object -t tree --stdin -w --literally) &&\n' > <'\tcommit_sha1=$(git commit-tree $tree_sha1) &&\n'> <'\tgit update-ref refs/heads/wrong $commit_sha1 &&\n'> <'\ttest_must_fail git fsck 2>out &&\n'> <'\ttest_i18ngrep "error: empty filename in tree entry" out &&\n'> <'\ttest_i18ngrep "$tree_sha1" out &&\n'> <'\ttest_i18ngrep ! "fatal: empty filename in tree entry" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'tag pointing to nonexistent'>)} { (SQ <'\n'> <'\tcat >invalid-tag <<-\\EOF &&\n'> <'\tobject ffffffffffffffffffffffffffffffffffffffff\n'> <'\ttype commit\n'> <'\ttag invalid\n'> <'\ttagger T A Gger <tagger@example.com> 1234567890 -0000\n'> <'\n'> <'\tThis is an invalid tag.\n'> <'\tEOF\n'> <'\n'> <'\ttag=$(git hash-object -t tag -w --stdin <invalid-tag) &&\n'> <'\ttest_when_finished "remove_object $tag" &&\n'> <'\techo $tag >.git/refs/tags/invalid &&\n'> <'\ttest_when_finished "git update-ref -d refs/tags/invalid" &&\n'> <'\ttest_must_fail git fsck --tags >out &&\n'> <'\tcat out &&\n'> <'\tgrep "broken link" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'tag pointing to something else than its type'>)} { (SQ <'\n'> <'\tsha=$(echo blob | git hash-object -w --stdin) &&\n'> <'\ttest_when_finished "remove_object $sha" &&\n'> <'\tcat >wrong-tag <<-EOF &&\n'> <'\tobject $sha\n'> <'\ttype commit\n'> <'\ttag wrong\n'> <'\ttagger T A Gger <tagger@example.com> 1234567890 -0000\n'> <'\n'> <'\tThis is an invalid tag.\n'> <'\tEOF\n'> <'\n'> <'\ttag=$(git hash-object -t tag -w --stdin <wrong-tag) &&\n'> <'\ttest_when_finished "remove_object $tag" &&\n'> <'\techo $tag >.git/refs/tags/wrong &&\n'> <'\ttest_when_finished "git update-ref -d refs/tags/wrong" &&\n'> <'\ttest_must_fail git fsck --tags\n'> ) } ) (C {<test_expect_success>} {(SQ <'tag with incorrect tag name & missing tagger'>)} { (SQ <'\n'> <'\tsha=$(git rev-parse HEAD) &&\n'> <'\tcat >wrong-tag <<-EOF &&\n'> <'\tobject $sha\n'> <'\ttype commit\n'> <'\ttag wrong name format\n'> <'\n'> <'\tThis is an invalid tag.\n'> <'\tEOF\n'> <'\n'> <'\ttag=$(git hash-object -t tag -w --stdin <wrong-tag) &&\n'> <'\ttest_when_finished "remove_object $tag" &&\n'> <'\techo $tag >.git/refs/tags/wrong &&\n'> <'\ttest_when_finished "git update-ref -d refs/tags/wrong" &&\n'> <'\tgit fsck --tags 2>out &&\n'> <'\n'> <'\tcat >expect <<-EOF &&\n'> <'\twarning in tag $tag: badTagName: invalid '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <tag>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <' name: wrong name format\n'> <'\twarning in tag $tag: missingTaggerEntry: invalid format - expected '> ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <tagger>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) (SQ <' line\n'> <'\tEOF\n'> <'\ttest_cmp expect out\n'>) } ) (C {<test_expect_success>} {(SQ <'tag with bad tagger'>)} { (SQ <'\n'> <'\tsha=$(git rev-parse HEAD) &&\n'> <'\tcat >wrong-tag <<-EOF &&\n'> <'\tobject $sha\n'> <'\ttype commit\n'> <'\ttag not-quite-wrong\n'> <'\ttagger Bad Tagger Name\n'> <'\n'> <'\tThis is an invalid tag.\n'> <'\tEOF\n'> <'\n'> <'\ttag=$(git hash-object --literally -t tag -w --stdin <wrong-tag) &&\n'> <'\ttest_when_finished "remove_object $tag" &&\n'> <'\techo $tag >.git/refs/tags/wrong &&\n'> <'\ttest_when_finished "git update-ref -d refs/tags/wrong" &&\n'> <'\ttest_must_fail git fsck --tags 2>out &&\n'> <'\tgrep "error in tag .*: invalid author/committer" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'tag with NUL in header'>)} { (SQ <'\n'> <'\tsha=$(git rev-parse HEAD) &&\n'> <'\tq_to_nul >tag-NUL-header <<-EOF &&\n'> <'\tobject $sha\n'> <'\ttype commit\n'> <'\ttag contains-Q-in-header\n'> <'\ttagger T A Gger <tagger@example.com> 1234567890 -0000\n'> <'\n'> <'\tThis is an invalid tag.\n'> <'\tEOF\n'> <'\n'> <'\ttag=$(git hash-object --literally -t tag -w --stdin <tag-NUL-header) &&\n'> <'\ttest_when_finished "remove_object $tag" &&\n'> <'\techo $tag >.git/refs/tags/wrong &&\n'> <'\ttest_when_finished "git update-ref -d refs/tags/wrong" &&\n'> <'\ttest_must_fail git fsck --tags 2>out &&\n'> <'\tcat out &&\n'> <'\tgrep "error in tag $tag.*unterminated header: NUL at offset" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'cleaned up'>)} {(SQ <'\n'> <'\tgit fsck >actual 2>&1 &&\n'> <'\ttest_cmp empty actual\n'>)} ) (C {<test_expect_success>} {(SQ <'rev-list --verify-objects'>)} { (SQ <'\n'> <'\tgit rev-list --verify-objects --all >/dev/null 2>out &&\n'> <'\ttest_cmp empty out\n'> ) } ) (C {<test_expect_success>} {(SQ <'rev-list --verify-objects with bad sha1'>)} { (SQ <'\n'> <'\tsha=$(echo blob | git hash-object -w --stdin) &&\n'> <'\told=$(echo $sha | sed "s+^..+&/+") &&\n'> <'\tnew=$(dirname $old)/ffffffffffffffffffffffffffffffffffffff &&\n'> <'\tsha="$(dirname $new)$(basename $new)" &&\n'> <'\tmv .git/objects/$old .git/objects/$new &&\n'> <'\ttest_when_finished "remove_object $sha" &&\n'> <'\tgit update-index --add --cacheinfo 100644 $sha foo &&\n'> <'\ttest_when_finished "git read-tree -u --reset HEAD" &&\n'> <'\ttree=$(git write-tree) &&\n'> <'\ttest_when_finished "remove_object $tree" &&\n'> <'\tcmt=$(echo bogus | git commit-tree $tree) &&\n'> <'\ttest_when_finished "remove_object $cmt" &&\n'> <'\tgit update-ref refs/heads/bogus $cmt &&\n'> <'\ttest_when_finished "git update-ref -d refs/heads/bogus" &&\n'> <'\n'> <'\ttest_might_fail git rev-list --verify-objects refs/heads/bogus >/dev/null 2>out &&\n'> <'\tcat out &&\n'> <'\tgrep -q "error: sha1 mismatch 63ffffffffffffffffffffffffffffffffffffff" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'force fsck to ignore double author'>)} { (SQ <'\n'> <'\tgit cat-file commit HEAD >basis &&\n'> <'\tsed "s/^author .*/&,&/" <basis | tr , \\\\n >multiple-authors &&\n'> <'\tnew=$(git hash-object -t commit -w --stdin <multiple-authors) &&\n'> <'\ttest_when_finished "remove_object $new" &&\n'> <'\tgit update-ref refs/heads/bogus "$new" &&\n'> <'\ttest_when_finished "git update-ref -d refs/heads/bogus" &&\n'> <'\ttest_must_fail git fsck &&\n'> <'\tgit -c fsck.multipleAuthors=ignore fsck\n'> ) } ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:_bz) op: assign_op.Equal rhs: {(SQ <'\\0'>)} spids: [602] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:_bz5) op: assign_op.Equal rhs: { (DQ ($ Id.VSub_DollarName '$_bz') ($ Id.VSub_DollarName '$_bz') ($ Id.VSub_DollarName '$_bz') ($ Id.VSub_DollarName '$_bz') ($ Id.VSub_DollarName '$_bz') ) } spids: [607] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:_bz20) op: assign_op.Equal rhs: { (DQ ($ Id.VSub_DollarName '$_bz5') ($ Id.VSub_DollarName '$_bz5') ($ Id.VSub_DollarName '$_bz5') ($ Id.VSub_DollarName '$_bz5') ) } spids: [616] ) ] ) (C {<test_expect_success>} {(SQ <'fsck notices blob entry pointing to null sha1'>)} { (SQ <'\n'> <'\t(git init null-blob &&\n'> <'\t cd null-blob &&\n'> <'\t sha=$(printf "100644 file$_bz$_bz20" |\n'> <'\t git hash-object -w --stdin -t tree) &&\n'> <'\t git fsck 2>out &&\n'> <'\t cat out &&\n'> <'\t grep "warning.*null sha1" out\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'fsck notices submodule entry pointing to null sha1'>)} { (SQ <'\n'> <'\t(git init null-commit &&\n'> <'\t cd null-commit &&\n'> <'\t sha=$(printf "160000 submodule$_bz$_bz20" |\n'> <'\t git hash-object -w --stdin -t tree) &&\n'> <'\t git fsck 2>out &&\n'> <'\t cat out &&\n'> <'\t grep "warning.*null sha1" out\n'> <'\t)\n'> ) } ) (command.WhileUntil keyword: <Id.KW_While while> cond: [ (command.Sentence child: (C {<read>} {<name>} {<path>} {<pretty>}) terminator: <Id.Op_Semi _> ) ] body: (command.DoGroup children: [ (command.WhileUntil keyword: <Id.KW_While while> cond: [(command.Sentence child:(C {<read>} {<mode>} {<type>}) terminator:<Id.Op_Semi _>)] body: (command.DoGroup children: [ (C {<Id.Lit_Colon ':'>} { (braced_var_sub token: <Id.VSub_Name pretty> suffix_op: (suffix_op.Unary op_id: Id.VTest_ColonEquals arg_word: {($ Id.VSub_DollarName '$path')} ) ) } ) (C {<test_expect_success>} { (DQ <'fsck notices '> ($ Id.VSub_DollarName '$pretty') <' as '> ($ Id.VSub_DollarName '$type') ) } { (SQ <'\n'> <'\t\t(\n'> <'\t\t\tgit init $name-$type &&\n'> <'\t\t\tcd $name-$type &&\n'> <'\t\t\techo content >file &&\n'> <'\t\t\tgit add file &&\n'> <'\t\t\tgit commit -m base &&\n'> <'\t\t\tblob=$(git rev-parse :file) &&\n'> <'\t\t\ttree=$(git rev-parse HEAD^{tree}) &&\n'> <'\t\t\tvalue=$(eval "echo \\$$type") &&\n'> <'\t\t\tprintf "$mode $type %s\\t%s" "$value" "$path" >bad &&\n'> <'\t\t\tbad_tree=$(git mktree <bad) &&\n'> <'\t\t\tgit fsck 2>out &&\n'> <'\t\t\tcat out &&\n'> <'\t\t\tgrep "warning.*tree $bad_tree" out\n'> <'\t\t)'> ) } ) ] ) redirects: [ (redir op: <Id.Redir_DLessDash '<<-'> loc: (redir_loc.Fd fd:0) arg: (redir_param.MultiLine here_begin: {(word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\E'>) <OF>} here_end_span_id: 735 stdin_parts: [<'100644 blob\n'> <'040000 tree\n'>] ) ) ] ) ] ) redirects: [ (redir op: <Id.Redir_DLessDash '<<-'> loc: (redir_loc.Fd fd:0) arg: (redir_param.MultiLine here_begin: {<EOF>} here_end_span_id: 765 stdin_parts: [ <'dot .\n'> <'dotdot ..\n'> <'dotgit .git\n'> <'dotgit-case .GIT\n'> <'dotgit-unicode .gI'> (${ Id.VSub_Name u200c) <'T .gI{u200c}T\n'> <'dotgit-case2 .Git\n'> <'git-tilde1 git~1\n'> <'dotgitdot .git.\n'> <'dot-backslash-case .'> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\\'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\\'>) <.GIT> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\\'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\\'>) <'foobar\n'> <'dotgit-case-backslash .git'> (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\\'>) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\\'>) <'foobar\n'> ] ) ) ] ) (C {<test_expect_success>} {(SQ <'fsck allows .Ňit'>)} { (SQ <'\n'> <'\t(\n'> <'\t\tgit init not-dotgit &&\n'> <'\t\tcd not-dotgit &&\n'> <'\t\techo content >file &&\n'> <'\t\tgit add file &&\n'> <'\t\tgit commit -m base &&\n'> <'\t\tblob=$(git rev-parse :file) &&\n'> <'\t\tprintf "100644 blob $blob\\t.\\\\305\\\\207it" >tree &&\n'> <'\t\ttree=$(git mktree <tree) &&\n'> <'\t\tgit fsck 2>err &&\n'> <'\t\ttest_line_count = 0 err\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'NUL in commit'>)} { (SQ <'\n'> <'\trm -fr nul-in-commit &&\n'> <'\tgit init nul-in-commit &&\n'> <'\t(\n'> <'\t\tcd nul-in-commit &&\n'> <'\t\tgit commit --allow-empty -m "initial commitQNUL after message" &&\n'> <'\t\tgit cat-file commit HEAD >original &&\n'> <'\t\tq_to_nul <original >munged &&\n'> <'\t\tgit hash-object -w -t commit --stdin <munged >name &&\n'> <'\t\tgit branch bad $(cat name) &&\n'> <'\n'> <'\t\ttest_must_fail git -c fsck.nulInCommit=error fsck 2>warn.1 &&\n'> <'\t\tgrep nulInCommit warn.1 &&\n'> <'\t\tgit fsck 2>warn.2 &&\n'> <'\t\tgrep nulInCommit warn.2\n'> <'\t)\n'> ) } ) (command.ShFunction name: create_repo_missing body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp] children: [ (C {<rm>} {<-rf>} {<missing>}) (C {<git>} {<init>} {<missing>}) (command.Subshell child: (command.AndOr ops: [ Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp ] children: [ (C {<cd>} {<missing>}) (C {<git>} {<commit>} {<-m>} {<one>} {<--allow-empty>}) (C {<mkdir>} {<subdir>}) (command.Simple words: [{<echo>} {<content>}] redirects: [ (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<'subdir/file'>} ) ] do_fork: T ) (C {<git>} {<add>} {<'subdir/file'>}) (C {<git>} {<commit>} {<-m>} {<two>}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:unrelated) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (command.Pipeline children: [ (C {<echo>} {<unrelated>}) (C {<git>} {<hash-object>} {<--stdin>} {<-w>}) ] negated: F ) ) } spids: [911] ) ] ) (C {<git>} {<tag>} {<-m>} {<foo>} {<tag>} {($ Id.VSub_DollarName '$unrelated')}) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:sha1) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<git>} {<rev-parse>} {<--verify>} {(DQ ($ Id.VSub_Number '$1'))}) ) } spids: [946] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:path) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (command.Pipeline children: [ (C {<echo>} {($ Id.VSub_DollarName '$sha1')}) (C {<sed>} {(SQ <'s|..|&/|'>)}) ] negated: F ) ) } spids: [962] ) ] ) (C {<rm>} {<'.git/objects/'> ($ Id.VSub_DollarName '$path')}) ] ) ) ] ) ] ) ) (C {<test_expect_success>} {(SQ <'fsck notices missing blob'>)} { (SQ <'\n'> <'\tcreate_repo_missing HEAD:subdir/file &&\n'> <'\ttest_must_fail git -C missing fsck\n'> ) } ) (C {<test_expect_success>} {(SQ <'fsck notices missing subtree'>)} { (SQ <'\n'> <'\tcreate_repo_missing HEAD:subdir &&\n'> <'\ttest_must_fail git -C missing fsck\n'> ) } ) (C {<test_expect_success>} {(SQ <'fsck notices missing root tree'>)} { (SQ <'\n'> <'\tcreate_repo_missing HEAD^{tree} &&\n'> <'\ttest_must_fail git -C missing fsck\n'> ) } ) (C {<test_expect_success>} {(SQ <'fsck notices missing parent'>)} {(SQ <'\n'> <'\tcreate_repo_missing HEAD^ &&\n'> <'\ttest_must_fail git -C missing fsck\n'>)} ) (C {<test_expect_success>} {(SQ <'fsck notices missing tagged object'>)} { (SQ <'\n'> <'\tcreate_repo_missing tag^{blob} &&\n'> <'\ttest_must_fail git -C missing fsck\n'>) } ) (C {<test_expect_success>} {(SQ <'fsck notices ref pointing to missing commit'>)} {(SQ <'\n'> <'\tcreate_repo_missing HEAD &&\n'> <'\ttest_must_fail git -C missing fsck\n'>)} ) (C {<test_expect_success>} {(SQ <'fsck notices ref pointing to missing tag'>)} {(SQ <'\n'> <'\tcreate_repo_missing tag &&\n'> <'\ttest_must_fail git -C missing fsck\n'>)} ) (C {<test_expect_success>} {(SQ <'fsck --connectivity-only'>)} { (SQ <'\n'> <'\trm -rf connectivity-only &&\n'> <'\tgit init connectivity-only &&\n'> <'\t(\n'> <'\t\tcd connectivity-only &&\n'> <'\t\ttouch empty &&\n'> <'\t\tgit add empty &&\n'> <'\t\ttest_commit empty &&\n'> <'\t\tempty=.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 &&\n'> <'\t\trm -f $empty &&\n'> <'\t\techo invalid >$empty &&\n'> <'\t\ttest_must_fail git fsck --strict &&\n'> <'\t\tgit fsck --strict --connectivity-only &&\n'> <'\t\ttree=$(git rev-parse HEAD:) &&\n'> <'\t\tsuffix=${tree#??} &&\n'> <'\t\ttree=.git/objects/${tree%$suffix}/$suffix &&\n'> <'\t\trm -f $tree &&\n'> <'\t\techo invalid >$tree &&\n'> <'\t\ttest_must_fail git fsck --strict --connectivity-only\n'> <'\t)\n'> ) } ) (command.ShFunction name: remove_loose_object body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp] children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:sha1) op: assign_op.Equal rhs: { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<git>} {<rev-parse>} {(DQ ($ Id.VSub_Number '$1'))}) ) ) } spids: [1120] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:remainder) op: assign_op.Equal rhs: { (braced_var_sub token: <Id.VSub_Name sha1> suffix_op: (suffix_op.Unary op_id:Id.VOp1_Pound arg_word:{<'??'>}) ) } spids: [1136] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:firsttwo) op: assign_op.Equal rhs: { (braced_var_sub token: <Id.VSub_Name sha1> suffix_op: (suffix_op.Unary op_id: Id.VOp1_Percent arg_word: {($ Id.VSub_DollarName '$remainder')} ) ) } spids: [1146] ) ] ) (C {<rm>} {<'.git/objects/'> ($ Id.VSub_DollarName '$firsttwo') <'/'> ($ Id.VSub_DollarName '$remainder') } ) ] ) ] ) ) (C {<test_expect_success>} {(SQ <'fsck --name-objects'>)} { (SQ <'\n'> <'\trm -rf name-objects &&\n'> <'\tgit init name-objects &&\n'> <'\t(\n'> <'\t\tcd name-objects &&\n'> <'\t\ttest_commit julius caesar.t &&\n'> <'\t\ttest_commit augustus &&\n'> <'\t\ttest_commit caesar &&\n'> <'\t\tremove_loose_object $(git rev-parse julius:caesar.t) &&\n'> <'\t\ttest_must_fail git fsck --name-objects >out &&\n'> <'\t\ttree=$(git rev-parse --verify julius:) &&\n'> <'\t\tgrep "$tree (\\(refs/heads/master\\|HEAD\\)@{[0-9]*}:" out\n'> <'\t)\n'> ) } ) (C {<test_done>}) ] )