(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:'prepare-commit-msg hook' span_id:6))}
          spids: [4]
        )
      ]
    )
    (C {(.)} {(./test-lib.sh)})
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'with no hook' span_id:18))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:22) (Token id:Id.Lit_Chars val:'\n' span_id:23) 
          (Token id:Id.Lit_Chars val:'\techo "foo" > file &&\n' span_id:24) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:25) 
          (Token id:Id.Lit_Chars val:'\tgit commit -m "first"\n' span_id:26) (Token id:Id.Lit_Chars val:'\n' span_id:27)
        )
      }
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:36)
          fd: -1
          arg_word: {(fake-editor)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:40)
          fd: -1
          here_begin: {(SQ (Token id:Id.Lit_Chars val:EOF span_id:42))}
          here_end_span_id: 47
          stdin_parts: [('#!/bin/sh\n') ('exit 0\n')]
        )
      ]
    )
    (C {(chmod)} {(Id.Lit_Other '+') (x)} {(fake-editor)})
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:FAKE_EDITOR)
          op: assign_op.Equal
          rhs: 
            {
              (DQ 
                (command_sub
                  left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:64)
                  command_list: (command.CommandList children:[(C {(pwd)})])
                ) (/fake-editor)
              )
            }
          spids: [62]
        )
      ]
    )
    (C {(export)} {(FAKE_EDITOR)})
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:HOOKDIR)
          op: assign_op.Equal
          rhs: 
            {
              (DQ 
                (command_sub
                  left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:80)
                  command_list: 
                    (command.CommandList
                      children: [(C {(git)} {(rev-parse)} {(--git-dir)})]
                    )
                ) (/hooks)
              )
            }
          spids: [78]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:HOOK)
          op: assign_op.Equal
          rhs: {(DQ ($ Id.VSub_DollarName '$HOOKDIR') (/prepare-commit-msg))}
          spids: [90]
        )
      ]
    )
    (C {(mkdir)} {(-p)} {(DQ ($ Id.VSub_DollarName '$HOOKDIR'))})
    (command.Simple
      words: [{(echo)} {(DQ ('#!') ($ Id.VSub_DollarName '$SHELL_PATH'))}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:111)
          fd: -1
          arg_word: {(DQ ($ Id.VSub_DollarName '$HOOK'))}
        )
      ]
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_DGreat val:'>>' span_id:119)
          fd: -1
          arg_word: {(DQ ($ Id.VSub_DollarName '$HOOK'))}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:125)
          fd: -1
          here_begin: {(SQ (Token id:Id.Lit_Chars val:EOF span_id:127))}
          here_end_span_id: 143
          stdin_parts: [
            ('\n')
            ('if test "$2" = commit; then\n')
            ('  source=$(git rev-parse "$3")\n')
            ('else\n')
            ('  source=${2-default}\n')
            ('fi\n')
            ('if test "$GIT_EDITOR" = :; then\n')
            ('  sed -e "1s/.*/$source (no editor)/" "$1" > msg.tmp\n')
            ('else\n')
            ('  sed -e "1s/.*/$source/" "$1" > msg.tmp\n')
            ('fi\n')
            ('mv msg.tmp "$1"\n')
            ('exit 0\n')
          ]
        )
      ]
    )
    (C {(chmod)} {(Id.Lit_Other '+') (x)} {(DQ ($ Id.VSub_DollarName '$HOOK'))})
    (command.Simple
      words: [{(echo)} {(dummy)} {(template)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:160)
          fd: -1
          arg_word: 
            {
              (DQ 
                (command_sub
                  left_token: (Token id:Id.Left_DollarParen val:'$(' span_id:163)
                  command_list: 
                    (command.CommandList
                      children: [(C {(git)} {(rev-parse)} {(--git-dir)})]
                    )
                ) (/template)
              )
            }
        )
      ]
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'with hook (-m)' span_id:177))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:181) (Token id:Id.Lit_Chars val:'\n' span_id:182) 
          (Token id:Id.Lit_Chars val:'\techo "more" >> file &&\n' span_id:183) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:184) 
          (Token id:Id.Lit_Chars val:'\tgit commit -m "more" &&\n' span_id:185) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest "$(git log -1 --pretty=format:%s)" = "message (no editor)"\n'
            span_id: 186
          ) (Token id:Id.Lit_Chars val:'\n' span_id:187)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'with hook (-m editor)' span_id:194))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:198) (Token id:Id.Lit_Chars val:'\n' span_id:199) 
          (Token id:Id.Lit_Chars val:'\techo "more" >> file &&\n' span_id:200) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:201) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit -e -m "more more" &&\n'
            span_id: 202
          ) (Token id:Id.Lit_Chars val:'\ttest "$(git log -1 --pretty=format:%s)" = message\n' span_id:203) 
          (Token id:Id.Lit_Chars val:'\n' span_id:204)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'with hook (-t)' span_id:211))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:215) (Token id:Id.Lit_Chars val:'\n' span_id:216) 
          (Token id:Id.Lit_Chars val:'\techo "more" >> file &&\n' span_id:217) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:218) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit commit -t "$(git rev-parse --git-dir)/template" &&\n'
            span_id: 219
          ) (Token id:Id.Lit_Chars val:'\ttest "$(git log -1 --pretty=format:%s)" = template\n' span_id:220) 
          (Token id:Id.Lit_Chars val:'\n' span_id:221)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'with hook (-F)' span_id:228))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:232) (Token id:Id.Lit_Chars val:'\n' span_id:233) 
          (Token id:Id.Lit_Chars val:'\techo "more" >> file &&\n' span_id:234) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:235) 
          (Token id:Id.Lit_Chars val:'\t(echo more | git commit -F -) &&\n' span_id:236) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest "$(git log -1 --pretty=format:%s)" = "message (no editor)"\n'
            span_id: 237
          ) (Token id:Id.Lit_Chars val:'\n' span_id:238)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'with hook (-F editor)' span_id:245))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:249) (Token id:Id.Lit_Chars val:'\n' span_id:250) 
          (Token id:Id.Lit_Chars val:'\techo "more" >> file &&\n' span_id:251) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:252) 
          (Token
            id: Id.Lit_Chars
            val: '\t(echo more more | GIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit -e -F -) &&\n'
            span_id: 253
          ) (Token id:Id.Lit_Chars val:'\ttest "$(git log -1 --pretty=format:%s)" = message\n' span_id:254) 
          (Token id:Id.Lit_Chars val:'\n' span_id:255)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'with hook (-C)' span_id:262))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:266) (Token id:Id.Lit_Chars val:'\n' span_id:267) 
          (Token id:Id.Lit_Chars val:'\thead=$(git rev-parse HEAD) &&\n' span_id:268) (Token id:Id.Lit_Chars val:'\techo "more" >> file &&\n' span_id:269) 
          (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:270) (Token id:Id.Lit_Chars val:'\tgit commit -C $head &&\n' span_id:271) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest "$(git log -1 --pretty=format:%s)" = "$head (no editor)"\n'
            span_id: 272
          ) (Token id:Id.Lit_Chars val:'\n' span_id:273)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'with hook (editor)' span_id:280))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:284) (Token id:Id.Lit_Chars val:'\n' span_id:285) 
          (Token id:Id.Lit_Chars val:'\techo "more more" >> file &&\n' span_id:286) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:287) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit &&\n'
            span_id: 288
          ) (Token id:Id.Lit_Chars val:'\ttest "$(git log -1 --pretty=format:%s)" = default\n' span_id:289) 
          (Token id:Id.Lit_Chars val:'\n' span_id:290)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'with hook (--amend)' span_id:297))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:301) (Token id:Id.Lit_Chars val:'\n' span_id:302) 
          (Token id:Id.Lit_Chars val:'\thead=$(git rev-parse HEAD) &&\n' span_id:303) (Token id:Id.Lit_Chars val:'\techo "more" >> file &&\n' span_id:304) 
          (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:305) (Token id:Id.Lit_Chars val:'\tGIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit --amend &&\n' span_id:306) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest "$(git log -1 --pretty=format:%s)" = "$head"\n'
            span_id: 307
          ) (Token id:Id.Lit_Chars val:'\n' span_id:308)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'with hook (-c)' span_id:315))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:319) (Token id:Id.Lit_Chars val:'\n' span_id:320) 
          (Token id:Id.Lit_Chars val:'\thead=$(git rev-parse HEAD) &&\n' span_id:321) (Token id:Id.Lit_Chars val:'\techo "more" >> file &&\n' span_id:322) 
          (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:323) 
          (Token
            id: Id.Lit_Chars
            val: '\tGIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit -c $head &&\n'
            span_id: 324
          ) (Token id:Id.Lit_Chars val:'\ttest "$(git log -1 --pretty=format:%s)" = "$head"\n' span_id:325) 
          (Token id:Id.Lit_Chars val:'\n' span_id:326)
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'with hook (merge)' span_id:333))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:337) (Token id:Id.Lit_Chars val:'\n' span_id:338) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_when_finished "git checkout -f master" &&\n'
            span_id: 339
          ) (Token id:Id.Lit_Chars val:'\tgit checkout -B other HEAD@{1} &&\n' span_id:340) 
          (Token id:Id.Lit_Chars val:'\techo "more" >>file &&\n' span_id:341) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:342) 
          (Token id:Id.Lit_Chars val:'\tgit commit -m other &&\n' span_id:343) (Token id:Id.Lit_Chars val:'\tgit checkout - &&\n' span_id:344) 
          (Token id:Id.Lit_Chars val:'\tgit merge --no-ff other &&\n' span_id:345) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest "$(git log -1 --pretty=format:%s)" = "merge (no editor)"\n'
            span_id: 346
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'with hook and editor (merge)' span_id:353))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:357) (Token id:Id.Lit_Chars val:'\n' span_id:358) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_when_finished "git checkout -f master" &&\n'
            span_id: 359
          ) (Token id:Id.Lit_Chars val:'\tgit checkout -B other HEAD@{1} &&\n' span_id:360) 
          (Token id:Id.Lit_Chars val:'\techo "more" >>file &&\n' span_id:361) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:362) 
          (Token id:Id.Lit_Chars val:'\tgit commit -m other &&\n' span_id:363) (Token id:Id.Lit_Chars val:'\tgit checkout - &&\n' span_id:364) 
          (Token
            id: Id.Lit_Chars
            val: '\tenv GIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git merge --no-ff -e other &&\n'
            span_id: 365
          ) (Token id:Id.Lit_Chars val:'\ttest "$(git log -1 --pretty=format:%s)" = "merge"\n' span_id:366)
        )
      }
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:372)
          fd: -1
          arg_word: {(DQ ($ Id.VSub_DollarName '$HOOK'))}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:378)
          fd: -1
          here_begin: {(SQ (Token id:Id.Lit_Chars val:EOF span_id:380))}
          here_end_span_id: 385
          stdin_parts: [('#!/bin/sh\n') ('exit 1\n')]
        )
      ]
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'with failing hook' span_id:390))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:394) (Token id:Id.Lit_Chars val:'\n' span_id:395) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_when_finished "git checkout -f master" &&\n'
            span_id: 396
          ) (Token id:Id.Lit_Chars val:'\thead=$(git rev-parse HEAD) &&\n' span_id:397) 
          (Token id:Id.Lit_Chars val:'\techo "more" >> file &&\n' span_id:398) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:399) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_must_fail env GIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit -c $head\n'
            span_id: 400
          ) (Token id:Id.Lit_Chars val:'\n' span_id:401)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'with failing hook (--no-verify)' span_id:408))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:412) (Token id:Id.Lit_Chars val:'\n' span_id:413) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_when_finished "git checkout -f master" &&\n'
            span_id: 414
          ) (Token id:Id.Lit_Chars val:'\thead=$(git rev-parse HEAD) &&\n' span_id:415) 
          (Token id:Id.Lit_Chars val:'\techo "more" >> file &&\n' span_id:416) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:417) 
          (Token
            id: Id.Lit_Chars
            val: 
'\ttest_must_fail env GIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit --no-verify -c $head\n'
            span_id: 418
          ) (Token id:Id.Lit_Chars val:'\n' span_id:419)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'with failing hook (merge)' span_id:426))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:430) (Token id:Id.Lit_Chars val:'\n' span_id:431) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_when_finished "git checkout -f master" &&\n'
            span_id: 432
          ) (Token id:Id.Lit_Chars val:'\tgit checkout -B other HEAD@{1} &&\n' span_id:433) 
          (Token id:Id.Lit_Chars val:'\techo "more" >> file &&\n' span_id:434) (Token id:Id.Lit_Chars val:'\tgit add file &&\n' span_id:435) 
          (Token id:Id.Lit_Chars val:'\trm -f "$HOOK" &&\n' span_id:436) (Token id:Id.Lit_Chars val:'\tgit commit -m other &&\n' span_id:437) 
          (Token id:Id.Lit_Chars val:'\twrite_script "$HOOK" <<-EOF &&\n' span_id:438) (Token id:Id.Lit_Chars val:'\texit 1\n' span_id:439) (Token id:Id.Lit_Chars val:'\tEOF\n' span_id:440) 
          (Token id:Id.Lit_Chars val:'\tgit checkout - &&\n' span_id:441) (Token id:Id.Lit_Chars val:'\ttest_must_fail git merge --no-ff other\n' span_id:442) 
          (Token id:Id.Lit_Chars val:'\n' span_id:443)
        )
      }
    )
    (C {(test_done)})
  ]
)