(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 ls-tree directory and filenames handling.\n'
                  span_id: 18
                ) (Token id:Id.Lit_Chars val:'\n' span_id:19) 
                (Token
                  id: Id.Lit_Chars
                  val: 'This test runs git ls-tree with the following in a tree.\n'
                  span_id: 20
                ) (Token id:Id.Lit_Chars val:'\n' span_id:21) 
                (Token
                  id: Id.Lit_Chars
                  val: '    1.txt              - a file\n'
                  span_id: 22
                ) (Token id:Id.Lit_Chars val:'    2.txt              - a file\n' span_id:23) 
                (Token
                  id: Id.Lit_Chars
                  val: '    path0/a/b/c/1.txt  - a file in a directory\n'
                  span_id: 24
                ) (Token id:Id.Lit_Chars val:'    path1/b/c/1.txt    - a file in a directory\n' span_id:25) 
                (Token
                  id: Id.Lit_Chars
                  val: '    path2/1.txt        - a file in a directory\n'
                  span_id: 26
                ) (Token id:Id.Lit_Chars val:'    path3/1.txt        - a file in a directory\n' span_id:27) 
                (Token
                  id: Id.Lit_Chars
                  val: '    path3/2.txt        - a file in a directory\n'
                  span_id: 28
                ) (Token id:Id.Lit_Chars val:'\n' span_id:29) 
                (Token
                  id: Id.Lit_Chars
                  val: 'Test the handling of multiple directories which have matching file\n'
                  span_id: 30
                ) 
                (Token
                  id: Id.Lit_Chars
                  val: 'entries.  Also test odd filename and missing entries handling.\n'
                  span_id: 31
                )
              )
            }
          spids: [16]
        )
      ]
    )
    (C {(.)} {(./test-lib.sh)})
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:setup span_id:42))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:46) 
          (Token id:Id.Lit_Chars val:'\techo 111 >1.txt &&\n' span_id:47) (Token id:Id.Lit_Chars val:'\techo 222 >2.txt &&\n' span_id:48) 
          (Token
            id: Id.Lit_Chars
            val: '\tmkdir path0 path0/a path0/a/b path0/a/b/c &&\n'
            span_id: 49
          ) (Token id:Id.Lit_Chars val:'\techo 111 >path0/a/b/c/1.txt &&\n' span_id:50) 
          (Token id:Id.Lit_Chars val:'\tmkdir path1 path1/b path1/b/c &&\n' span_id:51) (Token id:Id.Lit_Chars val:'\techo 111 >path1/b/c/1.txt &&\n' span_id:52) 
          (Token id:Id.Lit_Chars val:'\tmkdir path2 &&\n' span_id:53) (Token id:Id.Lit_Chars val:'\techo 111 >path2/1.txt &&\n' span_id:54) 
          (Token id:Id.Lit_Chars val:'\tmkdir path3 &&\n' span_id:55) (Token id:Id.Lit_Chars val:'\techo 111 >path3/1.txt &&\n' span_id:56) 
          (Token id:Id.Lit_Chars val:'\techo 222 >path3/2.txt &&\n' span_id:57) (Token id:Id.Lit_Chars val:'\tfind *.txt path* \\( -type f -o -type l \\) -print |\n' span_id:58) 
          (Token id:Id.Lit_Chars val:'\txargs git update-index --add &&\n' span_id:59) (Token id:Id.Lit_Chars val:'\ttree=$(git write-tree) &&\n' span_id:60) 
          (Token id:Id.Lit_Chars val:'\techo $tree\n' span_id:61)
        )
      }
    )
    (command.ShFunction
      name: test_output
      body: 
        (command.BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp]
              children: [
                (command.Simple
                  words: [{(sed)} {(-e)} {(DQ ('s/ ') ($ Id.VSub_DollarName '$_x40') ('\t/ X\t/'))}]
                  redirects: [
                    (redir.Redir
                      op: (Token id:Id.Redir_Less val:'<' span_id:83)
                      fd: -1
                      arg_word: {(current)}
                    )
                    (redir.Redir
                      op: (Token id:Id.Redir_Great val:'>' span_id:86)
                      fd: -1
                      arg_word: {(check)}
                    )
                  ]
                )
                (C {(test_cmp)} {(expected)} {(check)})
              ]
            )
          ]
        )
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'ls-tree plain' span_id:104))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:108) 
          (Token id:Id.Lit_Chars val:'\tgit ls-tree $tree >current &&\n' span_id:109) (Token id:Id.Lit_Chars val:'\tcat >expected <<\\EOF &&\n' span_id:110) 
          (Token id:Id.Lit_Chars val:'100644 blob X\t1.txt\n' span_id:111) (Token id:Id.Lit_Chars val:'100644 blob X\t2.txt\n' span_id:112) 
          (Token id:Id.Lit_Chars val:'040000 tree X\tpath0\n' span_id:113) (Token id:Id.Lit_Chars val:'040000 tree X\tpath1\n' span_id:114) 
          (Token id:Id.Lit_Chars val:'040000 tree X\tpath2\n' span_id:115) (Token id:Id.Lit_Chars val:'040000 tree X\tpath3\n' span_id:116) 
          (Token id:Id.Lit_Chars val:'EOF\n' span_id:117) (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:118)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'ls-tree recursive' span_id:128))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:132) 
          (Token id:Id.Lit_Chars val:'\tgit ls-tree -r $tree >current &&\n' span_id:133) (Token id:Id.Lit_Chars val:'\tcat >expected <<\\EOF &&\n' span_id:134) 
          (Token id:Id.Lit_Chars val:'100644 blob X\t1.txt\n' span_id:135) (Token id:Id.Lit_Chars val:'100644 blob X\t2.txt\n' span_id:136) 
          (Token id:Id.Lit_Chars val:'100644 blob X\tpath0/a/b/c/1.txt\n' span_id:137) (Token id:Id.Lit_Chars val:'100644 blob X\tpath1/b/c/1.txt\n' span_id:138) 
          (Token id:Id.Lit_Chars val:'100644 blob X\tpath2/1.txt\n' span_id:139) (Token id:Id.Lit_Chars val:'100644 blob X\tpath3/1.txt\n' span_id:140) 
          (Token id:Id.Lit_Chars val:'100644 blob X\tpath3/2.txt\n' span_id:141) (Token id:Id.Lit_Chars val:'EOF\n' span_id:142) 
          (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:143)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'ls-tree filter 1.txt' span_id:150))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:154) 
          (Token id:Id.Lit_Chars val:'\tgit ls-tree $tree 1.txt >current &&\n' span_id:155) (Token id:Id.Lit_Chars val:'\tcat >expected <<\\EOF &&\n' span_id:156) 
          (Token id:Id.Lit_Chars val:'100644 blob X\t1.txt\n' span_id:157) (Token id:Id.Lit_Chars val:'EOF\n' span_id:158) 
          (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:159)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'ls-tree filter path1/b/c/1.txt' span_id:166))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:170) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit ls-tree $tree path1/b/c/1.txt >current &&\n'
            span_id: 171
          ) (Token id:Id.Lit_Chars val:'\tcat >expected <<\\EOF &&\n' span_id:172) 
          (Token id:Id.Lit_Chars val:'100644 blob X\tpath1/b/c/1.txt\n' span_id:173) (Token id:Id.Lit_Chars val:'EOF\n' span_id:174) 
          (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:175)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'ls-tree filter all 1.txt files' span_id:182))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:186) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit ls-tree $tree 1.txt path0/a/b/c/1.txt \\\n'
            span_id: 187
          ) (Token id:Id.Lit_Chars val:'\t\tpath1/b/c/1.txt path2/1.txt path3/1.txt >current &&\n' span_id:188) 
          (Token id:Id.Lit_Chars val:'\tcat >expected <<\\EOF &&\n' span_id:189) (Token id:Id.Lit_Chars val:'100644 blob X\t1.txt\n' span_id:190) 
          (Token id:Id.Lit_Chars val:'100644 blob X\tpath0/a/b/c/1.txt\n' span_id:191) (Token id:Id.Lit_Chars val:'100644 blob X\tpath1/b/c/1.txt\n' span_id:192) 
          (Token id:Id.Lit_Chars val:'100644 blob X\tpath2/1.txt\n' span_id:193) (Token id:Id.Lit_Chars val:'100644 blob X\tpath3/1.txt\n' span_id:194) 
          (Token id:Id.Lit_Chars val:'EOF\n' span_id:195) (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:196)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'ls-tree filter directories' span_id:212))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:216) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit ls-tree $tree path3 path2 path0/a/b/c path1/b/c path0/a >current &&\n'
            span_id: 217
          ) (Token id:Id.Lit_Chars val:'\tcat >expected <<\\EOF &&\n' span_id:218) 
          (Token id:Id.Lit_Chars val:'040000 tree X\tpath0/a/b/c\n' span_id:219) (Token id:Id.Lit_Chars val:'040000 tree X\tpath1/b/c\n' span_id:220) 
          (Token id:Id.Lit_Chars val:'040000 tree X\tpath2\n' span_id:221) (Token id:Id.Lit_Chars val:'040000 tree X\tpath3\n' span_id:222) 
          (Token id:Id.Lit_Chars val:'EOF\n' span_id:223) (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:224)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'ls-tree filter odd names' span_id:237))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:241) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit ls-tree $tree 1.txt ./1.txt .//1.txt \\\n'
            span_id: 242
          ) (Token id:Id.Lit_Chars val:'\t\tpath3/1.txt path3/./1.txt path3 path3// >current &&\n' span_id:243) 
          (Token id:Id.Lit_Chars val:'\tcat >expected <<\\EOF &&\n' span_id:244) (Token id:Id.Lit_Chars val:'100644 blob X\t1.txt\n' span_id:245) 
          (Token id:Id.Lit_Chars val:'100644 blob X\tpath3/1.txt\n' span_id:246) (Token id:Id.Lit_Chars val:'100644 blob X\tpath3/2.txt\n' span_id:247) 
          (Token id:Id.Lit_Chars val:'EOF\n' span_id:248) (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:249)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'ls-tree filter missing files and extra slashes' span_id:256))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:260) 
          (Token id:Id.Lit_Chars val:'\tgit ls-tree $tree 1.txt/ abc.txt \\\n' span_id:261) (Token id:Id.Lit_Chars val:'\t\tpath3//23.txt path3/2.txt/// >current &&\n' span_id:262) 
          (Token id:Id.Lit_Chars val:'\t>expected &&\n' span_id:263) (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:264)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'ls-tree filter is leading path match' span_id:271))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:275) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit ls-tree $tree pa path3/a >current &&\n'
            span_id: 276
          ) (Token id:Id.Lit_Chars val:'\t>expected &&\n' span_id:277) 
          (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:278)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'ls-tree --full-name' span_id:285))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:289) 
          (Token id:Id.Lit_Chars val:'\t(\n' span_id:290) (Token id:Id.Lit_Chars val:'\t\tcd path0 &&\n' span_id:291) 
          (Token id:Id.Lit_Chars val:'\t\tgit ls-tree --full-name $tree a\n' span_id:292) (Token id:Id.Lit_Chars val:'\t) >current &&\n' span_id:293) 
          (Token id:Id.Lit_Chars val:'\tcat >expected <<\\EOF &&\n' span_id:294) (Token id:Id.Lit_Chars val:'040000 tree X\tpath0/a\n' span_id:295) 
          (Token id:Id.Lit_Chars val:'EOF\n' span_id:296) (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:297)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'ls-tree --full-tree' span_id:304))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:308) 
          (Token id:Id.Lit_Chars val:'\t(\n' span_id:309) (Token id:Id.Lit_Chars val:'\t\tcd path1/b/c &&\n' span_id:310) 
          (Token id:Id.Lit_Chars val:'\t\tgit ls-tree --full-tree $tree\n' span_id:311) (Token id:Id.Lit_Chars val:'\t) >current &&\n' span_id:312) 
          (Token id:Id.Lit_Chars val:'\tcat >expected <<\\EOF &&\n' span_id:313) (Token id:Id.Lit_Chars val:'100644 blob X\t1.txt\n' span_id:314) 
          (Token id:Id.Lit_Chars val:'100644 blob X\t2.txt\n' span_id:315) (Token id:Id.Lit_Chars val:'040000 tree X\tpath0\n' span_id:316) 
          (Token id:Id.Lit_Chars val:'040000 tree X\tpath1\n' span_id:317) (Token id:Id.Lit_Chars val:'040000 tree X\tpath2\n' span_id:318) 
          (Token id:Id.Lit_Chars val:'040000 tree X\tpath3\n' span_id:319) (Token id:Id.Lit_Chars val:'EOF\n' span_id:320) 
          (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:321)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'ls-tree --full-tree -r' span_id:328))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:332) 
          (Token id:Id.Lit_Chars val:'\t(\n' span_id:333) (Token id:Id.Lit_Chars val:'\t\tcd path3/ &&\n' span_id:334) 
          (Token id:Id.Lit_Chars val:'\t\tgit ls-tree --full-tree -r $tree\n' span_id:335) (Token id:Id.Lit_Chars val:'\t) >current &&\n' span_id:336) 
          (Token id:Id.Lit_Chars val:'\tcat >expected <<\\EOF &&\n' span_id:337) (Token id:Id.Lit_Chars val:'100644 blob X\t1.txt\n' span_id:338) 
          (Token id:Id.Lit_Chars val:'100644 blob X\t2.txt\n' span_id:339) (Token id:Id.Lit_Chars val:'100644 blob X\tpath0/a/b/c/1.txt\n' span_id:340) 
          (Token id:Id.Lit_Chars val:'100644 blob X\tpath1/b/c/1.txt\n' span_id:341) (Token id:Id.Lit_Chars val:'100644 blob X\tpath2/1.txt\n' span_id:342) 
          (Token id:Id.Lit_Chars val:'100644 blob X\tpath3/1.txt\n' span_id:343) (Token id:Id.Lit_Chars val:'100644 blob X\tpath3/2.txt\n' span_id:344) 
          (Token id:Id.Lit_Chars val:'EOF\n' span_id:345) (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:346)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'ls-tree --abbrev=5' span_id:353))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:357) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit ls-tree --abbrev=5 $tree >current &&\n'
            span_id: 358
          ) (Token id:Id.Lit_Chars val:'\tsed -e "s/ $_x05[0-9a-f]*\t/ X\t/" <current >check &&\n' span_id:359) 
          (Token id:Id.Lit_Chars val:'\tcat >expected <<\\EOF &&\n' span_id:360) (Token id:Id.Lit_Chars val:'100644 blob X\t1.txt\n' span_id:361) 
          (Token id:Id.Lit_Chars val:'100644 blob X\t2.txt\n' span_id:362) (Token id:Id.Lit_Chars val:'040000 tree X\tpath0\n' span_id:363) 
          (Token id:Id.Lit_Chars val:'040000 tree X\tpath1\n' span_id:364) (Token id:Id.Lit_Chars val:'040000 tree X\tpath2\n' span_id:365) 
          (Token id:Id.Lit_Chars val:'040000 tree X\tpath3\n' span_id:366) (Token id:Id.Lit_Chars val:'EOF\n' span_id:367) 
          (Token id:Id.Lit_Chars val:'\ttest_cmp expected check\n' span_id:368)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'ls-tree --name-only' span_id:375))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:379) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit ls-tree --name-only $tree >current &&\n'
            span_id: 380
          ) (Token id:Id.Lit_Chars val:'\tcat >expected <<\\EOF &&\n' span_id:381) 
          (Token id:Id.Lit_Chars val:'1.txt\n' span_id:382) (Token id:Id.Lit_Chars val:'2.txt\n' span_id:383) (Token id:Id.Lit_Chars val:'path0\n' span_id:384) 
          (Token id:Id.Lit_Chars val:'path1\n' span_id:385) (Token id:Id.Lit_Chars val:'path2\n' span_id:386) (Token id:Id.Lit_Chars val:'path3\n' span_id:387) 
          (Token id:Id.Lit_Chars val:'EOF\n' span_id:388) (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:389)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'ls-tree --name-only -r' span_id:396))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:400) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit ls-tree --name-only -r $tree >current &&\n'
            span_id: 401
          ) (Token id:Id.Lit_Chars val:'\tcat >expected <<\\EOF &&\n' span_id:402) 
          (Token id:Id.Lit_Chars val:'1.txt\n' span_id:403) (Token id:Id.Lit_Chars val:'2.txt\n' span_id:404) 
          (Token id:Id.Lit_Chars val:'path0/a/b/c/1.txt\n' span_id:405) (Token id:Id.Lit_Chars val:'path1/b/c/1.txt\n' span_id:406) 
          (Token id:Id.Lit_Chars val:'path2/1.txt\n' span_id:407) (Token id:Id.Lit_Chars val:'path3/1.txt\n' span_id:408) 
          (Token id:Id.Lit_Chars val:'path3/2.txt\n' span_id:409) (Token id:Id.Lit_Chars val:'EOF\n' span_id:410) 
          (Token id:Id.Lit_Chars val:'\ttest_output\n' span_id:411)
        )
      }
    )
    (C {(test_done)})
  ]
)