(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)})
  ]
)