(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:'git archive --format=zip test' span_id:6))}
          spids: [4]
        )
      ]
    )
    (C {(.)} {(./test-lib.sh)})
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:SUBSTFORMAT)
          op: assign_op.Equal
          rhs: {(Id.Lit_Other '%') (H) (Id.Lit_Other '%') (n)}
          spids: [15]
        )
      ]
    )
    (C {(test_lazy_prereq)} {(UNZIP_SYMLINKS)} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:27) (Token id:Id.Lit_Chars val:'\t(\n' span_id:28) 
          (Token id:Id.Lit_Chars val:'\t\tmkdir unzip-symlinks &&\n' span_id:29) (Token id:Id.Lit_Chars val:'\t\tcd unzip-symlinks &&\n' span_id:30) 
          (Token
            id: Id.Lit_Chars
            val: '\t\t"$GIT_UNZIP" "$TEST_DIRECTORY"/t5003/infozip-symlinks.zip &&\n'
            span_id: 31
          ) (Token id:Id.Lit_Chars val:'\t\ttest -h symlink\n' span_id:32) 
          (Token id:Id.Lit_Chars val:'\t)\n' span_id:33)
        )
      }
    )
    (command.ShFunction
      name: check_zip
      body: 
        (command.BraceGroup
          children: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:zipfile)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number '$1') (.zip)}
                  spids: [44]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:listfile)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number '$1') (.lst)}
                  spids: [49]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:dir)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number '$1')}
                  spids: [54]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:dir_with_prefix)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_DollarName '$dir') (/) ($ Id.VSub_Number '$2')}
                  spids: [58]
                )
              ]
            )
            (C {(test_expect_success)} {(UNZIP)} {(DQ (' extract ZIP archive'))} 
              {
                (SQ (Token id:Id.Lit_Chars val:'\n' span_id:74) 
                  (Token
                    id: Id.Lit_Chars
                    val: '\t\t(mkdir $dir && cd $dir && "$GIT_UNZIP" ../$zipfile)\n'
                    span_id: 75
                  ) (Token id:Id.Lit_Chars val:'\t' span_id:76)
                )
              }
            )
            (C {(test_expect_success)} {(UNZIP)} {(DQ (' validate filenames'))} 
              {
                (DQ ('\n') ('\t\t(cd ') (${ Id.VSub_Name dir_with_prefix) ('a && find .) | sort >') 
                  ($ Id.VSub_DollarName '$listfile') (' &&\n') ('\t\ttest_cmp a.lst ') ($ Id.VSub_DollarName '$listfile') ('\n') ('\t')
                )
              }
            )
            (C {(test_expect_success)} {(UNZIP)} {(DQ (' validate file contents'))} 
              {(DQ ('\n') ('\t\tdiff -r a ') (${ Id.VSub_Name dir_with_prefix) ('a\n') ('\t'))}
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:dir)
                  op: assign_op.Equal
                  rhs: {(eol_) ($ Id.VSub_Number '$1')}
                  spids: [126]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:dir_with_prefix)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_DollarName '$dir') (/) ($ Id.VSub_Number '$2')}
                  spids: [131]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:extracted)
                  op: assign_op.Equal
                  rhs: {(${ Id.VSub_Name dir_with_prefix) (a)}
                  spids: [137]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:original)
                  op: assign_op.Equal
                  rhs: {(a)}
                  spids: [144]
                )
              ]
            )
            (C {(test_expect_success)} {(UNZIP)} {(DQ (' extract ZIP archive with EOL conversion'))} 
              {
                (SQ (Token id:Id.Lit_Chars val:'\n' span_id:158) 
                  (Token
                    id: Id.Lit_Chars
                    val: '\t\t(mkdir $dir && cd $dir && "$GIT_UNZIP" -a ../$zipfile)\n'
                    span_id: 159
                  ) (Token id:Id.Lit_Chars val:'\t' span_id:160)
                )
              }
            )
            (C {(test_expect_success)} {(UNZIP)} {(DQ (' validate that text files are converted'))} 
              {
                (DQ ('\n') ('\t\ttest_cmp_bin ') ($ Id.VSub_DollarName '$extracted') ('/text.cr ') 
                  ($ Id.VSub_DollarName '$extracted') ('/text.crlf &&\n') ('\t\ttest_cmp_bin ') ($ Id.VSub_DollarName '$extracted') ('/text.cr ') 
                  ($ Id.VSub_DollarName '$extracted') ('/text.lf\n') ('\t')
                )
              }
            )
            (C {(test_expect_success)} {(UNZIP)} {(DQ (' validate that binary files are unchanged'))} 
              {
                (DQ ('\n') ('\t\ttest_cmp_bin ') ($ Id.VSub_DollarName '$original') ('/binary.cr   ') 
                  ($ Id.VSub_DollarName '$extracted') ('/binary.cr &&\n') ('\t\ttest_cmp_bin ') ($ Id.VSub_DollarName '$original') ('/binary.crlf ') 
                  ($ Id.VSub_DollarName '$extracted') ('/binary.crlf &&\n') ('\t\ttest_cmp_bin ') ($ Id.VSub_DollarName '$original') ('/binary.lf   ') 
                  ($ Id.VSub_DollarName '$extracted') ('/binary.lf\n') ('\t')
                )
              }
            )
            (C {(test_expect_success)} {(UNZIP)} {(DQ (' validate that diff files are converted'))} 
              {
                (DQ ('\n') ('\t\ttest_cmp_bin ') ($ Id.VSub_DollarName '$extracted') ('/diff.cr ') 
                  ($ Id.VSub_DollarName '$extracted') ('/diff.crlf &&\n') ('\t\ttest_cmp_bin ') ($ Id.VSub_DollarName '$extracted') ('/diff.cr ') 
                  ($ Id.VSub_DollarName '$extracted') ('/diff.lf\n') ('\t')
                )
              }
            )
            (C {(test_expect_success)} {(UNZIP)} {(DQ (' validate that -diff files are unchanged'))} 
              {
                (DQ ('\n') ('\t\ttest_cmp_bin ') ($ Id.VSub_DollarName '$original') ('/nodiff.cr   ') 
                  ($ Id.VSub_DollarName '$extracted') ('/nodiff.cr &&\n') ('\t\ttest_cmp_bin ') ($ Id.VSub_DollarName '$original') ('/nodiff.crlf ') 
                  ($ Id.VSub_DollarName '$extracted') ('/nodiff.crlf &&\n') ('\t\ttest_cmp_bin ') ($ Id.VSub_DollarName '$original') ('/nodiff.lf   ') 
                  ($ Id.VSub_DollarName '$extracted') ('/nodiff.lf\n') ('\t')
                )
              }
            )
          ]
        )
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'populate workdir' span_id:281))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'mkdir a &&\n' span_id:287) 
          (Token id:Id.Lit_Chars val:'     echo simple textfile >a/a &&\n' span_id:288) (Token id:Id.Lit_Chars val:'     mkdir a/bin &&\n' span_id:289) 
          (Token id:Id.Lit_Chars val:'     cp /bin/sh a/bin &&\n' span_id:290) (Token id:Id.Lit_Chars val:'     printf "text\\r"\t>a/text.cr &&\n' span_id:291) 
          (Token
            id: Id.Lit_Chars
            val: '     printf "text\\r\\n"\t>a/text.crlf &&\n'
            span_id: 292
          ) (Token id:Id.Lit_Chars val:'     printf "text\\n"\t>a/text.lf &&\n' span_id:293) 
          (Token
            id: Id.Lit_Chars
            val: '     printf "text\\r"\t>a/nodiff.cr &&\n'
            span_id: 294
          ) (Token id:Id.Lit_Chars val:'     printf "text\\r\\n"\t>a/nodiff.crlf &&\n' span_id:295) 
          (Token
            id: Id.Lit_Chars
            val: '     printf "text\\n"\t>a/nodiff.lf &&\n'
            span_id: 296
          ) (Token id:Id.Lit_Chars val:'     printf "\\0\\r"\t>a/binary.cr &&\n' span_id:297) 
          (Token
            id: Id.Lit_Chars
            val: '     printf "\\0\\r\\n"\t>a/binary.crlf &&\n'
            span_id: 298
          ) (Token id:Id.Lit_Chars val:'     printf "\\0\\n"\t>a/binary.lf &&\n' span_id:299) 
          (Token id:Id.Lit_Chars val:'     printf "\\0\\r"\t>a/diff.cr &&\n' span_id:300) (Token id:Id.Lit_Chars val:'     printf "\\0\\r\\n"\t>a/diff.crlf &&\n' span_id:301) 
          (Token id:Id.Lit_Chars val:'     printf "\\0\\n"\t>a/diff.lf &&\n' span_id:302) 
          (Token
            id: Id.Lit_Chars
            val: '     printf "A\\$Format:%s\\$O" "$SUBSTFORMAT" >a/substfile1 &&\n'
            span_id: 303
          ) (Token id:Id.Lit_Chars val:'     printf "A not substituted O" >a/substfile2 &&\n' span_id:304) 
          (Token
            id: Id.Lit_Chars
            val: '     (p=long_path_to_a_file && cd a &&\n'
            span_id: 305
          ) 
          (Token
            id: Id.Lit_Chars
            val: '      for depth in 1 2 3 4 5; do mkdir $p && cd $p; done &&\n'
            span_id: 306
          ) (Token id:Id.Lit_Chars val:'      echo text >file_with_long_path)\n' span_id:307)
        )
      }
    )
    (C {(test_expect_success)} {(SYMLINKS) (Id.Lit_Comma ',') (UNZIP_SYMLINKS)} 
      {(SQ (Token id:Id.Lit_Chars val:'add symlink' span_id:318))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:322) 
          (Token id:Id.Lit_Chars val:'\tln -s a a/symlink_to_a\n' span_id:323)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'prepare file list' span_id:330))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:334) 
          (Token id:Id.Lit_Chars val:'\t(cd a && find .) | sort >a.lst\n' span_id:335)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'add ignored file' span_id:344))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'echo ignore me >a/ignored &&\n' span_id:350) 
          (Token
            id: Id.Lit_Chars
            val: '     echo ignored export-ignore >.git/info/attributes'
            span_id: 351
          )
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'add files to repository' span_id:358))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:362) 
          (Token id:Id.Lit_Chars val:'\tgit add a &&\n' span_id:363) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_COMMITTER_DATE="2005-05-27 22:00" git commit -m initial\n'
            span_id: 364
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'setup export-subst and diff attributes' span_id:371))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:375) 
          (Token
            id: Id.Lit_Chars
            val: '\techo "a/nodiff.* -diff" >>.git/info/attributes &&\n'
            span_id: 376
          ) (Token id:Id.Lit_Chars val:'\techo "a/diff.* diff" >>.git/info/attributes &&\n' span_id:377) 
          (Token
            id: Id.Lit_Chars
            val: '\techo "substfile?" export-subst >>.git/info/attributes &&\n'
            span_id: 378
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit log --max-count=1 "--pretty=format:A${SUBSTFORMAT}O" HEAD \\\n'
            span_id: 379
          ) (Token id:Id.Lit_Chars val:'\t\t>a/substfile1\n' span_id:380)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'create bare clone' span_id:389))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'git clone --bare . bare.git &&\n' span_id:395) 
          (Token
            id: Id.Lit_Chars
            val: '     cp .git/info/attributes bare.git/info/attributes'
            span_id: 396
          )
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'remove ignored file' span_id:405))} 
      {(SQ (Token id:Id.Lit_Chars val:'rm a/ignored' span_id:411))}
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'git archive --format=zip' span_id:420))} 
      {(SQ (Token id:Id.Lit_Chars val:'git archive --format=zip HEAD >d.zip' span_id:426))}
    )
    (C {(check_zip)} {(d)})
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'git archive --format=zip in a bare repo' span_id:440))} {(SQ (Token id:Id.Lit_Chars val:'(cd bare.git && git archive --format=zip HEAD) >d1.zip' span_id:446))}
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'git archive --format=zip vs. the same in a bare repo'
            span_id: 455
          )
        )
      } {(SQ (Token id:Id.Lit_Chars val:'test_cmp_bin d.zip d1.zip' span_id:461))}
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'git archive --format=zip with --output' span_id:468))} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'git archive --format=zip --output=d2.zip HEAD &&\n'
            span_id: 474
          ) (Token id:Id.Lit_Chars val:'    test_cmp_bin d.zip d2.zip' span_id:475)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'git archive with --output, inferring format' span_id:482))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:486) 
          (Token id:Id.Lit_Chars val:'\tgit archive --output=d3.zip HEAD &&\n' span_id:487) (Token id:Id.Lit_Chars val:'\ttest_cmp_bin d.zip d3.zip\n' span_id:488)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'git archive --format=zip with prefix' span_id:497))} {(SQ (Token id:Id.Lit_Chars val:'git archive --format=zip --prefix=prefix/ HEAD >e.zip' span_id:503))}
    )
    (C {(check_zip)} {(e)} {(prefix/)})
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'git archive -0 --format=zip on large files' span_id:517))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:521) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_config core.bigfilethreshold 1 &&\n'
            span_id: 522
          ) (Token id:Id.Lit_Chars val:'\tgit archive -0 --format=zip HEAD >large.zip\n' span_id:523)
        )
      }
    )
    (C {(check_zip)} {(large)})
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'git archive --format=zip on large files' span_id:535))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:539) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_config core.bigfilethreshold 1 &&\n'
            span_id: 540
          ) (Token id:Id.Lit_Chars val:'\tgit archive --format=zip HEAD >large-compressed.zip\n' span_id:541)
        )
      }
    )
    (C {(check_zip)} {(large-compressed)})
    (C {(test_done)})
  ]
)