(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:'read-tree -m -u checks working tree files' span_id:6))}
          spids: [4]
        )
      ]
    )
    (C {(.)} {(./test-lib.sh)})
    (C {(.)} {(DQ ($ Id.VSub_DollarName '$TEST_DIRECTORY')) (/lib-read-tree.sh)})
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'two-way setup' span_id:29))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:33) (Token id:Id.Lit_Chars val:'\n' span_id:34) 
          (Token id:Id.Lit_Chars val:'\tmkdir subdir &&\n' span_id:35) (Token id:Id.Lit_Chars val:'\techo >file1 file one &&\n' span_id:36) 
          (Token id:Id.Lit_Chars val:'\techo >file2 file two &&\n' span_id:37) (Token id:Id.Lit_Chars val:'\techo >subdir/file1 file one in subdirectory &&\n' span_id:38) 
          (Token
            id: Id.Lit_Chars
            val: '\techo >subdir/file2 file two in subdirectory &&\n'
            span_id: 39
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit update-index --add file1 file2 subdir/file1 subdir/file2 &&\n'
            span_id: 40
          ) (Token id:Id.Lit_Chars val:'\tgit commit -m initial &&\n' span_id:41) 
          (Token id:Id.Lit_Chars val:'\n' span_id:42) (Token id:Id.Lit_Chars val:'\tgit branch side &&\n' span_id:43) 
          (Token id:Id.Lit_Chars val:'\tgit tag -f branch-point &&\n' span_id:44) (Token id:Id.Lit_Chars val:'\n' span_id:45) 
          (Token
            id: Id.Lit_Chars
            val: '\techo file2 is not tracked on the master anymore &&\n'
            span_id: 46
          ) (Token id:Id.Lit_Chars val:'\trm -f file2 subdir/file2 &&\n' span_id:47) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit update-index --remove file2 subdir/file2 &&\n'
            span_id: 48
          ) (Token id:Id.Lit_Chars val:'\tgit commit -a -m "master removes file2 and subdir/file2"\n' span_id:49)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'two-way not clobbering' span_id:56))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:60) (Token id:Id.Lit_Chars val:'\n' span_id:61) 
          (Token
            id: Id.Lit_Chars
            val: '\techo >file2 master creates untracked file2 &&\n'
            span_id: 62
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\techo >subdir/file2 master creates untracked subdir/file2 &&\n'
            span_id: 63
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\tif err=$(read_tree_u_must_succeed -m -u master side 2>&1)\n'
            span_id: 64
          ) (Token id:Id.Lit_Chars val:'\tthen\n' span_id:65) 
          (Token id:Id.Lit_Chars val:'\t\techo should have complained\n' span_id:66) (Token id:Id.Lit_Chars val:'\t\tfalse\n' span_id:67) (Token id:Id.Lit_Chars val:'\telse\n' span_id:68) 
          (Token id:Id.Lit_Chars val:'\t\techo "happy to see $err"\n' span_id:69) (Token id:Id.Lit_Chars val:'\tfi\n' span_id:70)
        )
      }
    )
    (command.Simple
      words: [{(echo)} {(file2)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:78)
          fd: -1
          arg_word: {(.gitignore)}
        )
      ]
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'two-way with incorrect --exclude-per-directory (1)'
            span_id: 85
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:89) (Token id:Id.Lit_Chars val:'\n' span_id:90) 
          (Token
            id: Id.Lit_Chars
            val: 
'\tif err=$(read_tree_u_must_succeed -m --exclude-per-directory=.gitignore master side 2>&1)\n'
            span_id: 91
          ) (Token id:Id.Lit_Chars val:'\tthen\n' span_id:92) 
          (Token id:Id.Lit_Chars val:'\t\techo should have complained\n' span_id:93) (Token id:Id.Lit_Chars val:'\t\tfalse\n' span_id:94) (Token id:Id.Lit_Chars val:'\telse\n' span_id:95) 
          (Token id:Id.Lit_Chars val:'\t\techo "happy to see $err"\n' span_id:96) (Token id:Id.Lit_Chars val:'\tfi\n' span_id:97)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'two-way with incorrect --exclude-per-directory (2)'
            span_id: 104
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:108) (Token id:Id.Lit_Chars val:'\n' span_id:109) 
          (Token
            id: Id.Lit_Chars
            val: 
'\tif err=$(read_tree_u_must_succeed -m -u --exclude-per-directory=foo --exclude-per-directory=.gitignore master side 2>&1)\n'
            span_id: 110
          ) (Token id:Id.Lit_Chars val:'\tthen\n' span_id:111) 
          (Token id:Id.Lit_Chars val:'\t\techo should have complained\n' span_id:112) (Token id:Id.Lit_Chars val:'\t\tfalse\n' span_id:113) 
          (Token id:Id.Lit_Chars val:'\telse\n' span_id:114) (Token id:Id.Lit_Chars val:'\t\techo "happy to see $err"\n' span_id:115) 
          (Token id:Id.Lit_Chars val:'\tfi\n' span_id:116)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'two-way clobbering a ignored file' span_id:123))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:127) (Token id:Id.Lit_Chars val:'\n' span_id:128) 
          (Token
            id: Id.Lit_Chars
            val: '\tread_tree_u_must_succeed -m -u --exclude-per-directory=.gitignore master side\n'
            span_id: 129
          )
        )
      }
    )
    (C {(rm)} {(-f)} {(.gitignore)})
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: 'three-way not complaining on an untracked path in both'
            span_id: 147
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:151) (Token id:Id.Lit_Chars val:'\n' span_id:152) 
          (Token id:Id.Lit_Chars val:'\trm -f file2 subdir/file2 &&\n' span_id:153) (Token id:Id.Lit_Chars val:'\tgit checkout side &&\n' span_id:154) 
          (Token id:Id.Lit_Chars val:'\techo >file3 file three &&\n' span_id:155) (Token id:Id.Lit_Chars val:'\techo >subdir/file3 file three &&\n' span_id:156) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit update-index --add file3 subdir/file3 &&\n'
            span_id: 157
          ) (Token id:Id.Lit_Chars val:'\tgit commit -a -m "side adds file3 and removes file2" &&\n' span_id:158) 
          (Token id:Id.Lit_Chars val:'\n' span_id:159) (Token id:Id.Lit_Chars val:'\tgit checkout master &&\n' span_id:160) 
          (Token
            id: Id.Lit_Chars
            val: '\techo >file2 file two is untracked on the master side &&\n'
            span_id: 161
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\techo >subdir/file2 file two is untracked on the master side &&\n'
            span_id: 162
          ) (Token id:Id.Lit_Chars val:'\n' span_id:163) 
          (Token
            id: Id.Lit_Chars
            val: '\tread_tree_u_must_succeed -m -u branch-point master side\n'
            span_id: 164
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'three-way not clobbering a working tree file' span_id:171))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:175) (Token id:Id.Lit_Chars val:'\n' span_id:176) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:177) (Token id:Id.Lit_Chars val:'\trm -f file2 subdir/file2 file3 subdir/file3 &&\n' span_id:178) 
          (Token id:Id.Lit_Chars val:'\tgit checkout master &&\n' span_id:179) (Token id:Id.Lit_Chars val:'\techo >file3 file three created in master, untracked &&\n' span_id:180) 
          (Token
            id: Id.Lit_Chars
            val: '\techo >subdir/file3 file three created in master, untracked &&\n'
            span_id: 181
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\tif err=$(read_tree_u_must_succeed -m -u branch-point master side 2>&1)\n'
            span_id: 182
          ) (Token id:Id.Lit_Chars val:'\tthen\n' span_id:183) 
          (Token id:Id.Lit_Chars val:'\t\techo should have complained\n' span_id:184) (Token id:Id.Lit_Chars val:'\t\tfalse\n' span_id:185) 
          (Token id:Id.Lit_Chars val:'\telse\n' span_id:186) (Token id:Id.Lit_Chars val:'\t\techo "happy to see $err"\n' span_id:187) 
          (Token id:Id.Lit_Chars val:'\tfi\n' span_id:188)
        )
      }
    )
    (command.Simple
      words: [{(echo)} {(file3)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:194)
          fd: -1
          arg_word: {(.gitignore)}
        )
      ]
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'three-way not complaining on an untracked file' span_id:203))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:207) (Token id:Id.Lit_Chars val:'\n' span_id:208) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:209) (Token id:Id.Lit_Chars val:'\trm -f file2 subdir/file2 file3 subdir/file3 &&\n' span_id:210) 
          (Token id:Id.Lit_Chars val:'\tgit checkout master &&\n' span_id:211) (Token id:Id.Lit_Chars val:'\techo >file3 file three created in master, untracked &&\n' span_id:212) 
          (Token
            id: Id.Lit_Chars
            val: '\techo >subdir/file3 file three created in master, untracked &&\n'
            span_id: 213
          ) (Token id:Id.Lit_Chars val:'\n' span_id:214) 
          (Token
            id: Id.Lit_Chars
            val: 
'\tread_tree_u_must_succeed -m -u --exclude-per-directory=.gitignore branch-point master side\n'
            span_id: 215
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'3-way not overwriting local changes (setup)' span_id:222))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:226) (Token id:Id.Lit_Chars val:'\n' span_id:227) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:228) (Token id:Id.Lit_Chars val:'\tgit checkout -b side-a branch-point &&\n' span_id:229) 
          (Token
            id: Id.Lit_Chars
            val: '\techo >>file1 "new line to be kept in the merge result" &&\n'
            span_id: 230
          ) (Token id:Id.Lit_Chars val:'\tgit commit -a -m "side-a changes file1" &&\n' span_id:231) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit checkout -b side-b branch-point &&\n'
            span_id: 232
          ) 
          (Token
            id: Id.Lit_Chars
            val: '\techo >>file2 "new line to be kept in the merge result" &&\n'
            span_id: 233
          ) (Token id:Id.Lit_Chars val:'\tgit commit -a -m "side-b changes file2" &&\n' span_id:234) 
          (Token id:Id.Lit_Chars val:'\tgit checkout side-a\n' span_id:235) (Token id:Id.Lit_Chars val:'\n' span_id:236)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'3-way not overwriting local changes (our side)' span_id:243))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:247) (Token id:Id.Lit_Chars val:'\n' span_id:248) 
          (Token
            id: Id.Lit_Chars
            val: '\t# At this point, file1 from side-a should be kept as side-b\n'
            span_id: 249
          ) (Token id:Id.Lit_Chars val:'\t# did not touch it.\n' span_id:250) 
          (Token id:Id.Lit_Chars val:'\n' span_id:251) (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:252) 
          (Token id:Id.Lit_Chars val:'\n' span_id:253) (Token id:Id.Lit_Chars val:'\techo >>file1 "local changes" &&\n' span_id:254) 
          (Token
            id: Id.Lit_Chars
            val: '\tread_tree_u_must_succeed -m -u branch-point side-a side-b &&\n'
            span_id: 255
          ) (Token id:Id.Lit_Chars val:'\tgrep "new line to be kept" file1 &&\n' span_id:256) 
          (Token id:Id.Lit_Chars val:'\tgrep "local changes" file1\n' span_id:257) (Token id:Id.Lit_Chars val:'\n' span_id:258)
        )
      }
    )
    (C {(test_expect_success)} 
      {
        (SQ 
          (Token
            id: Id.Lit_Chars
            val: '3-way not overwriting local changes (their side)'
            span_id: 265
          )
        )
      } 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:269) (Token id:Id.Lit_Chars val:'\n' span_id:270) 
          (Token
            id: Id.Lit_Chars
            val: '\t# At this point, file2 from side-b should be taken as side-a\n'
            span_id: 271
          ) (Token id:Id.Lit_Chars val:'\t# did not touch it.\n' span_id:272) 
          (Token id:Id.Lit_Chars val:'\n' span_id:273) (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:274) 
          (Token id:Id.Lit_Chars val:'\n' span_id:275) (Token id:Id.Lit_Chars val:'\techo >>file2 "local changes" &&\n' span_id:276) 
          (Token
            id: Id.Lit_Chars
            val: '\tread_tree_u_must_fail -m -u branch-point side-a side-b &&\n'
            span_id: 277
          ) (Token id:Id.Lit_Chars val:'\t! grep "new line to be kept" file2 &&\n' span_id:278) 
          (Token id:Id.Lit_Chars val:'\tgrep "local changes" file2\n' span_id:279) (Token id:Id.Lit_Chars val:'\n' span_id:280)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'funny symlink in work tree' span_id:287))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:291) (Token id:Id.Lit_Chars val:'\n' span_id:292) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:293) (Token id:Id.Lit_Chars val:'\tgit checkout -b sym-b side-b &&\n' span_id:294) 
          (Token id:Id.Lit_Chars val:'\tmkdir -p a &&\n' span_id:295) (Token id:Id.Lit_Chars val:'\t>a/b &&\n' span_id:296) 
          (Token id:Id.Lit_Chars val:'\tgit add a/b &&\n' span_id:297) (Token id:Id.Lit_Chars val:'\tgit commit -m "side adds a/b" &&\n' span_id:298) 
          (Token id:Id.Lit_Chars val:'\n' span_id:299) (Token id:Id.Lit_Chars val:'\trm -fr a &&\n' span_id:300) 
          (Token id:Id.Lit_Chars val:'\tgit checkout -b sym-a side-a &&\n' span_id:301) (Token id:Id.Lit_Chars val:'\tmkdir -p a &&\n' span_id:302) 
          (Token id:Id.Lit_Chars val:'\ttest_ln_s_add ../b a/b &&\n' span_id:303) (Token id:Id.Lit_Chars val:'\tgit commit -m "we add a/b" &&\n' span_id:304) 
          (Token id:Id.Lit_Chars val:'\n' span_id:305) (Token id:Id.Lit_Chars val:'\tread_tree_u_must_succeed -m -u sym-a sym-a sym-b\n' span_id:306) 
          (Token id:Id.Lit_Chars val:'\n' span_id:307)
        )
      }
    )
    (C {(test_expect_success)} {(SANITY)} 
      {(SQ (Token id:Id.Lit_Chars val:'funny symlink in work tree, un-unlink-able' span_id:316))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:320) (Token id:Id.Lit_Chars val:'\n' span_id:321) 
          (Token id:Id.Lit_Chars val:'\trm -fr a b &&\n' span_id:322) (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:323) 
          (Token id:Id.Lit_Chars val:'\n' span_id:324) (Token id:Id.Lit_Chars val:'\tgit checkout sym-a &&\n' span_id:325) 
          (Token id:Id.Lit_Chars val:'\tchmod a-w a &&\n' span_id:326) (Token id:Id.Lit_Chars val:'\ttest_must_fail git read-tree -m -u sym-a sym-a sym-b\n' span_id:327) 
          (Token id:Id.Lit_Chars val:'\n' span_id:328)
        )
      }
    )
    (command.Simple
      words: [{(chmod)} {(a) (Id.Lit_Other '+') (w)} {(a)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'2>' span_id:343)
          fd: 2
          arg_word: {(/dev/null)}
        )
      ]
    )
    (C {(rm)} {(-fr)} {(a)} {(b)})
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'D/F setup' span_id:358))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:362) (Token id:Id.Lit_Chars val:'\n' span_id:363) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:364) (Token id:Id.Lit_Chars val:'\n' span_id:365) 
          (Token id:Id.Lit_Chars val:'\tgit checkout side-a &&\n' span_id:366) (Token id:Id.Lit_Chars val:'\trm -f subdir/file2 &&\n' span_id:367) 
          (Token id:Id.Lit_Chars val:'\tmkdir subdir/file2 &&\n' span_id:368) (Token id:Id.Lit_Chars val:'\techo qfwfq >subdir/file2/another &&\n' span_id:369) 
          (Token id:Id.Lit_Chars val:'\tgit add subdir/file2/another &&\n' span_id:370) (Token id:Id.Lit_Chars val:'\ttest_tick &&\n' span_id:371) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit commit -m "side-a changes file2 to directory"\n'
            span_id: 372
          ) (Token id:Id.Lit_Chars val:'\n' span_id:373)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:D/F span_id:380))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:384) (Token id:Id.Lit_Chars val:'\n' span_id:385) 
          (Token id:Id.Lit_Chars val:'\tgit checkout side-b &&\n' span_id:386) 
          (Token
            id: Id.Lit_Chars
            val: '\tread_tree_u_must_succeed -m -u branch-point side-b side-a &&\n'
            span_id: 387
          ) (Token id:Id.Lit_Chars val:'\tgit ls-files -u >actual &&\n' span_id:388) 
          (Token id:Id.Lit_Chars val:'\t(\n' span_id:389) (Token id:Id.Lit_Chars val:'\t\ta=$(git rev-parse branch-point:subdir/file2)\n' span_id:390) 
          (Token
            id: Id.Lit_Chars
            val: '\t\tb=$(git rev-parse side-a:subdir/file2/another)\n'
            span_id: 391
          ) (Token id:Id.Lit_Chars val:'\t\techo "100644 $a 1\tsubdir/file2"\n' span_id:392) 
          (Token id:Id.Lit_Chars val:'\t\techo "100644 $a 2\tsubdir/file2"\n' span_id:393) (Token id:Id.Lit_Chars val:'\t\techo "100644 $b 3\tsubdir/file2/another"\n' span_id:394) 
          (Token id:Id.Lit_Chars val:'\t) >expect &&\n' span_id:395) (Token id:Id.Lit_Chars val:'\ttest_cmp actual expect\n' span_id:396) 
          (Token id:Id.Lit_Chars val:'\n' span_id:397)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'D/F resolve' span_id:404))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:408) (Token id:Id.Lit_Chars val:'\n' span_id:409) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:410) (Token id:Id.Lit_Chars val:'\tgit checkout side-b &&\n' span_id:411) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit merge-resolve branch-point -- side-b side-a\n'
            span_id: 412
          ) (Token id:Id.Lit_Chars val:'\n' span_id:413)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'D/F recursive' span_id:420))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:424) (Token id:Id.Lit_Chars val:'\n' span_id:425) 
          (Token id:Id.Lit_Chars val:'\tgit reset --hard &&\n' span_id:426) (Token id:Id.Lit_Chars val:'\tgit checkout side-b &&\n' span_id:427) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit merge-recursive branch-point -- side-b side-a\n'
            span_id: 428
          ) (Token id:Id.Lit_Chars val:'\n' span_id:429)
        )
      }
    )
    (C {(test_done)})
  ]
)