(CommandList
  children: [
    (Assignment
      keyword: Assign_None
      pairs: [
        (assign_pair
          lhs: (LhsName name:test_description)
          op: Equal
          rhs: 
            {
              (SQ <"git archive and git get-tar-commit-id test\n"> <"\n"> 
                <"This test covers the topics of file contents, commit date handling and\n"> <"commit id embedding:\n"> <"\n"> 
                <"  The contents of the repository is compared to the extracted tar\n"> <"  archive.  The repository contains simple text files, symlinks and a\n"> 
                <"  binary file (/bin/sh).  Only paths shorter than 99 characters are\n"> <"  used.\n"> <"\n"> <"  git archive applies the commit date to every file in the archive it\n"> 
                <"  creates.  The test sets the commit date to a specific value and checks\n"> <"  if the tar archive contains that value.\n"> <"\n"> 
                <"  When giving git archive a commit id (in contrast to a tree id) it\n"> <"  embeds this commit id into the tar archive as a comment.  The test\n"> 
                <"  checks the ability of git get-tar-commit-id to figure it out from the\n"> <"  tar file.\n"> <"\n">
              )
            }
          spids: [13]
        )
      ]
      spids: [13]
    )
    (C {(.)} {(./test-lib.sh)})
    (Assignment
      keyword: Assign_None
      pairs: [
        (assign_pair
          lhs: (LhsName name:SUBSTFORMAT)
          op: Equal
          rhs: {(Lit_Other "%") (H) (Lit_Other "%") (n)}
          spids: [42]
        )
      ]
      spids: [42]
    )
    (C {(test_lazy_prereq)} {(TAR_NEEDS_PAX_FALLBACK)} 
      {
        (SQ <"\n"> <"\t(\n"> <"\t\tmkdir pax &&\n"> <"\t\tcd pax &&\n"> 
          <"\t\t\"$TAR\" xf \"$TEST_DIRECTORY\"/t5000/pax.tar &&\n"> <"\t\ttest -f PaxHeaders.1791/file\n"> <"\t)\n">
        )
      }
    )
    (C {(test_lazy_prereq)} {(GZIP)} {(SQ <"gzip --version">)})
    (FuncDef
      name: get_pax_header
      body: 
        (BraceGroup
          children: [
            (Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (LhsName name:file)
                  op: Equal
                  rhs: {($ VSub_Number "$1")}
                  spids: [80]
                )
              ]
              spids: [80]
            )
            (Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (LhsName name:header)
                  op: Equal
                  rhs: {($ VSub_Number "$2") (Lit_Other "=")}
                  spids: [84]
                )
              ]
              spids: [84]
            )
            (While
              cond: [(C {(read)} {(len)} {(rest)})]
              body: 
                (DoGroup
                  children: [
                    (If
                      arms: [
                        (if_arm
                          cond: [
                            (C {(test)} {(DQ ($ VSub_Name "$len"))} {(Lit_Other "=")} 
                              {
                                (CommandSubPart
                                  command_list: 
                                    (CommandList
                                      children: [
                                        (Pipeline
                                          children: [
                                            (C {(echo)} 
                                              {(DQ ($ VSub_Name "$len") (" ") ($ VSub_Name "$rest"))}
                                            )
                                            (C {(wc)} {(-c)})
                                          ]
                                          negated: False
                                        )
                                      ]
                                    )
                                  left_token: <Left_CommandSub "$(">
                                  spids: [112 126]
                                )
                              }
                            )
                          ]
                          action: [
                            (Case
                              to_match: {(DQ ($ VSub_Name "$rest"))}
                              arms: [
                                (case_arm
                                  pat_list: [{($ VSub_Name "$header") (Lit_Other "*")}]
                                  action: [
                                    (C {(echo)} 
                                      {
                                        (DQ 
                                          (BracedVarSub
                                            token: <VSub_Name rest>
                                            suffix_op: 
                                              (StringUnary
                                                op_id: VOp1_Pound
                                                arg_word: {($ VSub_Name "$header")}
                                              )
                                            spids: [149 153]
                                          )
                                        )
                                      }
                                    )
                                  ]
                                  spids: [141 143 157 -1]
                                )
                              ]
                              spids: [132 138 160]
                            )
                          ]
                          spids: [-1 129]
                        )
                      ]
                      spids: [-1 163]
                    )
                  ]
                  spids: [99 166]
                )
              redirects: [
                (Redir
                  op_id: Redir_Less
                  fd: -1
                  arg_word: {(DQ ($ VSub_Name "$file"))}
                  spids: [168]
                )
              ]
            )
          ]
          spids: [77]
        )
      spids: [73 76]
    )
    (FuncDef
      name: check_tar
      body: 
        (BraceGroup
          children: [
            (Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (LhsName name:tarfile)
                  op: Equal
                  rhs: {($ VSub_Number "$1") (.tar)}
                  spids: [183]
                )
              ]
              spids: [183]
            )
            (Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (LhsName name:listfile)
                  op: Equal
                  rhs: {($ VSub_Number "$1") (.lst)}
                  spids: [188]
                )
              ]
              spids: [188]
            )
            (Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (LhsName name:dir)
                  op: Equal
                  rhs: {($ VSub_Number "$1")}
                  spids: [193]
                )
              ]
              spids: [193]
            )
            (Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (LhsName name:dir_with_prefix)
                  op: Equal
                  rhs: {($ VSub_Name "$dir") (/) ($ VSub_Number "$2")}
                  spids: [197]
                )
              ]
              spids: [197]
            )
            (C {(test_expect_success)} {(SQ <" extract tar archive">)} 
              {(SQ <"\n"> <"\t\t(mkdir $dir && cd $dir && \"$TAR\" xf -) <$tarfile\n"> <"\t">)}
            )
            (C {(test_expect_success)} {(TAR_NEEDS_PAX_FALLBACK)} {(SQ <" interpret pax headers">)} 
              {
                (SQ <"\n"> <"\t\t(\n"> <"\t\t\tcd $dir &&\n"> <"\t\t\tfor header in *.paxheader\n"> 
                  <"\t\t\tdo\n"> <"\t\t\t\tdata=${header%.paxheader}.data &&\n"> <"\t\t\t\tif test -h $data || test -e $data\n"> 
                  <"\t\t\t\tthen\n"> <"\t\t\t\t\tpath=$(get_pax_header $header path) &&\n"> <"\t\t\t\t\tif test -n \"$path\"\n"> 
                  <"\t\t\t\t\tthen\n"> <"\t\t\t\t\t\tmv \"$data\" \"$path\"\n"> <"\t\t\t\t\tfi\n"> <"\t\t\t\tfi\n"> <"\t\t\tdone\n"> <"\t\t)\n"> 
                  <"\t">
                )
              }
            )
            (C {(test_expect_success)} {(SQ <" validate filenames">)} 
              {
                (SQ <"\n"> <"\t\t(cd ${dir_with_prefix}a && find .) | sort >$listfile &&\n"> 
                  <"\t\ttest_cmp a.lst $listfile\n"> <"\t">
                )
              }
            )
            (C {(test_expect_success)} {(SQ <" validate file contents">)} 
              {(SQ <"\n"> <"\t\tdiff -r a ${dir_with_prefix}a\n"> <"\t">)}
            )
          ]
          spids: [180]
        )
      spids: [176 179]
    )
    (C {(test_expect_success)} {(SQ <"populate workdir">)} 
      {
        (SQ <"mkdir a &&\n"> <"     echo simple textfile >a/a &&\n"> 
          <"     ten=0123456789 && hundred=$ten$ten$ten$ten$ten$ten$ten$ten$ten$ten &&\n"> <"     echo long filename >a/four$hundred &&\n"> <"     mkdir a/bin &&\n"> 
          <"     test-genrandom \"frotz\" 500000 >a/bin/sh &&\n"> <"     printf \"A\\$Format:%s\\$O\" \"$SUBSTFORMAT\" >a/substfile1 &&\n"> 
          <"     printf \"A not substituted O\" >a/substfile2 &&\n"> <"     if test_have_prereq SYMLINKS; then\n"> <"\tln -s a a/l1\n"> <"     else\n"> 
          <"\tprintf %s a > a/l1\n"> <"     fi &&\n"> <"     (p=long_path_to_a_file && cd a &&\n"> 
          <"      for depth in 1 2 3 4 5; do mkdir $p && cd $p; done &&\n"> <"      echo text >file_with_long_path) &&\n"> <"     (cd a && find .) | sort >a.lst">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"add ignored file">)} 
      {
        (SQ <"echo ignore me >a/ignored &&\n"> 
          <"     echo ignored export-ignore >.git/info/attributes">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"add files to repository">)} 
      {
        (SQ <"\n"> <"\tgit add a &&\n"> 
          <"\tGIT_COMMITTER_DATE=\"2005-05-27 22:00\" git commit -m initial\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"setup export-subst">)} 
      {
        (SQ <"\n"> <"\techo \"substfile?\" export-subst >>.git/info/attributes &&\n"> 
          <"\tgit log --max-count=1 \"--pretty=format:A${SUBSTFORMAT}O\" HEAD \\\n"> <"\t\t>a/substfile1\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"create bare clone">)} 
      {
        (SQ <"git clone --bare . bare.git &&\n"> 
          <"     cp .git/info/attributes bare.git/info/attributes">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"remove ignored file">)} {(SQ <"rm a/ignored">)})
    (C {(test_expect_success)} {(SQ <"git archive">)} {(SQ <"git archive HEAD >b.tar">)})
    (C {(check_tar)} {(b)})
    (C {(test_expect_success)} {(SQ <"git archive --prefix=prefix/">)} 
      {(SQ <"\n"> <"\tgit archive --prefix=prefix/ HEAD >with_prefix.tar\n">)}
    )
    (C {(check_tar)} {(with_prefix)} {(prefix/)})
    (C {(test_expect_success)} {(SQ <"git-archive --prefix=olde-">)} 
      {(SQ <"\n"> <"\tgit archive --prefix=olde- HEAD >with_olde-prefix.tar\n">)}
    )
    (C {(check_tar)} {(with_olde-prefix)} {(olde-)})
    (C {(test_expect_success)} {(SQ <"git archive on large files">)} 
      {
        (SQ <"\n"> <"    test_config core.bigfilethreshold 1 &&\n"> 
          <"    git archive HEAD >b3.tar &&\n"> <"    test_cmp_bin b.tar b3.tar\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"git archive in a bare repo">)} 
      {(SQ <"(cd bare.git && git archive HEAD) >b3.tar">)}
    )
    (C {(test_expect_success)} {(SQ <"git archive vs. the same in a bare repo">)} 
      {(SQ <"test_cmp_bin b.tar b3.tar">)}
    )
    (C {(test_expect_success)} {(SQ <"git archive with --output">)} 
      {(SQ <"git archive --output=b4.tar HEAD &&\n"> <"    test_cmp_bin b.tar b4.tar">)}
    )
    (C {(test_expect_success)} {(SQ <"git archive --remote">)} 
      {(SQ <"git archive --remote=. HEAD >b5.tar &&\n"> <"    test_cmp_bin b.tar b5.tar">)}
    )
    (C {(test_expect_success)} {(SQ <"validate file modification time">)} 
      {
        (SQ <"mkdir extract &&\n"> <"     \"$TAR\" xf b.tar -C extract a/a &&\n"> 
          <"     test-chmtime -v +0 extract/a/a |cut -f 1 >b.mtime &&\n"> <"     echo \"1117231200\" >expected.mtime &&\n"> <"     test_cmp expected.mtime b.mtime">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"git get-tar-commit-id">)} 
      {
        (SQ <"git get-tar-commit-id <b.tar >b.commitid &&\n"> 
          <"     test_cmp .git/$(git symbolic-ref HEAD) b.commitid">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"git archive with --output, override inferred format">)} 
      {
        (SQ <"\n"> <"\tgit archive --format=tar --output=d4.zip HEAD &&\n"> 
          <"\ttest_cmp_bin b.tar d4.zip\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"git archive --list outside of a git repo">)} 
      {(SQ <"GIT_DIR=some/non-existing/directory git archive --list">)}
    )
    (C {(test_expect_success)} {(SQ <"clients cannot access unreachable commits">)} 
      {
        (SQ <"\n"> <"\ttest_commit unreachable &&\n"> <"\tsha1=$(git rev-parse HEAD) &&\n"> 
          <"\tgit reset --hard HEAD^ &&\n"> <"\tgit archive $sha1 >remote.tar &&\n"> 
          <"\ttest_must_fail git archive --remote=. $sha1 >remote.tar\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"upload-archive can allow unreachable commits">)} 
      {
        (SQ <"\n"> <"\ttest_commit unreachable1 &&\n"> <"\tsha1=$(git rev-parse HEAD) &&\n"> 
          <"\tgit reset --hard HEAD^ &&\n"> <"\tgit archive $sha1 >remote.tar &&\n"> <"\ttest_config uploadarchive.allowUnreachable true &&\n"> 
          <"\tgit archive --remote=. $sha1 >remote.tar\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"setup tar filters">)} 
      {
        (SQ <"\n"> <"\tgit config tar.tar.foo.command \"tr ab ba\" &&\n"> 
          <"\tgit config tar.bar.command \"tr ab ba\" &&\n"> <"\tgit config tar.bar.remote true &&\n"> <"\tgit config tar.invalid baz\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"archive --list mentions user filter">)} 
      {
        (SQ <"\n"> <"\tgit archive --list >output &&\n"> <"\tgrep \"^tar\\.foo\\$\" output &&\n"> 
          <"\tgrep \"^bar\\$\" output\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"archive --list shows only enabled remote filters">)} 
      {
        (SQ <"\n"> <"\tgit archive --list --remote=. >output &&\n"> 
          <"\t! grep \"^tar\\.foo\\$\" output &&\n"> <"\tgrep \"^bar\\$\" output\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"invoke tar filter by format">)} 
      {
        (SQ <"\n"> <"\tgit archive --format=tar.foo HEAD >config.tar.foo &&\n"> 
          <"\ttr ab ba <config.tar.foo >config.tar &&\n"> <"\ttest_cmp_bin b.tar config.tar &&\n"> <"\tgit archive --format=bar HEAD >config.bar &&\n"> 
          <"\ttr ab ba <config.bar >config.tar &&\n"> <"\ttest_cmp_bin b.tar config.tar\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"invoke tar filter by extension">)} 
      {
        (SQ <"\n"> <"\tgit archive -o config-implicit.tar.foo HEAD &&\n"> 
          <"\ttest_cmp_bin config.tar.foo config-implicit.tar.foo &&\n"> <"\tgit archive -o config-implicit.bar HEAD &&\n"> 
          <"\ttest_cmp_bin config.tar.foo config-implicit.bar\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"default output format remains tar">)} 
      {
        (SQ <"\n"> <"\tgit archive -o config-implicit.baz HEAD &&\n"> 
          <"\ttest_cmp_bin b.tar config-implicit.baz\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"extension matching requires dot">)} 
      {
        (SQ <"\n"> <"\tgit archive -o config-implicittar.foo HEAD &&\n"> 
          <"\ttest_cmp_bin b.tar config-implicittar.foo\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"only enabled filters are available remotely">)} 
      {
        (SQ <"\n"> <"\ttest_must_fail git archive --remote=. --format=tar.foo HEAD \\\n"> 
          <"\t\t>remote.tar.foo &&\n"> <"\tgit archive --remote=. --format=bar >remote.bar HEAD &&\n"> 
          <"\ttest_cmp_bin remote.bar config.bar\n">
        )
      }
    )
    (C {(test_expect_success)} {(GZIP)} {(SQ <"git archive --format=tgz">)} 
      {(SQ <"\n"> <"\tgit archive --format=tgz HEAD >j.tgz\n">)}
    )
    (C {(test_expect_success)} {(GZIP)} {(SQ <"git archive --format=tar.gz">)} 
      {
        (SQ <"\n"> <"\tgit archive --format=tar.gz HEAD >j1.tar.gz &&\n"> 
          <"\ttest_cmp_bin j.tgz j1.tar.gz\n">
        )
      }
    )
    (C {(test_expect_success)} {(GZIP)} {(SQ <"infer tgz from .tgz filename">)} 
      {(SQ <"\n"> <"\tgit archive --output=j2.tgz HEAD &&\n"> <"\ttest_cmp_bin j.tgz j2.tgz\n">)}
    )
    (C {(test_expect_success)} {(GZIP)} {(SQ <"infer tgz from .tar.gz filename">)} 
      {
        (SQ <"\n"> <"\tgit archive --output=j3.tar.gz HEAD &&\n"> <"\ttest_cmp_bin j.tgz j3.tar.gz\n">)
      }
    )
    (C {(test_expect_success)} {(GZIP)} {(SQ <"extract tgz file">)} 
      {(SQ <"\n"> <"\tgzip -d -c <j.tgz >j.tar &&\n"> <"\ttest_cmp_bin b.tar j.tar\n">)}
    )
    (C {(test_expect_success)} {(GZIP)} {(SQ <"remote tar.gz is allowed by default">)} 
      {
        (SQ <"\n"> <"\tgit archive --remote=. --format=tar.gz HEAD >remote.tar.gz &&\n"> 
          <"\ttest_cmp_bin j.tgz remote.tar.gz\n">
        )
      }
    )
    (C {(test_expect_success)} {(GZIP)} {(SQ <"remote tar.gz can be disabled">)} 
      {
        (SQ <"\n"> <"\tgit config tar.tar.gz.remote false &&\n"> 
          <"\ttest_must_fail git archive --remote=. --format=tar.gz HEAD \\\n"> <"\t\t>remote.tar.gz\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"archive and :(glob)">)} 
      {
        (SQ <"\n"> <"\tgit archive -v HEAD -- \":(glob)**/sh\" >/dev/null 2>actual &&\n"> 
          <"\tcat >expect <<EOF &&\n"> <"a/\n"> <"a/bin/\n"> <"a/bin/sh\n"> <"EOF\n"> <"\ttest_cmp expect actual\n">
        )
      }
    )
    (C {(test_expect_success)} {(SQ <"catch non-matching pathspec">)} 
      {(SQ <"\n"> <"\ttest_must_fail git archive -v HEAD -- \"*.abc\" >/dev/null\n">)}
    )
    (FuncDef
      name: tar_info
      body: 
        (BraceGroup
          children: [
            (Pipeline
              children: [
                (C {(DQ ($ VSub_Name "$TAR"))} {(tvf)} {(DQ ($ VSub_Number "$1"))})
                (C {(awk)} 
                  {
                    (SQ <"{\n"> <"\t\tsplit($4, date, \"-\")\n"> <"\t\tprint $3 \" \" date[1]\n"> 
                      <"\t}">
                    )
                  }
                )
              ]
              negated: False
            )
          ]
          spids: [892]
        )
      spids: [887 891]
    )
    (C {(test_lazy_prereq)} {(TAR_HUGE)} 
      {
        (SQ <"\n"> <"\techo \"68719476737 4147\" >expect &&\n"> 
          <"\ttar_info \"$TEST_DIRECTORY\"/t5000/huge-and-future.tar >actual &&\n"> <"\ttest_cmp expect actual\n">
        )
      }
    )
    (C {(test_expect_success)} {(LONG_IS_64BIT)} {(SQ <"set up repository with huge blob">)} 
      {
        (SQ <"\n"> <"\tobj_d=19 &&\n"> <"\tobj_f=f9c8273ec45a8938e6999cb59b3ff66739902a &&\n"> 
          <"\tobj=${obj_d}${obj_f} &&\n"> <"\tmkdir -p .git/objects/$obj_d &&\n"> 
          <"\tcp \"$TEST_DIRECTORY\"/t5000/$obj .git/objects/$obj_d/$obj_f &&\n"> <"\trm -f .git/index &&\n"> <"\tgit update-index --add --cacheinfo 100644,$obj,huge &&\n"> 
          <"\tgit commit -m huge\n">
        )
      }
    )
    (C {(test_expect_success)} {(LONG_IS_64BIT)} {(SQ <"generate tar with huge size">)} 
      {
        (SQ <"\n"> <"\t{\n"> <"\t\tgit archive HEAD\n"> <"\t\techo $? >exit-code\n"> 
          <"\t} | test_copy_bytes 4096 >huge.tar &&\n"> <"\techo 141 >expect &&\n"> <"\ttest_cmp expect exit-code\n">
        )
      }
    )
    (C {(test_expect_success)} {(TAR_HUGE) (Lit_Comma ",") (LONG_IS_64BIT)} 
      {(SQ <"system tar can read our huge size">)} 
      {
        (SQ <"\n"> <"\techo 68719476737 >expect &&\n"> 
          <"\ttar_info huge.tar | cut -d\" \" -f1 >actual &&\n"> <"\ttest_cmp expect actual\n">
        )
      }
    )
    (C {(test_expect_success)} {(LONG_IS_64BIT)} {(SQ <"set up repository with far-future commit">)} 
      {
        (SQ <"\n"> <"\trm -f .git/index &&\n"> <"\techo content >file &&\n"> <"\tgit add file &&\n"> 
          <"\tGIT_COMMITTER_DATE=\"@68719476737 +0000\" \\\n"> <"\t\tgit commit -m \"tempori parendum\"\n">
        )
      }
    )
    (C {(test_expect_success)} {(LONG_IS_64BIT)} {(SQ <"generate tar with future mtime">)} 
      {(SQ <"\n"> <"\tgit archive HEAD >future.tar\n">)}
    )
    (C {(test_expect_success)} {(TAR_HUGE) (Lit_Comma ",") (LONG_IS_64BIT)} 
      {(SQ <"system tar can read our future mtime">)} 
      {
        (SQ <"\n"> <"\techo 4147 >expect &&\n"> 
          <"\ttar_info future.tar | cut -d\" \" -f2 >actual &&\n"> <"\ttest_cmp expect actual\n">
        )
      }
    )
    (C {(test_done)})
  ]
)