(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name left:<Id.Lit_VarLike 'test_description='> name:test_description)
          op: assign_op.Equal
          rhs: {(SQ <'log --grep/--author/--regexp-ignore-case/-S/-G'>)}
          spids: [4]
        )
      ]
      redirects: []
    )
    (C {<.>} {<'./test-lib.sh'>})
    (command.ShFunction
      name: test_log
      body: 
        (BraceGroup
          left: <Id.Lit_LBrace '{'>
          children: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name left:<Id.Lit_VarLike 'expect='> name:expect)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number 1)}
                  spids: [22]
                )
              ]
              redirects: []
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name left:<Id.Lit_VarLike 'kind='> name:kind)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number 2)}
                  spids: [26]
                )
              ]
              redirects: []
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name left:<Id.Lit_VarLike 'needle='> name:needle)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number 3)}
                  spids: [30]
                )
              ]
              redirects: []
            )
            (C {<shift>} {<3>})
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name left:<Id.Lit_VarLike 'rest='> name:rest)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_At '@')}
                  spids: [39]
                )
              ]
              redirects: []
            )
            (command.Case
              to_match: {($ Id.VSub_DollarName kind)}
              arms: [
                (case_arm
                  pat_list: [{<--> <Id.Lit_Star '*'>}]
                  action: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name left:<Id.Lit_VarLike 'opt='> name:opt)
                          op: assign_op.Equal
                          rhs: 
                            {($ Id.VSub_DollarName kind) <Id.Lit_Equals '='> 
                              ($ Id.VSub_DollarName needle)
                            }
                          spids: [56]
                        )
                      ]
                      redirects: []
                    )
                  ]
                  spids: [51 53 62 -1]
                )
                (case_arm
                  pat_list: [{<Id.Lit_Star '*'>}]
                  action: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name left:<Id.Lit_VarLike 'opt='> name:opt)
                          op: assign_op.Equal
                          rhs: {($ Id.VSub_DollarName kind) ($ Id.VSub_DollarName needle)}
                          spids: [69]
                        )
                      ]
                      redirects: []
                    )
                  ]
                  spids: [65 66 74 -1]
                )
              ]
              redirects: []
            )
            (command.Case
              to_match: {($ Id.VSub_DollarName expect)}
              arms: [
                (case_arm
                  pat_list: [{<expect_nomatch>}]
                  action: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name left:<Id.Lit_VarLike 'match='> name:match)
                          op: assign_op.Equal
                          rhs: {<nomatch>}
                          spids: [91]
                        )
                      ]
                      redirects: []
                    )
                  ]
                  spids: [87 88 95 -1]
                )
                (case_arm
                  pat_list: [{<Id.Lit_Star '*'>}]
                  action: [
                    (command.ShAssignment
                      pairs: [
                        (assign_pair
                          lhs: (sh_lhs_expr.Name left:<Id.Lit_VarLike 'match='> name:match)
                          op: assign_op.Equal
                          rhs: {<match>}
                          spids: [102]
                        )
                      ]
                      redirects: []
                    )
                  ]
                  spids: [98 99 106 -1]
                )
              ]
              redirects: []
            )
            (C {<test_expect_success>} 
              {
                (DQ <'log '> ($ Id.VSub_DollarName kind) 
                  (braced_var_sub
                    left: <Id.Left_DollarBrace '${'>
                    token: <Id.VSub_Name rest>
                    var_name: rest
                    suffix_op: 
                      (suffix_op.Unary
                        op: <Id.VTest_ColonPlus _>
                        arg_word: {<' '> ($ Id.VSub_DollarName rest)}
                      )
                    right: <Id.Right_DollarBrace '}'>
                  ) <' ('> ($ Id.VSub_DollarName match) <')'>
                )
              } 
              {
                (DQ <'\n'> <'\t\tgit log '> ($ Id.VSub_DollarName rest) <' '> ($ Id.VSub_DollarName opt) 
                  <' --format=%H >actual &&\n'> <'\t\ttest_cmp '> ($ Id.VSub_DollarName expect) <' actual\n'> <'\t'>
                )
              }
            )
          ]
          redirects: []
          right: <Id.Lit_RBrace '}'>
        )
    )
    (command.ShFunction
      name: test_log_icase
      body: 
        (BraceGroup
          left: <Id.Lit_LBrace '{'>
          children: [
            (C {<test_log>} {($ Id.VSub_At '@')} {<--regexp-ignore-case>})
            (C {<test_log>} {($ Id.VSub_At '@')} {<-i>})
          ]
          redirects: []
          right: <Id.Lit_RBrace '}'>
        )
    )
    (C {<test_expect_success>} {<setup>} 
      {
        (SQ <'\n'> <'\t>expect_nomatch &&\n'> <'\n'> <'\t>file &&\n'> <'\tgit add file &&\n'> 
          <'\ttest_tick &&\n'> <'\tgit commit -m initial &&\n'> <'\tgit rev-parse --verify HEAD >expect_initial &&\n'> <'\n'> 
          <'\techo Picked >file &&\n'> <'\tgit add file &&\n'> <'\ttest_tick &&\n'> 
          <'\tgit commit --author="Another Person <another@example.com>" -m second &&\n'> <'\tgit rev-parse --verify HEAD >expect_second\n'>
        )
      }
    )
    (C {<test_log>} {<expect_initial>} {<--grep>} {<initial>})
    (C {<test_log>} {<expect_nomatch>} {<--grep>} {<InItial>})
    (C {<test_log_icase>} {<expect_initial>} {<--grep>} {<InItial>})
    (C {<test_log_icase>} {<expect_nomatch>} {<--grep>} {<initail>})
    (C {<test_log>} {<expect_second>} {<--author>} {<Person>})
    (C {<test_log>} {<expect_nomatch>} {<--author>} {<person>})
    (C {<test_log_icase>} {<expect_second>} {<--author>} {<person>})
    (C {<test_log_icase>} {<expect_nomatch>} {<--author>} {<spreon>})
    (C {<test_log>} {<expect_nomatch>} {<-G>} {<picked>})
    (C {<test_log>} {<expect_second>} {<-G>} {<Picked>})
    (C {<test_log_icase>} {<expect_nomatch>} {<-G>} {<pickle>})
    (C {<test_log_icase>} {<expect_second>} {<-G>} {<picked>})
    (C {<test_expect_success>} {(SQ <'log -G --textconv (missing textconv tool)'>)} 
      {
        (SQ <'\n'> <'\techo "* diff=test" >.gitattributes &&\n'> 
          <'\ttest_must_fail git -c diff.test.textconv=missing log -Gfoo &&\n'> <'\trm .gitattributes\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'log -G --no-textconv (missing textconv tool)'>)} 
      {
        (SQ <'\n'> <'\techo "* diff=test" >.gitattributes &&\n'> 
          <'\tgit -c diff.test.textconv=missing log -Gfoo --no-textconv >actual &&\n'> <'\ttest_cmp expect_nomatch actual &&\n'> <'\trm .gitattributes\n'>
        )
      }
    )
    (C {<test_log>} {<expect_nomatch>} {<-S>} {<picked>})
    (C {<test_log>} {<expect_second>} {<-S>} {<Picked>})
    (C {<test_log_icase>} {<expect_second>} {<-S>} {<picked>})
    (C {<test_log_icase>} {<expect_nomatch>} {<-S>} {<pickle>})
    (C {<test_log>} {<expect_nomatch>} {<-S>} {<p.cked>} {<--pickaxe-regex>})
    (C {<test_log>} {<expect_second>} {<-S>} {<P.cked>} {<--pickaxe-regex>})
    (C {<test_log_icase>} {<expect_second>} {<-S>} {<p.cked>} {<--pickaxe-regex>})
    (C {<test_log_icase>} {<expect_nomatch>} {<-S>} {<p.ckle>} {<--pickaxe-regex>})
    (C {<test_expect_success>} {(SQ <'log -S --textconv (missing textconv tool)'>)} 
      {
        (SQ <'\n'> <'\techo "* diff=test" >.gitattributes &&\n'> 
          <'\ttest_must_fail git -c diff.test.textconv=missing log -Sfoo &&\n'> <'\trm .gitattributes\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'log -S --no-textconv (missing textconv tool)'>)} 
      {
        (SQ <'\n'> <'\techo "* diff=test" >.gitattributes &&\n'> 
          <'\tgit -c diff.test.textconv=missing log -Sfoo --no-textconv >actual &&\n'> <'\ttest_cmp expect_nomatch actual &&\n'> <'\trm .gitattributes\n'>
        )
      }
    )
    (C {<test_done>})
  ]
)