(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_description)
          op: assign_op.Equal
          rhs: {(SQ <'commit-msg hook'>)}
          spids: [4]
        )
      ]
    )
    (C {<.>} {<'./test-lib.sh'>})
    (C {<test_expect_success>} {(SQ <'with no hook'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "foo" > file &&\n'> <'\tgit add file &&\n'> 
          <'\tgit commit -m "first"\n'> <'\n'>
        )
      }
    )
    (command.Simple
      words: [{<cat>}]
      redirects: [
        (redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<fake-editor>})
        (redir
          op: <Id.Redir_DLess '<<'>
          loc: (redir_loc.Fd fd:0)
          arg: 
            (redir_param.HereDoc
              here_begin: {(SQ <EOF>)}
              here_end_span_id: 48
              stdin_parts: [<'#!/bin/sh\n'> <'cp FAKE_MSG "$1"\n'> <'exit 0\n'>]
            )
        )
      ]
      do_fork: T
    )
    (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:<Id.Left_DollarParen '$('> child:(C {<pwd>})) 
                <'/fake-editor'>
              )
            }
          spids: [63]
        )
      ]
    )
    (C {<export>} {<FAKE_EDITOR>})
    (C {<test_expect_success>} {(SQ <'with no hook (editor)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "more foo" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\techo "more foo" > FAKE_MSG &&\n'> <'\tGIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'--no-verify with no hook'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "bar" > file &&\n'> <'\tgit add file &&\n'> 
          <'\tgit commit --no-verify -m "bar"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'--no-verify with no hook (editor)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "more bar" > file &&\n'> <'\tgit add file &&\n'> 
          <'\techo "more bar" > FAKE_MSG &&\n'> <'\tGIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit --no-verify\n'> <'\n'>
        )
      }
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:HOOKDIR)
          op: assign_op.Equal
          rhs: 
            {
              (DQ 
                (command_sub
                  left_token: <Id.Left_DollarParen '$('>
                  child: (C {<git>} {<rev-parse>} {<--git-dir>})
                ) <'/hooks'>
              )
            }
          spids: [129]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:HOOK)
          op: assign_op.Equal
          rhs: {(DQ ($ Id.VSub_DollarName '$HOOKDIR') <'/commit-msg'>)}
          spids: [141]
        )
      ]
    )
    (C {<mkdir>} {<-p>} {(DQ ($ Id.VSub_DollarName '$HOOKDIR'))})
    (command.Simple
      words: [{<cat>}]
      redirects: [
        (redir
          op: <Id.Redir_Great '>'>
          loc: (redir_loc.Fd fd:1)
          arg: {(DQ ($ Id.VSub_DollarName '$HOOK'))}
        )
        (redir
          op: <Id.Redir_DLess '<<'>
          loc: (redir_loc.Fd fd:0)
          arg: 
            (redir_param.HereDoc
              here_begin: {<EOF>}
              here_end_span_id: 169
              stdin_parts: [<'#!/bin/sh\n'> <'exit 0\n'>]
            )
        )
      ]
      do_fork: T
    )
    (C {<chmod>} {<Id.Lit_Other '+'> <x>} {(DQ ($ Id.VSub_DollarName '$HOOK'))})
    (C {<test_expect_success>} {(SQ <'with succeeding hook'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "more" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\tgit commit -m "more"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'with succeeding hook (editor)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "more more" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\techo "more more" > FAKE_MSG &&\n'> <'\tGIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'--no-verify with succeeding hook'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "even more" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\tgit commit --no-verify -m "even more"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'--no-verify with succeeding hook (editor)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "even more more" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\techo "even more more" > FAKE_MSG &&\n'> <'\tGIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit --no-verify\n'> <'\n'>
        )
      }
    )
    (command.Simple
      words: [{<cat>}]
      redirects: [
        (redir
          op: <Id.Redir_Great '>'>
          loc: (redir_loc.Fd fd:1)
          arg: {(DQ ($ Id.VSub_DollarName '$HOOK'))}
        )
        (redir
          op: <Id.Redir_DLess '<<'>
          loc: (redir_loc.Fd fd:0)
          arg: 
            (redir_param.HereDoc
              here_begin: {<EOF>}
              here_end_span_id: 263
              stdin_parts: [<'#!/bin/sh\n'> <'exit 1\n'>]
            )
        )
      ]
      do_fork: T
    )
    (C {<test_expect_success>} {(SQ <'with failing hook'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "another" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\ttest_must_fail git commit -m "another"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'with failing hook (editor)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "more another" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\techo "more another" > FAKE_MSG &&\n'> <'\t! (GIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit)\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'--no-verify with failing hook'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "stuff" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\tgit commit --no-verify -m "stuff"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'--no-verify with failing hook (editor)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "more stuff" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\techo "more stuff" > FAKE_MSG &&\n'> <'\tGIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit --no-verify\n'> <'\n'>
        )
      }
    )
    (C {<chmod>} {<-x>} {(DQ ($ Id.VSub_DollarName '$HOOK'))})
    (C {<test_expect_success>} {<POSIXPERM>} {(SQ <'with non-executable hook'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "content" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\tgit commit -m "content"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {<POSIXPERM>} {(SQ <'with non-executable hook (editor)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "content again" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\techo "content again" > FAKE_MSG &&\n'> <'\tGIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit -m "content again"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {<POSIXPERM>} {(SQ <'--no-verify with non-executable hook'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "more content" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\tgit commit --no-verify -m "more content"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {<POSIXPERM>} {(SQ <'--no-verify with non-executable hook (editor)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "even more content" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\techo "even more content" > FAKE_MSG &&\n'> <'\tGIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit --no-verify\n'> <'\n'>
        )
      }
    )
    (command.Simple
      words: [{<cat>}]
      redirects: [
        (redir
          op: <Id.Redir_Great '>'>
          loc: (redir_loc.Fd fd:1)
          arg: {(DQ ($ Id.VSub_DollarName '$HOOK'))}
        )
        (redir
          op: <Id.Redir_DLess '<<'>
          loc: (redir_loc.Fd fd:0)
          arg: 
            (redir_param.HereDoc
              here_begin: {(SQ <EOF>)}
              here_end_span_id: 432
              stdin_parts: [<'#!/bin/sh\n'> <'echo "new message" > "$1"\n'> <'exit 0\n'>]
            )
        )
      ]
      do_fork: T
    )
    (C {<chmod>} {<Id.Lit_Other '+'> <x>} {(DQ ($ Id.VSub_DollarName '$HOOK'))})
    (command.ShFunction
      name: commit_msg_is
      body: 
        (BraceGroup
          children: [
            (C {<test>} 
              {
                (DQ 
                  (command_sub
                    left_token: <Id.Left_DollarParen '$('>
                    child: 
                      (C {<git>} {<log>} 
                        {<--pretty> <Id.Lit_Equals '='> <format> <Id.Lit_Colon ':'> <Id.Lit_Other '%'> 
                          <s> <Id.Lit_Other '%'> <b>
                        } {<-1>}
                      )
                  )
                )
              } {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_Number '$1'))}
            )
          ]
        )
    )
    (C {<test_expect_success>} {(SQ <'hook edits commit message'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "additional" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\tgit commit -m "additional" &&\n'> <'\tcommit_msg_is "new message"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'hook edits commit message (editor)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "additional content" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\techo "additional content" > FAKE_MSG &&\n'> <'\tGIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit &&\n'> <'\tcommit_msg_is "new message"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(DQ <'hook doesn\'t edit commit message'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "plus" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\tgit commit --no-verify -m "plus" &&\n'> <'\tcommit_msg_is "plus"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(DQ <'hook doesn\'t edit commit message (editor)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo "more plus" >> file &&\n'> <'\tgit add file &&\n'> 
          <'\techo "more plus" > FAKE_MSG &&\n'> <'\tGIT_EDITOR="\\"\\$FAKE_EDITOR\\"" git commit --no-verify &&\n'> <'\tcommit_msg_is "more plus"\n'> 
          <'\n'>
        )
      }
    )
    (C {<test_done>})
  ]
)