(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_description)
          op: assign_op.Equal
          rhs: {(SQ <'git commit porcelain-ish'>)}
          spids: [4]
        )
      ]
    )
    (C {<.>} {<'./test-lib.sh'>})
    (command.ShFunction
      name: commit_msg_is
      body: 
        (BraceGroup
          children: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:expect)
                  op: assign_op.Equal
                  rhs: {<commit_msg_is.expect>}
                  spids: [23]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:actual)
                  op: assign_op.Equal
                  rhs: {<commit_msg_is.actual>}
                  spids: [27]
                )
              ]
            )
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp]
              children: [
                (command.Simple
                  words: [
                    {<printf>}
                    {(DQ <'%s'>)}
                    {
                      (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>}
                            )
                        )
                      )
                    }
                  ]
                  redirects: [
                    (redir
                      op: <Id.Redir_Great '>'>
                      loc: (redir_loc.Fd fd:1)
                      arg: {($ Id.VSub_DollarName '$actual')}
                    )
                  ]
                  do_fork: T
                )
                (command.Simple
                  words: [{<printf>} {(DQ <'%s'>)} {(DQ ($ Id.VSub_Number '$1'))}]
                  redirects: [
                    (redir
                      op: <Id.Redir_Great '>'>
                      loc: (redir_loc.Fd fd:1)
                      arg: {($ Id.VSub_DollarName '$expect')}
                    )
                  ]
                  do_fork: T
                )
                (C {<test_i18ncmp>} {($ Id.VSub_DollarName '$expect')} 
                  {($ Id.VSub_DollarName '$actual')}
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: check_summary_oneline
      body: 
        (BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp]
              children: [
                (C {<test_tick>})
                (command.Pipeline
                  children: [
                    (C {<git>} {<commit>} 
                      {
                        (braced_var_sub
                          token: <Id.VSub_Number 3>
                          suffix_op: 
                            (suffix_op.Unary
                              tok: <Id.VTest_Plus '+'>
                              arg_word: {(DQ ($ Id.VSub_Number '$3'))}
                            )
                        )
                      } {<-m>} {(DQ ($ Id.VSub_Number '$2'))}
                    )
                    (command.Simple
                      words: [{<head>} {<-1>}]
                      redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<act>})]
                      do_fork: T
                    )
                  ]
                  negated: F
                )
                (command.ShAssignment
                  pairs: [
                    (assign_pair
                      lhs: (sh_lhs_expr.Name name:SUMMARY_PREFIX)
                      op: assign_op.Equal
                      rhs: 
                        {
                          (DQ 
                            (command_sub
                              left_token: <Id.Left_DollarParen '$('>
                              child: (C {<git>} {<name-rev>} {<--name-only>} {<HEAD>})
                            )
                          )
                        }
                      spids: [139]
                    )
                  ]
                )
                (command.If
                  arms: [
                    (if_arm
                      cond: 
                        (condition.Shell
                          commands: [(C {<test>} {<-n>} {(DQ ($ Id.VSub_Number '$1'))})]
                        )
                      action: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:SUMMARY_PREFIX)
                              op: assign_op.Equal
                              rhs: 
                                {
                                  (DQ ($ Id.VSub_DollarName '$SUMMARY_PREFIX') <' ('> 
                                    ($ Id.VSub_Number '$1') <')'>
                                  )
                                }
                              spids: [174]
                            )
                          ]
                        )
                      ]
                      spids: [160 171]
                    )
                  ]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:SUMMARY_POSTFIX)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (DQ 
                        (command_sub
                          left_token: <Id.Left_DollarParen '$('>
                          child: 
                            (C {<git>} {<log>} {<-1>} {<--pretty> <Id.Lit_Equals '='> (SQ <'format:%h'>)})
                        )
                      )
                    }
                  spids: [191]
                )
              ]
            )
            (command.AndOr
              ops: [Id.Op_DAmp]
              children: [
                (command.Simple
                  words: [
                    {<echo>}
                    {
                      (DQ <'['> ($ Id.VSub_DollarName '$SUMMARY_PREFIX') <' '> 
                        ($ Id.VSub_DollarName '$SUMMARY_POSTFIX') <'] '> ($ Id.VSub_Number '$2')
                      )
                    }
                  ]
                  redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<exp>})]
                  do_fork: T
                )
                (C {<test_i18ncmp>} {<exp>} {<act>})
              ]
            )
          ]
        )
    )
    (C {<test_expect_success>} {(SQ <'output summary format'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo new >file1 &&\n'> <'\tgit add file1 &&\n'> 
          <'\tcheck_summary_oneline "root-commit" "initial" &&\n'> <'\n'> <'\techo change >>file1 &&\n'> <'\tgit add file1\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'output summary format: root-commit'>)} 
      {(SQ <'\n'> <'\tcheck_summary_oneline "" "a change"\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'output summary format for commit with an empty diff'>)} 
      {(SQ <'\n'> <'\n'> <'\tcheck_summary_oneline "" "empty" "--allow-empty"\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'output summary format for merges'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tgit checkout -b recursive-base &&\n'> <'\ttest_commit base file1 &&\n'> 
          <'\n'> <'\tgit checkout -b recursive-a recursive-base &&\n'> <'\ttest_commit commit-a file1 &&\n'> <'\n'> 
          <'\tgit checkout -b recursive-b recursive-base &&\n'> <'\ttest_commit commit-b file1 &&\n'> <'\n'> <'\t# conflict\n'> <'\tgit checkout recursive-a &&\n'> 
          <'\ttest_must_fail git merge recursive-b &&\n'> <'\t# resolve the conflict\n'> <'\techo commit-a > file1 &&\n'> <'\tgit add file1 &&\n'> 
          <'\tcheck_summary_oneline "" "Merge"\n'>
        )
      }
    )
    (command.ShFunction
      name: output_tests_cleanup
      body: 
        (BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp]
              children: [
                (C {<git>} {<checkout>} {<master>})
                (C {<git>} {<rm>} {<file1>})
                (C {<git>} {<commit>} {<-m>} {(DQ <cleanup>)})
              ]
            )
          ]
        )
    )
    (C {<test_expect_success>} {(SQ <'the basics'>)} 
      {
        (SQ <'\n'> <'\n'> <'\toutput_tests_cleanup &&\n'> <'\n'> 
          <'\techo doing partial >"commit is" &&\n'> <'\tmkdir not &&\n'> <'\techo very much encouraged but we should >not/forbid &&\n'> 
          <'\tgit add "commit is" not &&\n'> <'\techo update added "commit is" file >"commit is" &&\n'> 
          <'\techo also update another >not/forbid &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -a -m "initial with -a" &&\n'> <'\n'> 
          <'\tgit cat-file blob HEAD:"commit is" >current.1 &&\n'> <'\tgit cat-file blob HEAD:not/forbid >current.2 &&\n'> <'\n'> <'\tcmp current.1 "commit is" &&\n'> 
          <'\tcmp current.2 not/forbid\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <partial>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo another >"commit is" &&\n'> <'\techo another >not/forbid &&\n'> 
          <'\ttest_tick &&\n'> <'\tgit commit -m "partial commit to handle a file" "commit is" &&\n'> <'\n'> 
          <'\tchanged=$(git diff-tree --name-only HEAD^ HEAD) &&\n'> <'\ttest "$changed" = "commit is"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'partial modification in a subdirectory'>)} 
      {
        (SQ <'\n'> <'\n'> <'\ttest_tick &&\n'> 
          <'\tgit commit -m "partial commit to subdirectory" not &&\n'> <'\n'> <'\tchanged=$(git diff-tree -r --name-only HEAD^ HEAD) &&\n'> 
          <'\ttest "$changed" = "not/forbid"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'partial removal'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tgit rm not/forbid &&\n'> 
          <'\tgit commit -m "partial commit to remove not/forbid" not &&\n'> <'\n'> <'\tchanged=$(git diff-tree -r --name-only HEAD^ HEAD) &&\n'> 
          <'\ttest "$changed" = "not/forbid" &&\n'> <'\tremain=$(git ls-tree -r --name-only HEAD) &&\n'> <'\ttest "$remain" = "commit is"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'sign off'>)} 
      {
        (SQ <'\n'> <'\n'> <'\t>positive &&\n'> <'\tgit add positive &&\n'> 
          <'\tgit commit -s -m "thank you" &&\n'> <'\tactual=$(git cat-file commit HEAD | sed -ne "s/Signed-off-by: //p") &&\n'> 
          <'\texpected=$(git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/") &&\n'> <'\ttest "z$actual" = "z$expected"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'multiple -m'>)} 
      {
        (SQ <'\n'> <'\n'> <'\t>negative &&\n'> <'\tgit add negative &&\n'> 
          <'\tgit commit -m "one" -m "two" -m "three" &&\n'> <'\tactual=$(git cat-file commit HEAD | sed -e "1,/^\\$/d") &&\n'> 
          <'\texpected=$(echo one; echo; echo two; echo; echo three) &&\n'> <'\ttest "z$actual" = "z$expected"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <verbose>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo minus >negative &&\n'> <'\tgit add negative &&\n'> 
          <'\tgit status -v | sed -ne "/^diff --git /p" >actual &&\n'> <'\techo "diff --git a/negative b/negative" >expect &&\n'> <'\ttest_cmp expect actual\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'verbose respects diff config'>)} 
      {
        (SQ <'\n'> <'\n'> <'\ttest_config color.diff always &&\n'> <'\tgit status -v >actual &&\n'> 
          <'\tgrep "\\[1mdiff --git" actual\n'>
        )
      }
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:mesg_with_comment_and_newlines)
          op: assign_op.Equal
          rhs: {(SQ <'\n'> <'# text\n'> <'\n'>)}
          spids: [512]
        )
      ]
    )
    (C {<test_expect_success>} {(SQ <'prepare file with comment line and trailing newlines'>)} 
      {(SQ <'\n'> <'\tprintf "%s" "$mesg_with_comment_and_newlines" >expect\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit messages (verbatim option,-t)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo >>negative &&\n'> 
          <'\tgit commit --cleanup=verbatim --no-status -t expect -a &&\n'> <'\tgit cat-file -p HEAD |sed -e "1,/^\\$/d" >actual &&\n'> <'\ttest_cmp expect actual\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit messages (verbatim option,-F)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo >>negative &&\n'> 
          <'\tgit commit --cleanup=verbatim -F expect -a &&\n'> <'\tgit cat-file -p HEAD |sed -e "1,/^\\$/d">actual &&\n'> <'\ttest_cmp expect actual\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit messages (verbatim option,-m)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo >>negative &&\n'> 
          <'\tgit commit --cleanup=verbatim -m "$mesg_with_comment_and_newlines" -a &&\n'> <'\tgit cat-file -p HEAD |sed -e "1,/^\\$/d">actual &&\n'> <'\ttest_cmp expect actual\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit messages (whitespace option,-F)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo >>negative &&\n'> <'\t{ echo;echo "# text";echo; } >text &&\n'> 
          <'\techo "# text" >expect &&\n'> <'\tgit commit --cleanup=whitespace -F text -a &&\n'> 
          <'\tgit cat-file -p HEAD |sed -e "1,/^\\$/d">actual &&\n'> <'\ttest_cmp expect actual\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit messages (scissors option,-F,-e)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo >>negative &&\n'> <'\tcat >text <<EOF &&\n'> <'\n'> <'# to be kept\n'> 
          <'\n'> <'  # ------------------------ >8 ------------------------\n'> <'# to be kept, too\n'> 
          <'# ------------------------ >8 ------------------------\n'> <'to be removed\n'> <'# ------------------------ >8 ------------------------\n'> 
          <'to be removed, too\n'> <'EOF\n'> <'\n'> <'\tcat >expect <<EOF &&\n'> <'# to be kept\n'> <'\n'> 
          <'  # ------------------------ >8 ------------------------\n'> <'# to be kept, too\n'> <'EOF\n'> <'\tgit commit --cleanup=scissors -e -F text -a &&\n'> 
          <'\tgit cat-file -p HEAD |sed -e "1,/^\\$/d">actual &&\n'> <'\ttest_cmp expect actual\n'>
        )
      }
    )
    (C {<test_expect_success>} 
      {(SQ <'cleanup commit messages (scissors option,-F,-e, scissors on first line)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo >>negative &&\n'> <'\tcat >text <<EOF &&\n'> 
          <'# ------------------------ >8 ------------------------\n'> <'to be removed\n'> <'EOF\n'> 
          <'\tgit commit --cleanup=scissors -e -F text -a --allow-empty-message &&\n'> <'\tgit cat-file -p HEAD |sed -e "1,/^\\$/d">actual &&\n'> <'\ttest_must_be_empty actual\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit messages (strip option,-F)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo >>negative &&\n'> 
          <'\t{ echo;echo "# text";echo sample;echo; } >text &&\n'> <'\techo sample >expect &&\n'> <'\tgit commit --cleanup=strip -F text -a &&\n'> 
          <'\tgit cat-file -p HEAD |sed -e "1,/^\\$/d">actual &&\n'> <'\ttest_cmp expect actual\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit messages (strip option,-F,-e)'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo >>negative &&\n'> <'\t{ echo;echo sample;echo; } >text &&\n'> 
          <'\tgit commit -e -F text -a &&\n'> <'\thead -n 4 .git/COMMIT_EDITMSG >actual\n'>
        )
      }
    )
    (command.Simple
      words: [
        {<echo>}
        {
          (DQ <'sample\n'> <'\n'> 
            <'# Please enter the commit message for your changes. Lines starting\n'> <'# with \'#\' will be ignored, and an empty message aborts the commit.'>
          )
        }
      ]
      redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<expect>})]
      do_fork: T
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit messages (strip option,-F,-e): output'>)} 
      {(SQ <'\n'> <'\ttest_i18ncmp expect actual\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit message (fail on invalid cleanup mode option)'>)} 
      {(SQ <'\n'> <'\ttest_must_fail git commit --cleanup=non-existent\n'>)}
    )
    (C {<test_expect_success>} 
      {(SQ <'cleanup commit message (fail on invalid cleanup mode configuration)'>)} {(SQ <'\n'> <'\ttest_must_fail git -c commit.cleanup=non-existent commit\n'>)}
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit message (no config and no option uses default)'>)} 
      {
        (SQ <'\n'> <'\techo content >>file &&\n'> <'\tgit add file &&\n'> <'\t(\n'> 
          <'\t  test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&\n'> <'\t  git commit --no-status\n'> <'\t) &&\n'> <'\tcommit_msg_is "commit message"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit message (option overrides default)'>)} 
      {
        (SQ <'\n'> <'\techo content >>file &&\n'> <'\tgit add file &&\n'> <'\t(\n'> 
          <'\t  test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&\n'> <'\t  git commit --cleanup=whitespace --no-status\n'> <'\t) &&\n'> 
          <'\tcommit_msg_is "commit message # comment"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit message (config overrides default)'>)} 
      {
        (SQ <'\n'> <'\techo content >>file &&\n'> <'\tgit add file &&\n'> <'\t(\n'> 
          <'\t  test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&\n'> <'\t  git -c commit.cleanup=whitespace commit --no-status\n'> <'\t) &&\n'> 
          <'\tcommit_msg_is "commit message # comment"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit message (option overrides config)'>)} 
      {
        (SQ <'\n'> <'\techo content >>file &&\n'> <'\tgit add file &&\n'> <'\t(\n'> 
          <'\t  test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&\n'> <'\t  git -c commit.cleanup=whitespace commit --cleanup=default\n'> <'\t) &&\n'> 
          <'\tcommit_msg_is "commit message"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit message (default, -m)'>)} 
      {
        (SQ <'\n'> <'\techo content >>file &&\n'> <'\tgit add file &&\n'> 
          <'\tgit commit -m "message #comment " &&\n'> <'\tcommit_msg_is "message #comment"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit message (whitespace option, -m)'>)} 
      {
        (SQ <'\n'> <'\techo content >>file &&\n'> <'\tgit add file &&\n'> 
          <'\tgit commit --cleanup=whitespace --no-status -m "message #comment " &&\n'> <'\tcommit_msg_is "message #comment"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cleanup commit message (whitespace config, -m)'>)} 
      {
        (SQ <'\n'> <'\techo content >>file &&\n'> <'\tgit add file &&\n'> 
          <'\tgit -c commit.cleanup=whitespace commit --no-status -m "message #comment " &&\n'> <'\tcommit_msg_is "message #comment"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'message shows author when it is not equal to committer'>)} 
      {
        (SQ <'\n'> <'\techo >>negative &&\n'> <'\tgit commit -e -m "sample" -a &&\n'> 
          <'\ttest_i18ngrep \\\n'> <'\t  "^# Author: *A U Thor <author@example.com>\\$" \\\n'> <'\t  .git/COMMIT_EDITMSG\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'message shows date when it is explicitly set'>)} 
      {
        (SQ <'\n'> <'\tgit commit --allow-empty -e -m foo --date="2010-01-02T03:04:05" &&\n'> 
          <'\ttest_i18ngrep \\\n'> <'\t  "^# Date: *Sat Jan 2 03:04:05 2010 +0000" \\\n'> <'\t  .git/COMMIT_EDITMSG\n'>
        )
      }
    )
    (C {<test_expect_success>} {<AUTOIDENT>} {(SQ <'message shows committer when it is automatic'>)} 
      {
        (SQ <'\n'> <'\n'> <'\techo >>negative &&\n'> <'\t(\n'> 
          <'\t\tsane_unset GIT_COMMITTER_EMAIL &&\n'> <'\t\tsane_unset GIT_COMMITTER_NAME &&\n'> <'\t\tgit commit -e -m "sample" -a\n'> <'\t) &&\n'> 
          <'\t# the ident is calculated from the system, so we cannot\n'> <'\t# check the actual value, only that it is there\n'> 
          <'\ttest_i18ngrep "^# Committer: " .git/COMMIT_EDITMSG\n'>
        )
      }
    )
    (command.Simple
      words: [{<write_script>} {<'.git/FAKE_EDITOR'>}]
      redirects: [
        (redir
          op: <Id.Redir_DLess '<<'>
          loc: (redir_loc.Fd fd:0)
          arg: 
            (redir_param.HereDoc
              here_begin: {<EOF>}
              here_end_span_id: 928
              stdin_parts: [
                <'echo editor started > '>
                <Id.Right_DoubleQuote '"'>
                (command_sub left_token:<Id.Left_DollarParen '$('> child:(C {<pwd>}))
                <'/.git/result'>
                <Id.Right_DoubleQuote '"'>
                <'\n'>
                <'exit 0\n'>
              ]
            )
        )
      ]
      do_fork: T
    )
    (C {<test_expect_success>} {<Id.KW_Bang '!'> <AUTOIDENT>} 
      {(SQ <'do not fire editor when committer is bogus'>)} 
      {
        (SQ <'\n'> <'\t>.git/result &&\n'> <'\t>expect &&\n'> <'\n'> <'\techo >>negative &&\n'> <'\t(\n'> 
          <'\t\tsane_unset GIT_COMMITTER_EMAIL &&\n'> <'\t\tsane_unset GIT_COMMITTER_NAME &&\n'> <'\t\tGIT_EDITOR="\\"$(pwd)/.git/FAKE_EDITOR\\"" &&\n'> 
          <'\t\texport GIT_EDITOR &&\n'> <'\t\ttest_must_fail git commit -e -m sample -a\n'> <'\t) &&\n'> <'\ttest_cmp expect .git/result\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'do not fire editor if -m <msg> was given'>)} 
      {
        (SQ <'\n'> <'\techo tick >file &&\n'> <'\tgit add file &&\n'> 
          <'\techo "editor not started" >.git/result &&\n'> <'\t(GIT_EDITOR="\\"$(pwd)/.git/FAKE_EDITOR\\"" git commit -m tick) &&\n'> 
          <'\ttest "$(cat .git/result)" = "editor not started"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'do not fire editor if -m "" was given'>)} 
      {
        (SQ <'\n'> <'\techo tock >file &&\n'> <'\tgit add file &&\n'> 
          <'\techo "editor not started" >.git/result &&\n'> <'\t(GIT_EDITOR="\\"$(pwd)/.git/FAKE_EDITOR\\"" \\\n'> 
          <'\t git commit -m "" --allow-empty-message) &&\n'> <'\ttest "$(cat .git/result)" = "editor not started"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'do not fire editor in the presence of conflicts'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tgit clean -f &&\n'> <'\techo f >g &&\n'> <'\tgit add g &&\n'> 
          <'\tgit commit -m "add g" &&\n'> <'\tgit branch second &&\n'> <'\techo master >g &&\n'> <'\techo g >h &&\n'> <'\tgit add g h &&\n'> 
          <'\tgit commit -m "modify g and add h" &&\n'> <'\tgit checkout second &&\n'> <'\techo second >g &&\n'> <'\tgit add g &&\n'> 
          <'\tgit commit -m second &&\n'> <'\t# Must fail due to conflict\n'> <'\ttest_must_fail git cherry-pick -n master &&\n'> 
          <'\techo "editor not started" >.git/result &&\n'> <'\t(\n'> <'\t\tGIT_EDITOR="\\"$(pwd)/.git/FAKE_EDITOR\\"" &&\n'> <'\t\texport GIT_EDITOR &&\n'> 
          <'\t\ttest_must_fail git commit\n'> <'\t) &&\n'> <'\ttest "$(cat .git/result)" = "editor not started"\n'>
        )
      }
    )
    (command.Simple
      words: [{<write_script>} {<'.git/FAKE_EDITOR'>}]
      redirects: [
        (redir
          op: <Id.Redir_DLess '<<'>
          loc: (redir_loc.Fd fd:0)
          arg: 
            (redir_param.HereDoc
              here_begin: {<EOF>}
              here_end_span_id: 1032
              stdin_parts: [<'# kill -TERM command added below.\n'>]
            )
        )
      ]
      do_fork: T
    )
    (C {<test_expect_success>} {<EXECKEEPSPID>} {(SQ <'a SIGTERM should break locks'>)} 
      {(SQ <'\n'> <'\techo >>negative &&\n'> <'\t! "$SHELL_PATH" -c '>) 
        (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) 
        (SQ <'\n'> <'\t  echo kill -TERM $$ >> .git/FAKE_EDITOR\n'> 
          <'\t  GIT_EDITOR=.git/FAKE_EDITOR\n'> <'\t  export GIT_EDITOR\n'> <'\t  exec git commit -a'>
        ) (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\\''>) 
        (SQ <' &&\n'> <'\ttest ! -f .git/index.lock\n'>)
      }
    )
    (C {<rm>} {<-f>} {<'.git/MERGE_MSG'>} {<'.git/COMMIT_EDITMSG'>})
    (C {<git>} {<reset>} {<-q>} {<--hard>})
    (C {<test_expect_success>} {(SQ <'Hand committing of a redundant merge removes dups'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tgit rev-parse second master >expect &&\n'> 
          <'\ttest_must_fail git merge second master &&\n'> <'\tgit checkout master g &&\n'> <'\tEDITOR=: git commit -a &&\n'> 
          <'\tgit cat-file commit HEAD | sed -n -e "s/^parent //p" -e "/^$/q" >actual &&\n'> <'\ttest_cmp expect actual\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'A single-liner subject with a token plus colon is not a footer'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tgit reset --hard &&\n'> 
          <'\tgit commit -s -m "hello: kitty" --allow-empty &&\n'> <'\tgit cat-file commit HEAD | sed -e "1,/^$/d" >actual &&\n'> <'\ttest_line_count = 3 actual\n'> 
          <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'commit -s places sob on third line after two empty lines'>)} 
      {
        (SQ <'\n'> <'\tgit commit -s --allow-empty --allow-empty-message &&\n'> 
          <'\tcat <<-EOF >expect &&\n'> <'\n'> <'\n'> <'\tSigned-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>\n'> <'\n'> <'\tEOF\n'> 
          <'\tsed -e "/^#/d" -e "s/^:.*//" .git/COMMIT_EDITMSG >actual &&\n'> <'\ttest_cmp expect actual\n'>
        )
      }
    )
    (command.Simple
      words: [{<write_script>} {<'.git/FAKE_EDITOR'>}]
      redirects: [
        (redir
          op: <Id.Redir_DLess '<<'>
          loc: (redir_loc.Fd fd:0)
          arg: 
            (redir_param.HereDoc
              here_begin: {(word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\E'>) <OF>}
              here_end_span_id: 1148
              stdin_parts: [
                <'mv "$1" "$1.orig"\n'>
                <'(\n'>
                <'\techo message\n'>
                <'\tcat "$1.orig"\n'>
                <') >"$1"\n'>
              ]
            )
        )
      ]
      do_fork: T
    )
    (command.Simple
      words: [{<echo>} {(SQ <'## Custom template'>)}]
      redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<template>})]
      do_fork: T
    )
    (command.ShFunction
      name: try_commit
      body: 
        (BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp]
              children: [
                (C {<git>} {<reset>} {<--hard>})
                (command.Simple
                  words: [{<echo>}]
                  redirects: [
                    (redir
                      op: <Id.Redir_DGreat '>>'>
                      loc: (redir_loc.Fd fd:1)
                      arg: {<negative>}
                    )
                  ]
                  do_fork: T
                )
                (command.Simple
                  words: [
                    {<git>}
                    {<commit>}
                    {<-a>}
                    {($ Id.VSub_Star '$*')}
                    {($ Id.VSub_DollarName '$use_template')}
                  ]
                  more_env: [(env_pair name:GIT_EDITOR val:{<'.git/FAKE_EDITOR'>} spids:[1185])]
                  do_fork: T
                )
                (command.Case
                  to_match: {(DQ ($ Id.VSub_DollarName '$use_template'))}
                  arms: [
                    (case_arm
                      pat_list: [{(SQ )}]
                      action: [
                        (C {<test_i18ngrep>} {<Id.KW_Bang '!'>} {(DQ <'^## Custom template'>)} 
                          {<'.git/COMMIT_EDITMSG'>}
                        )
                      ]
                      spids: [1210 1212 1225 -1]
                    )
                    (case_arm
                      pat_list: [{<Id.Lit_Star '*'>}]
                      action: [
                        (C {<test_i18ngrep>} {(DQ <'^## Custom template'>)} {<'.git/COMMIT_EDITMSG'>})
                      ]
                      spids: [1228 1229 1240 -1]
                    )
                  ]
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: try_commit_status_combo
      body: 
        (BraceGroup
          children: [
            (C {<test_expect_success>} {(SQ <commit>)} 
              {
                (SQ <'\n'> <'\t\ttry_commit "" &&\n'> 
                  <'\t\ttest_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG\n'> <'\t'>
                )
              }
            )
            (C {<test_expect_success>} {(SQ <'commit --status'>)} 
              {
                (SQ <'\n'> <'\t\ttry_commit --status &&\n'> 
                  <'\t\ttest_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG\n'> <'\t'>
                )
              }
            )
            (C {<test_expect_success>} {(SQ <'commit --no-status'>)} 
              {
                (SQ <'\n'> <'\t\ttry_commit --no-status &&\n'> 
                  <'\t\ttest_i18ngrep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG\n'> <'\t'>
                )
              }
            )
            (C {<test_expect_success>} {(SQ <'commit with commit.status = yes'>)} 
              {
                (SQ <'\n'> <'\t\ttest_config commit.status yes &&\n'> <'\t\ttry_commit "" &&\n'> 
                  <'\t\ttest_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG\n'> <'\t'>
                )
              }
            )
            (C {<test_expect_success>} {(SQ <'commit with commit.status = no'>)} 
              {
                (SQ <'\n'> <'\t\ttest_config commit.status no &&\n'> <'\t\ttry_commit "" &&\n'> 
                  <'\t\ttest_i18ngrep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG\n'> <'\t'>
                )
              }
            )
            (C {<test_expect_success>} {(SQ <'commit --status with commit.status = yes'>)} 
              {
                (SQ <'\n'> <'\t\ttest_config commit.status yes &&\n'> <'\t\ttry_commit --status &&\n'> 
                  <'\t\ttest_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG\n'> <'\t'>
                )
              }
            )
            (C {<test_expect_success>} {(SQ <'commit --no-status with commit.status = yes'>)} 
              {
                (SQ <'\n'> <'\t\ttest_config commit.status yes &&\n'> 
                  <'\t\ttry_commit --no-status &&\n'> <'\t\ttest_i18ngrep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG\n'> <'\t'>
                )
              }
            )
            (C {<test_expect_success>} {(SQ <'commit --status with commit.status = no'>)} 
              {
                (SQ <'\n'> <'\t\ttest_config commit.status no &&\n'> <'\t\ttry_commit --status &&\n'> 
                  <'\t\ttest_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG\n'> <'\t'>
                )
              }
            )
            (C {<test_expect_success>} {(SQ <'commit --no-status with commit.status = no'>)} 
              {
                (SQ <'\n'> <'\t\ttest_config commit.status no &&\n'> 
                  <'\t\ttry_commit --no-status &&\n'> <'\t\ttest_i18ngrep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG\n'> <'\t'>
                )
              }
            )
          ]
        )
    )
    (C {<try_commit_status_combo>})
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:use_template)
          op: assign_op.Equal
          rhs: {(DQ <'-t template'>)}
          spids: [1403]
        )
      ]
    )
    (C {<try_commit_status_combo>})
    (C {<test_expect_success>} {(SQ <'commit --status with custom comment character'>)} 
      {
        (SQ <'\n'> <'\ttest_config core.commentchar ";" &&\n'> <'\ttry_commit --status &&\n'> 
          <'\ttest_i18ngrep "^; Changes to be committed:" .git/COMMIT_EDITMSG\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'switch core.commentchar'>)} 
      {
        (SQ <'\n'> <'\ttest_commit "#foo" foo &&\n'> 
          <'\tGIT_EDITOR=.git/FAKE_EDITOR git -c core.commentChar=auto commit --amend &&\n'> <'\ttest_i18ngrep "^; Changes to be committed:" .git/COMMIT_EDITMSG\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'switch core.commentchar but out of options'>)} 
      {
        (SQ <'\n'> <'\tcat >text <<\\EOF &&\n'> <'# 1\n'> <'; 2\n'> <'@ 3\n'> <'! 4\n'> <'$ 5\n'> <'% 6\n'> 
          <'^ 7\n'> <'& 8\n'> <'| 9\n'> <': 10\n'> <'EOF\n'> <'\tgit commit --amend -F text &&\n'> <'\t(\n'> 
          <'\t\ttest_set_editor .git/FAKE_EDITOR &&\n'> <'\t\ttest_must_fail git -c core.commentChar=auto commit --amend\n'> <'\t)\n'>
        )
      }
    )
    (C {<test_done>})
  ]
)