(command.CommandList children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:test_description) op: assign_op.Equal rhs: {(SQ (Token id:Id.Lit_Chars val:'test corner cases of git-archive' span_id:6))} spids: [4] ) ] ) (C {(.)} {(./test-lib.sh)}) (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'create commit with empty tree' span_id:17))} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:21) (Token id:Id.Lit_Chars val:'\tgit commit --allow-empty -m foo\n' span_id:22) ) } ) (command.ShFunction name: make_dir body: (command.BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp] children: [ (C {(mkdir)} {(DQ ($ Id.VSub_Number '$1'))}) (C {(test_when_finished)} {(DQ ("rm -rf '") ($ Id.VSub_Number '$1') ("'"))}) ] ) ] ) ) (command.ShFunction name: check_dir body: (command.BraceGroup children: [ (command.Sentence child: (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:dir) op: assign_op.Equal rhs: {($ Id.VSub_Number '$1')} spids: [69] ) ] ) terminator: (Token id:Id.Op_Semi val:';' span_id:71) ) (C {(shift)}) (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp] children: [ (command.Pipeline children: [ (command.BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp] children: [ (C {(echo)} {(DQ ($ Id.VSub_DollarName '$dir'))}) (command.ForEach iter_name: i iter_words: [{(DQ ($ Id.VSub_At '$@'))}] do_arg_iter: F body: (command.DoGroup children: [ (C {(echo)} { (DQ ($ Id.VSub_DollarName '$dir') (/) ($ Id.VSub_DollarName '$i') ) } ) ] ) ) ] ) ] ) (command.Simple words: [{(sort)}] redirects: [ (redir.Redir op: (Token id:Id.Redir_Great val:'>' span_id:120) fd: -1 arg_word: {(expect)} ) ] ) ] negated: F ) (command.Pipeline children: [ (C {(find)} {(DQ ($ Id.VSub_DollarName '$dir'))} {(Id.KW_Bang '!')} {(-name)} {(pax_global_header)} {(-print)} ) (command.Simple words: [{(sort)}] redirects: [ (redir.Redir op: (Token id:Id.Redir_Great val:'>' span_id:144) fd: -1 arg_word: {(actual)} ) ] ) ] negated: F ) (C {(test_cmp)} {(expect)} {(actual)}) ] ) ] ) ) (command.If arms: [ (if_arm cond: [ (command.Simple words: [ {(DQ ($ Id.VSub_DollarName '$TAR'))} {(tf)} {(DQ ($ Id.VSub_DollarName '$TEST_DIRECTORY')) (/t5004/empty-with-pax-header.tar)} ] redirects: [ (redir.Redir op: (Token id:Id.Redir_Great val:'>' span_id:179) fd: -1 arg_word: {(/dev/null)} ) (redir.Redir op: (Token id:Id.Redir_GreatAnd val:'2>&' span_id:182) fd: 2 arg_word: {(1)} ) ] ) ] action: [(C {(test_set_prereq)} {(HEADER_ONLY_TAR_OK)})] spids: [166 185] ) ] ) (C {(test_expect_success)} {(HEADER_ONLY_TAR_OK)} {(SQ (Token id:Id.Lit_Chars val:'tar archive of commit with empty tree' span_id:200))} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:204) (Token id: Id.Lit_Chars val: '\tgit archive --format=tar HEAD >empty-with-pax-header.tar &&\n' span_id: 205 ) (Token id:Id.Lit_Chars val:'\tmake_dir extract &&\n' span_id:206) (Token id: Id.Lit_Chars val: '\t"$TAR" xf empty-with-pax-header.tar -C extract &&\n' span_id: 207 ) (Token id:Id.Lit_Chars val:'\tcheck_dir extract\n' span_id:208) ) } ) (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'tar archive of empty tree is empty' span_id:215))} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:219) (Token id: Id.Lit_Chars val: '\tgit archive --format=tar HEAD: >empty.tar &&\n' span_id: 220 ) (Token id:Id.Lit_Chars val:'\tperl -e "print \\"\\\\0\\" x 10240" >10knuls.tar &&\n' span_id:221) (Token id:Id.Lit_Chars val:'\ttest_cmp_bin 10knuls.tar empty.tar\n' span_id:222) ) } ) (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'tar archive of empty tree with prefix' span_id:229))} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:233) (Token id: Id.Lit_Chars val: '\tgit archive --format=tar --prefix=foo/ HEAD >prefix.tar &&\n' span_id: 234 ) (Token id:Id.Lit_Chars val:'\tmake_dir extract &&\n' span_id:235) (Token id:Id.Lit_Chars val:'\t"$TAR" xf prefix.tar -C extract &&\n' span_id:236) (Token id:Id.Lit_Chars val:'\tcheck_dir extract foo\n' span_id:237) ) } ) (C {(test_expect_success)} {(UNZIP)} {(SQ (Token id:Id.Lit_Chars val:'zip archive of empty tree is empty' span_id:246))} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:250) (Token id: Id.Lit_Chars val: '\t# Detect the exit code produced when our particular flavor of unzip\n' span_id: 251 ) (Token id: Id.Lit_Chars val: '\t# sees an empty archive. Infozip will generate a warning and exit with\n' span_id: 252 ) (Token id: Id.Lit_Chars val: '\t# code 1. But in the name of sanity, we do not expect other unzip\n' span_id: 253 ) (Token id: Id.Lit_Chars val: '\t# implementations to do the same thing (it would be perfectly\n' span_id: 254 ) (Token id:Id.Lit_Chars val:'\t# reasonable to exit 0, for example).\n' span_id:255) (Token id:Id.Lit_Chars val:'\t#\n' span_id:256) (Token id: Id.Lit_Chars val: '\t# This makes our test less rigorous on some platforms (unzip may not\n' span_id: 257 ) (Token id: Id.Lit_Chars val: '\t# handle the empty repo at all, making our later check of its exit code\n' span_id: 258 ) (Token id: Id.Lit_Chars val: '\t# a no-op). But we cannot do anything reasonable except skip the test\n' span_id: 259 ) (Token id: Id.Lit_Chars val: '\t# on such platforms anyway, and this is the moral equivalent.\n' span_id: 260 ) (Token id:Id.Lit_Chars val:'\t{\n' span_id:261) (Token id: Id.Lit_Chars val: '\t\t"$GIT_UNZIP" "$TEST_DIRECTORY"/t5004/empty.zip\n' span_id: 262 ) (Token id:Id.Lit_Chars val:'\t\texpect_code=$?\n' span_id:263) (Token id:Id.Lit_Chars val:'\t} &&\n' span_id:264) (Token id:Id.Lit_Chars val:'\n' span_id:265) (Token id: Id.Lit_Chars val: '\tgit archive --format=zip HEAD >empty.zip &&\n' span_id: 266 ) (Token id:Id.Lit_Chars val:'\tmake_dir extract &&\n' span_id:267) (Token id:Id.Lit_Chars val:'\t(\n' span_id:268) (Token id:Id.Lit_Chars val:'\t\tcd extract &&\n' span_id:269) (Token id: Id.Lit_Chars val: '\t\ttest_expect_code $expect_code "$GIT_UNZIP" ../empty.zip\n' span_id: 270 ) (Token id:Id.Lit_Chars val:'\t) &&\n' span_id:271) (Token id:Id.Lit_Chars val:'\tcheck_dir extract\n' span_id:272) ) } ) (C {(test_expect_success)} {(UNZIP)} {(SQ (Token id:Id.Lit_Chars val:'zip archive of empty tree with prefix' span_id:281))} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:285) (Token id: Id.Lit_Chars val: '\t# We do not have to play exit-code tricks here, because our\n' span_id: 286 ) (Token id:Id.Lit_Chars val:'\t# result should not be empty; it has a directory in it.\n' span_id:287) (Token id: Id.Lit_Chars val: '\tgit archive --format=zip --prefix=foo/ HEAD >prefix.zip &&\n' span_id: 288 ) (Token id:Id.Lit_Chars val:'\tmake_dir extract &&\n' span_id:289) (Token id:Id.Lit_Chars val:'\t(\n' span_id:290) (Token id:Id.Lit_Chars val:'\t\tcd extract &&\n' span_id:291) (Token id:Id.Lit_Chars val:'\t\t"$GIT_UNZIP" ../prefix.zip\n' span_id:292) (Token id:Id.Lit_Chars val:'\t) &&\n' span_id:293) (Token id:Id.Lit_Chars val:'\tcheck_dir extract foo\n' span_id:294) ) } ) (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'archive complains about pathspec on empty tree' span_id:301))} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:305) (Token id: Id.Lit_Chars val: '\ttest_must_fail git archive --format=tar HEAD -- foo >/dev/null\n' span_id: 306 ) ) } ) (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'create a commit with an empty subtree' span_id:313))} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:317) (Token id: Id.Lit_Chars val: '\tempty_tree=$(git hash-object -t tree /dev/null) &&\n' span_id: 318 ) (Token id: Id.Lit_Chars val: '\troot_tree=$(printf "040000 tree $empty_tree\\tsub\\n" | git mktree)\n' span_id: 319 ) ) } ) (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'archive empty subtree with no pathspec' span_id:326))} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:330) (Token id: Id.Lit_Chars val: '\tgit archive --format=tar $root_tree >subtree-all.tar &&\n' span_id: 331 ) (Token id:Id.Lit_Chars val:'\tmake_dir extract &&\n' span_id:332) (Token id: Id.Lit_Chars val: '\t"$TAR" xf subtree-all.tar -C extract &&\n' span_id: 333 ) (Token id:Id.Lit_Chars val:'\tcheck_dir extract sub\n' span_id:334) ) } ) (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'archive empty subtree by direct pathspec' span_id:341))} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:345) (Token id: Id.Lit_Chars val: '\tgit archive --format=tar $root_tree -- sub >subtree-path.tar &&\n' span_id: 346 ) (Token id:Id.Lit_Chars val:'\tmake_dir extract &&\n' span_id:347) (Token id: Id.Lit_Chars val: '\t"$TAR" xf subtree-path.tar -C extract &&\n' span_id: 348 ) (Token id:Id.Lit_Chars val:'\tcheck_dir extract sub\n' span_id:349) ) } ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:ZIPINFO) op: assign_op.Equal rhs: {(zipinfo)} spids: [353] ) ] ) (C {(test_lazy_prereq)} {(ZIPINFO)} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:362) (Token id: Id.Lit_Chars val: '\tn=$("$ZIPINFO" "$TEST_DIRECTORY"/t5004/empty.zip | sed -n "2s/.* //p")\n' span_id: 363 ) (Token id:Id.Lit_Chars val:'\ttest "x$n" = "x0"\n' span_id:364) ) } ) (C {(test_expect_success)} {(ZIPINFO)} {(SQ (Token id:Id.Lit_Chars val:'zip archive with many entries' span_id:373))} { (SQ (Token id:Id.Lit_Chars val:'\n' span_id:377) (Token id:Id.Lit_Chars val:'\t# add a directory with 256 files\n' span_id:378) (Token id:Id.Lit_Chars val:'\tmkdir 00 &&\n' span_id:379) (Token id: Id.Lit_Chars val: '\tfor a in 0 1 2 3 4 5 6 7 8 9 a b c d e f\n' span_id: 380 ) (Token id:Id.Lit_Chars val:'\tdo\n' span_id:381) (Token id: Id.Lit_Chars val: '\t\tfor b in 0 1 2 3 4 5 6 7 8 9 a b c d e f\n' span_id: 382 ) (Token id:Id.Lit_Chars val:'\t\tdo\n' span_id:383) (Token id:Id.Lit_Chars val:'\t\t\t: >00/$a$b\n' span_id:384) (Token id:Id.Lit_Chars val:'\t\tdone\n' span_id:385) (Token id:Id.Lit_Chars val:'\tdone &&\n' span_id:386) (Token id:Id.Lit_Chars val:'\tgit add 00 &&\n' span_id:387) (Token id: Id.Lit_Chars val: '\tgit commit -m "256 files in 1 directory" &&\n' span_id: 388 ) (Token id:Id.Lit_Chars val:'\n' span_id:389) (Token id: Id.Lit_Chars val: '\t# duplicate it to get 65536 files in 256 directories\n' span_id: 390 ) (Token id:Id.Lit_Chars val:'\tsubtree=$(git write-tree --prefix=00/) &&\n' span_id:391) (Token id: Id.Lit_Chars val: '\tfor c in 0 1 2 3 4 5 6 7 8 9 a b c d e f\n' span_id: 392 ) (Token id:Id.Lit_Chars val:'\tdo\n' span_id:393) (Token id: Id.Lit_Chars val: '\t\tfor d in 0 1 2 3 4 5 6 7 8 9 a b c d e f\n' span_id: 394 ) (Token id:Id.Lit_Chars val:'\t\tdo\n' span_id:395) (Token id: Id.Lit_Chars val: '\t\t\techo "040000 tree $subtree\t$c$d"\n' span_id: 396 ) (Token id:Id.Lit_Chars val:'\t\tdone\n' span_id:397) (Token id:Id.Lit_Chars val:'\tdone >tree &&\n' span_id:398) (Token id:Id.Lit_Chars val:'\ttree=$(git mktree <tree) &&\n' span_id:399) (Token id:Id.Lit_Chars val:'\n' span_id:400) (Token id:Id.Lit_Chars val:'\t# zip them\n' span_id:401) (Token id:Id.Lit_Chars val:'\tgit archive -o many.zip $tree &&\n' span_id:402) (Token id:Id.Lit_Chars val:'\n' span_id:403) (Token id: Id.Lit_Chars val: '\t# check the number of entries in the ZIP file directory\n' span_id: 404 ) (Token id:Id.Lit_Chars val:'\texpr 65536 + 256 >expect &&\n' span_id:405) (Token id: Id.Lit_Chars val: '\t"$ZIPINFO" many.zip | head -2 | sed -n "2s/.* //p" >actual &&\n' span_id: 406 ) (Token id:Id.Lit_Chars val:'\ttest_cmp expect actual\n' span_id:407) ) } ) (C {(test_done)}) ] )