(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: 'gitweb as standalone script (parsing script output).\n'
                  span_id: 15
                ) (Token id:Id.Lit_Chars val:'\n' span_id:16) 
                (Token
                  id: Id.Lit_Chars
                  val: 'This test runs gitweb (git web interface) as a CGI script from the\n'
                  span_id: 17
                ) 
                (Token
                  id: Id.Lit_Chars
                  val: 'commandline, and checks that it produces the correct output, either\n'
                  span_id: 18
                ) (Token id:Id.Lit_Chars val:'in the HTTP header or the actual script output.' span_id:19)
              )
            }
          spids: [13]
        )
      ]
    )
    (C {(.)} {(./gitweb-lib.sh)})
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_DGreat val:'>>' span_id:38)
          fd: -1
          arg_word: {(gitweb_config.perl)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:41)
          fd: -1
          here_begin: 
            {(word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\E' span_id:42)) (OF)}
          here_end_span_id: 54
          stdin_parts: [
            ('\n')
            ("$known_snapshot_formats{'tar'} = {\n")
            ("\t'display' => 'tar',\n")
            ("\t'type' => 'application/x-tar',\n")
            ("\t'suffix' => '.tar',\n")
            ("\t'format' => 'tar',\n")
            ('};\n')
            ('\n')
            ("$feature{'snapshot'}{'default'} = ['tar'];\n")
          ]
        )
      ]
    )
    (command.ShFunction
      name: check_snapshot
      body: 
        (command.BraceGroup
          children: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:basename)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number '$1')}
                  spids: [85]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:prefix)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (braced_var_sub
                        token: (Token id:Id.VSub_Number val:2 span_id:91)
                        suffix_op: 
                          (suffix_op.Unary
                            op_id: Id.VTest_ColonHyphen
                            arg_word: {(DQ ($ Id.VSub_Number '$1'))}
                          )
                      )
                    }
                  spids: [89]
                )
              ]
            )
            (C {(echo)} {(DQ ('basename=') ($ Id.VSub_DollarName '$basename'))})
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp]
              children: [
                (command.Simple
                  words: [
                    {(grep)}
                    {(DQ ('filename=.*') ($ Id.VSub_DollarName '$basename') (.tar))}
                    {(gitweb.headers)}
                  ]
                  redirects: [
                    (redir.Redir
                      op: (Token id:Id.Redir_Great val:'>' span_id:117)
                      fd: -1
                      arg_word: {(/dev/null)}
                    )
                    (redir.Redir
                      op: (Token id:Id.Redir_GreatAnd val:'2>&' span_id:120)
                      fd: 2
                      arg_word: {(1)}
                    )
                  ]
                )
                (command.Simple
                  words: [{(DQ ($ Id.VSub_DollarName '$TAR'))} {(tf)} {(gitweb.body)}]
                  redirects: [
                    (redir.Redir
                      op: (Token id:Id.Redir_Great val:'>' span_id:134)
                      fd: -1
                      arg_word: {(file_list)}
                    )
                  ]
                )
                (command.Pipeline
                  children: [
                    (C {(grep)} {(-v)} {(-e)} 
                      {(DQ ('^') ($ Id.VSub_DollarName '$prefix') (Id.Lit_Other '$'))} {(-e)} {(DQ ('^') ($ Id.VSub_DollarName '$prefix') (/))} {(-e)} 
                      {(DQ ('^pax_global_header') (Id.Lit_Other '$'))} {(file_list)}
                    )
                  ]
                  negated: T
                )
              ]
            )
          ]
        )
    )
    (C {(test_expect_success)} {(setup)} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:179) 
          (Token id:Id.Lit_Chars val:'\ttest_commit first foo &&\n' span_id:180) (Token id:Id.Lit_Chars val:'\tgit branch xx/test &&\n' span_id:181) 
          (Token
            id: Id.Lit_Chars
            val: '\tFULL_ID=$(git rev-parse --verify HEAD) &&\n'
            span_id: 182
          ) (Token id:Id.Lit_Chars val:'\tSHORT_ID=$(git rev-parse --verify --short=7 HEAD)\n' span_id:183)
        )
      }
    )
    (C {(test_debug)} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:189) 
          (Token id:Id.Lit_Chars val:'\techo "FULL_ID  = $FULL_ID"\n' span_id:190) (Token id:Id.Lit_Chars val:'\techo "SHORT_ID = $SHORT_ID"\n' span_id:191)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'snapshot: full sha1' span_id:198))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:202) 
          (Token
            id: Id.Lit_Chars
            val: '\tgitweb_run "p=.git;a=snapshot;h=$FULL_ID;sf=tar" &&\n'
            span_id: 203
          ) (Token id:Id.Lit_Chars val:'\tcheck_snapshot ".git-$SHORT_ID"\n' span_id:204)
        )
      }
    )
    (C {(test_debug)} 
      {(SQ (Token id:Id.Lit_Chars val:'cat gitweb.headers && cat file_list' span_id:210))}
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'snapshot: shortened sha1' span_id:217))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:221) 
          (Token
            id: Id.Lit_Chars
            val: '\tgitweb_run "p=.git;a=snapshot;h=$SHORT_ID;sf=tar" &&\n'
            span_id: 222
          ) (Token id:Id.Lit_Chars val:'\tcheck_snapshot ".git-$SHORT_ID"\n' span_id:223)
        )
      }
    )
    (C {(test_debug)} 
      {(SQ (Token id:Id.Lit_Chars val:'cat gitweb.headers && cat file_list' span_id:229))}
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'snapshot: almost full sha1' span_id:236))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:240) 
          (Token
            id: Id.Lit_Chars
            val: '\tID=$(git rev-parse --short=30 HEAD) &&\n'
            span_id: 241
          ) (Token id:Id.Lit_Chars val:'\tgitweb_run "p=.git;a=snapshot;h=$ID;sf=tar" &&\n' span_id:242) 
          (Token id:Id.Lit_Chars val:'\tcheck_snapshot ".git-$SHORT_ID"\n' span_id:243)
        )
      }
    )
    (C {(test_debug)} 
      {(SQ (Token id:Id.Lit_Chars val:'cat gitweb.headers && cat file_list' span_id:249))}
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'snapshot: HEAD' span_id:256))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:260) 
          (Token
            id: Id.Lit_Chars
            val: '\tgitweb_run "p=.git;a=snapshot;h=HEAD;sf=tar" &&\n'
            span_id: 261
          ) (Token id:Id.Lit_Chars val:'\tcheck_snapshot ".git-HEAD-$SHORT_ID"\n' span_id:262)
        )
      }
    )
    (C {(test_debug)} 
      {(SQ (Token id:Id.Lit_Chars val:'cat gitweb.headers && cat file_list' span_id:268))}
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'snapshot: short branch name (master)' span_id:275))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:279) 
          (Token
            id: Id.Lit_Chars
            val: '\tgitweb_run "p=.git;a=snapshot;h=master;sf=tar" &&\n'
            span_id: 280
          ) (Token id:Id.Lit_Chars val:'\tID=$(git rev-parse --verify --short=7 master) &&\n' span_id:281) 
          (Token id:Id.Lit_Chars val:'\tcheck_snapshot ".git-master-$ID"\n' span_id:282)
        )
      }
    )
    (C {(test_debug)} 
      {(SQ (Token id:Id.Lit_Chars val:'cat gitweb.headers && cat file_list' span_id:288))}
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'snapshot: short tag name (first)' span_id:295))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:299) 
          (Token
            id: Id.Lit_Chars
            val: '\tgitweb_run "p=.git;a=snapshot;h=first;sf=tar" &&\n'
            span_id: 300
          ) (Token id:Id.Lit_Chars val:'\tID=$(git rev-parse --verify --short=7 first) &&\n' span_id:301) 
          (Token id:Id.Lit_Chars val:'\tcheck_snapshot ".git-first-$ID"\n' span_id:302)
        )
      }
    )
    (C {(test_debug)} 
      {(SQ (Token id:Id.Lit_Chars val:'cat gitweb.headers && cat file_list' span_id:308))}
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'snapshot: full branch name (refs/heads/master)' span_id:315))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:319) 
          (Token
            id: Id.Lit_Chars
            val: '\tgitweb_run "p=.git;a=snapshot;h=refs/heads/master;sf=tar" &&\n'
            span_id: 320
          ) (Token id:Id.Lit_Chars val:'\tID=$(git rev-parse --verify --short=7 master) &&\n' span_id:321) 
          (Token id:Id.Lit_Chars val:'\tcheck_snapshot ".git-master-$ID"\n' span_id:322)
        )
      }
    )
    (C {(test_debug)} 
      {(SQ (Token id:Id.Lit_Chars val:'cat gitweb.headers && cat file_list' span_id:328))}
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'snapshot: full tag name (refs/tags/first)' span_id:335))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:339) 
          (Token
            id: Id.Lit_Chars
            val: '\tgitweb_run "p=.git;a=snapshot;h=refs/tags/first;sf=tar" &&\n'
            span_id: 340
          ) (Token id:Id.Lit_Chars val:'\tcheck_snapshot ".git-first"\n' span_id:341)
        )
      }
    )
    (C {(test_debug)} 
      {(SQ (Token id:Id.Lit_Chars val:'cat gitweb.headers && cat file_list' span_id:347))}
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'snapshot: hierarchical branch name (xx/test)' span_id:354))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:358) 
          (Token
            id: Id.Lit_Chars
            val: '\tgitweb_run "p=.git;a=snapshot;h=xx/test;sf=tar" &&\n'
            span_id: 359
          ) (Token id:Id.Lit_Chars val:'\t! grep "filename=.*/" gitweb.headers\n' span_id:360)
        )
      }
    )
    (C {(test_debug)} {(SQ (Token id:Id.Lit_Chars val:'cat gitweb.headers' span_id:366))})
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'forks: setup' span_id:380))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:384) 
          (Token id:Id.Lit_Chars val:'\tgit init --bare foo.git &&\n' span_id:385) (Token id:Id.Lit_Chars val:'\techo file > file &&\n' span_id:386) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit --git-dir=foo.git --work-tree=. add file &&\n'
            span_id: 387
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit --git-dir=foo.git --work-tree=. commit -m "Initial commit" &&\n'
            span_id: 388
          ) (Token id:Id.Lit_Chars val:'\techo "foo" > foo.git/description &&\n' span_id:389) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit clone --bare foo.git foo.bar.git &&\n'
            span_id: 390
          ) (Token id:Id.Lit_Chars val:'\techo "foo.bar" > foo.bar.git/description &&\n' span_id:391) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit clone --bare foo.git foo_baz.git &&\n'
            span_id: 392
          ) (Token id:Id.Lit_Chars val:'\techo "foo_baz" > foo_baz.git/description &&\n' span_id:393) 
          (Token id:Id.Lit_Chars val:'\trm -fr   foo &&\n' span_id:394) (Token id:Id.Lit_Chars val:'\tmkdir -p foo &&\n' span_id:395) 
          (Token id:Id.Lit_Chars val:'\t(\n' span_id:396) (Token id:Id.Lit_Chars val:'\t\tcd foo &&\n' span_id:397) 
          (Token
            id: Id.Lit_Chars
            val: '\t\tgit clone --shared --bare ../foo.git foo-forked.git &&\n'
            span_id: 398
          ) (Token id:Id.Lit_Chars val:'\t\techo "fork of foo" > foo-forked.git/description\n' span_id:399) 
          (Token id:Id.Lit_Chars val:'\t)\n' span_id:400)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'forks: not skipped unless "forks" feature enabled'
            span_id: 407
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:411) 
          (Token id:Id.Lit_Chars val:'\tgitweb_run "a=project_list" &&\n' span_id:412) (Token id:Id.Lit_Chars val:'\tgrep -q ">\\\\.git<"               gitweb.body &&\n' span_id:413) 
          (Token
            id: Id.Lit_Chars
            val: '\tgrep -q ">foo\\\\.git<"            gitweb.body &&\n'
            span_id: 414
          ) (Token id:Id.Lit_Chars val:'\tgrep -q ">foo_baz\\\\.git<"        gitweb.body &&\n' span_id:415) 
          (Token
            id: Id.Lit_Chars
            val: '\tgrep -q ">foo\\\\.bar\\\\.git<"      gitweb.body &&\n'
            span_id: 416
          ) (Token id:Id.Lit_Chars val:'\tgrep -q ">foo_baz\\\\.git<"        gitweb.body &&\n' span_id:417) 
          (Token
            id: Id.Lit_Chars
            val: '\tgrep -q ">foo/foo-forked\\\\.git<" gitweb.body &&\n'
            span_id: 418
          ) (Token id:Id.Lit_Chars val:'\tgrep -q ">fork of .*<"           gitweb.body\n' span_id:419)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'enable forks feature' span_id:426))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:430) 
          (Token id:Id.Lit_Chars val:'\tcat >>gitweb_config.perl <<-\\EOF\n' span_id:431) (Token id:Id.Lit_Chars val:'\t$feature{"forks"}{"default"} = [1];\n' span_id:432) 
          (Token id:Id.Lit_Chars val:'\tEOF\n' span_id:433)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'forks: forks skipped if "forks" feature enabled' span_id:440))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:444) 
          (Token id:Id.Lit_Chars val:'\tgitweb_run "a=project_list" &&\n' span_id:445) (Token id:Id.Lit_Chars val:'\tgrep -q ">\\\\.git<"               gitweb.body &&\n' span_id:446) 
          (Token
            id: Id.Lit_Chars
            val: '\tgrep -q ">foo\\\\.git<"            gitweb.body &&\n'
            span_id: 447
          ) (Token id:Id.Lit_Chars val:'\tgrep -q ">foo_baz\\\\.git<"        gitweb.body &&\n' span_id:448) 
          (Token
            id: Id.Lit_Chars
            val: '\tgrep -q ">foo\\\\.bar\\\\.git<"      gitweb.body &&\n'
            span_id: 449
          ) (Token id:Id.Lit_Chars val:'\tgrep -q ">foo_baz\\\\.git<"        gitweb.body &&\n' span_id:450) 
          (Token
            id: Id.Lit_Chars
            val: '\tgrep -v ">foo/foo-forked\\\\.git<" gitweb.body &&\n'
            span_id: 451
          ) (Token id:Id.Lit_Chars val:'\tgrep -v ">fork of .*<"           gitweb.body\n' span_id:452)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'forks: "forks" action for forked repository' span_id:459))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:463) 
          (Token id:Id.Lit_Chars val:'\tgitweb_run "p=foo.git;a=forks" &&\n' span_id:464) (Token id:Id.Lit_Chars val:'\tgrep -q ">foo/foo-forked\\\\.git<" gitweb.body &&\n' span_id:465) 
          (Token
            id: Id.Lit_Chars
            val: '\tgrep -q ">fork of foo<"          gitweb.body\n'
            span_id: 466
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'forks: can access forked repository' span_id:473))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:477) 
          (Token
            id: Id.Lit_Chars
            val: '\tgitweb_run "p=foo/foo-forked.git;a=summary" &&\n'
            span_id: 478
          ) (Token id:Id.Lit_Chars val:'\tgrep -q "200 OK"        gitweb.headers &&\n' span_id:479) 
          (Token id:Id.Lit_Chars val:'\tgrep -q ">fork of foo<" gitweb.body\n' span_id:480)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'forks: project_index lists all projects (incl. forks)'
            span_id: 487
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:491) 
          (Token id:Id.Lit_Chars val:'\tcat >expected <<-\\EOF &&\n' span_id:492) (Token id:Id.Lit_Chars val:'\t.git\n' span_id:493) 
          (Token id:Id.Lit_Chars val:'\tfoo.bar.git\n' span_id:494) (Token id:Id.Lit_Chars val:'\tfoo.git\n' span_id:495) 
          (Token id:Id.Lit_Chars val:'\tfoo/foo-forked.git\n' span_id:496) (Token id:Id.Lit_Chars val:'\tfoo_baz.git\n' span_id:497) 
          (Token id:Id.Lit_Chars val:'\tEOF\n' span_id:498) (Token id:Id.Lit_Chars val:'\tgitweb_run "a=project_index" &&\n' span_id:499) 
          (Token
            id: Id.Lit_Chars
            val: '\tsed -e "s/ .*//" <gitweb.body | sort >actual &&\n'
            span_id: 500
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp expected actual\n' span_id:501)
        )
      }
    )
    (command.ShFunction
      name: xss
      body: 
        (command.BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp]
              children: [
                (command.Simple
                  words: [{(echo)} {(DQ ('Checking ') ($ Id.VSub_Number '$1') (...))}]
                  redirects: [
                    (redir.Redir
                      op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:514)
                      fd: -1
                      arg_word: {(2)}
                    )
                  ]
                )
                (C {(gitweb_run)} {(DQ ($ Id.VSub_Number '$1'))})
                (command.If
                  arms: [
                    (if_arm
                      cond: [
                        (command.Sentence
                          child: (C {(grep)} {(DQ ($ Id.VSub_DollarName '$TAG'))} {(gitweb.body)})
                          terminator: (Token id:Id.Op_Semi val:';' span_id:544)
                        )
                      ]
                      action: [
                        (command.Simple
                          words: [
                            {(echo)}
                            {
                              (DQ ('xss: ') ($ Id.VSub_DollarName '$TAG') 
                                (' should have been quoted in output')
                              )
                            }
                          ]
                          redirects: [
                            (redir.Redir
                              op: (Token id:Id.Redir_GreatAnd val:'>&' span_id:551)
                              fd: -1
                              arg_word: {(2)}
                            )
                          ]
                        )
                        (command.ControlFlow
                          token: (Token id:Id.ControlFlow_Return val:return span_id:561)
                          arg_word: {(1)}
                        )
                      ]
                      spids: [535 546]
                    )
                  ]
                )
              ]
            )
            (command.ControlFlow
              token: (Token id:Id.ControlFlow_Return val:return span_id:569)
              arg_word: {(0)}
            )
          ]
        )
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'xss checks' span_id:579))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:583) 
          (Token id:Id.Lit_Chars val:'\tTAG="<magic-xss-tag>" &&\n' span_id:584) (Token id:Id.Lit_Chars val:'\txss "a=rss&p=$TAG" &&\n' span_id:585) 
          (Token id:Id.Lit_Chars val:'\txss "a=rss&p=foo.git&f=$TAG"\n' span_id:586)
        )
      }
    )
    (C {(test_done)})
  ]
)