(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 update-index --again test.\n' span_id:15))}
          spids: [13]
        )
      ]
    )
    (C {(.)} {(./test-lib.sh)})
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:26)
          fd: -1
          arg_word: {(expected)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:30)
          fd: -1
          here_begin: 
            {(word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\E' span_id:31)) (OF)}
          here_end_span_id: 36
          stdin_parts: [
            ('100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0\tfile1\n')
            ('100644 9db8893856a8a02eaa73470054b7c1c5a7c82e47 0\tfile2\n')
          ]
        )
      ]
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'update-index --add' span_id:40))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'echo hello world >file1 &&\n' span_id:46) 
          (Token id:Id.Lit_Chars val:'\t echo goodbye people >file2 &&\n' span_id:47) (Token id:Id.Lit_Chars val:'\t git update-index --add file1 file2 &&\n' span_id:48) 
          (Token id:Id.Lit_Chars val:'\t git ls-files -s >current &&\n' span_id:49) (Token id:Id.Lit_Chars val:'\t cmp current expected' span_id:50)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'update-index --again' span_id:57))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'rm -f file1 &&\n' span_id:63) 
          (Token id:Id.Lit_Chars val:'\techo hello everybody >file2 &&\n' span_id:64) (Token id:Id.Lit_Chars val:'\tif git update-index --again\n' span_id:65) 
          (Token id:Id.Lit_Chars val:'\tthen\n' span_id:66) (Token id:Id.Lit_Chars val:'\t\techo should have refused to remove file1\n' span_id:67) 
          (Token id:Id.Lit_Chars val:'\t\texit 1\n' span_id:68) (Token id:Id.Lit_Chars val:'\telse\n' span_id:69) 
          (Token id:Id.Lit_Chars val:'\t\techo happy - failed as expected\n' span_id:70) (Token id:Id.Lit_Chars val:'\tfi &&\n' span_id:71) 
          (Token id:Id.Lit_Chars val:'\t git ls-files -s >current &&\n' span_id:72) (Token id:Id.Lit_Chars val:'\t cmp current expected' span_id:73)
        )
      }
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:79)
          fd: -1
          arg_word: {(expected)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:83)
          fd: -1
          here_begin: 
            {(word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\E' span_id:84)) (OF)}
          here_end_span_id: 88
          stdin_parts: [('100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0\tfile2\n')]
        )
      ]
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'update-index --remove --again' span_id:92))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'git update-index --remove --again &&\n' span_id:98) 
          (Token id:Id.Lit_Chars val:'\t git ls-files -s >current &&\n' span_id:99) (Token id:Id.Lit_Chars val:'\t cmp current expected' span_id:100)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'first commit' span_id:107))} 
      {(SQ (Token id:Id.Lit_Chars val:'git commit -m initial' span_id:111))}
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:117)
          fd: -1
          arg_word: {(expected)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:121)
          fd: -1
          here_begin: 
            {(word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\E' span_id:122)) 
              (OF)
            }
          here_end_span_id: 127
          stdin_parts: [
            ('100644 53ab446c3f4e42ce9bb728a0ccb283a101be4979 0\tdir1/file3\n')
            ('100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0\tfile2\n')
          ]
        )
      ]
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'update-index again' span_id:131))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'mkdir -p dir1 &&\n' span_id:137) 
          (Token id:Id.Lit_Chars val:'\techo hello world >dir1/file3 &&\n' span_id:138) (Token id:Id.Lit_Chars val:'\techo goodbye people >file2 &&\n' span_id:139) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit update-index --add file2 dir1/file3 &&\n'
            span_id: 140
          ) (Token id:Id.Lit_Chars val:'\techo hello everybody >file2 &&\n' span_id:141) 
          (Token id:Id.Lit_Chars val:'\techo happy >dir1/file3 &&\n' span_id:142) (Token id:Id.Lit_Chars val:'\tgit update-index --again &&\n' span_id:143) 
          (Token id:Id.Lit_Chars val:'\tgit ls-files -s >current &&\n' span_id:144) (Token id:Id.Lit_Chars val:'\tcmp current expected' span_id:145)
        )
      }
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:151)
          fd: -1
          arg_word: {(expected)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:155)
          fd: -1
          here_begin: 
            {(word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\E' span_id:156)) 
              (OF)
            }
          here_end_span_id: 161
          stdin_parts: [
            ('100644 d7fb3f695f06c759dbf3ab00046e7cc2da22d10f 0\tdir1/file3\n')
            ('100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0\tfile2\n')
          ]
        )
      ]
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'update-index --update from subdir' span_id:165))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'echo not so happy >file2 &&\n' span_id:171) 
          (Token id:Id.Lit_Chars val:'\t(cd dir1 &&\n' span_id:172) (Token id:Id.Lit_Chars val:'\tcat ../file2 >file3 &&\n' span_id:173) 
          (Token id:Id.Lit_Chars val:'\tgit update-index --again\n' span_id:174) (Token id:Id.Lit_Chars val:'\t) &&\n' span_id:175) 
          (Token id:Id.Lit_Chars val:'\tgit ls-files -s >current &&\n' span_id:176) (Token id:Id.Lit_Chars val:'\tcmp current expected' span_id:177)
        )
      }
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:183)
          fd: -1
          arg_word: {(expected)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:187)
          fd: -1
          here_begin: 
            {(word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\E' span_id:188)) 
              (OF)
            }
          here_end_span_id: 193
          stdin_parts: [
            ('100644 594fb5bb1759d90998e2bf2a38261ae8e243c760 0\tdir1/file3\n')
            ('100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0\tfile2\n')
          ]
        )
      ]
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'update-index --update with pathspec' span_id:197))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'echo very happy >file2 &&\n' span_id:203) 
          (Token id:Id.Lit_Chars val:'\tcat file2 >dir1/file3 &&\n' span_id:204) (Token id:Id.Lit_Chars val:'\tgit update-index --again dir1/ &&\n' span_id:205) 
          (Token id:Id.Lit_Chars val:'\tgit ls-files -s >current &&\n' span_id:206) (Token id:Id.Lit_Chars val:'\tcmp current expected' span_id:207)
        )
      }
    )
    (C {(test_done)})
  ]
)