(command.CommandList
  children: [
    (command.Assignment
      keyword: Assign_None
      pairs: [
        (assign_pair
          lhs: (lhs_expr.LhsName name:test_description)
          op: Equal
          rhs: {(SQ <'git patch-id'>)}
        )
      ]
    )
    (C {(.)} {(./test-lib.sh)})
    (C {(test_expect_success)} {(SQ <setup>)} 
      {
        (SQ <'\n'> <'\tas="a a a a a a a a" && # eight a\n'> <'\ttest_write_lines $as >foo &&\n'> 
          <'\ttest_write_lines $as >bar &&\n'> <'\tgit add foo bar &&\n'> <'\tgit commit -a -m initial &&\n'> <'\ttest_write_lines $as b >foo &&\n'> 
          <'\ttest_write_lines $as b >bar &&\n'> <'\tgit commit -a -m first &&\n'> <'\tgit checkout -b same master &&\n'> 
          <'\tgit commit --amend -m same-msg &&\n'> <'\tgit checkout -b notsame master &&\n'> <'\techo c >foo &&\n'> <'\techo c >bar &&\n'> 
          <'\tgit commit --amend -a -m notsame-msg &&\n'> <'\ttest_write_lines bar foo >bar-then-foo &&\n'> <'\ttest_write_lines foo bar >foo-then-bar\n'>
        )
      }
    )
    (C {(test_expect_success)} {(SQ <'patch-id output is well-formed'>)} 
      {
        (SQ <'\n'> <'\tgit log -p -1 | git patch-id >output &&\n'> 
          <'\tgrep "^[a-f0-9]\\{40\\} $(git rev-parse HEAD)$" output\n'>
        )
      }
    )
    (command.FuncDef
      name: calc_patch_id
      body: 
        (command.BraceGroup
          children: [
            (command.Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (lhs_expr.LhsName name:patch_name)
                  op: Equal
                  rhs: {(DQ ($ VSub_Number '$1'))}
                )
              ]
            )
            (C {(shift)})
            (command.AndOr
              ops: [Op_DAmp]
              children: [
                (command.Pipeline
                  children: [
                    (C {(git)} {(patch-id)} {(DQ ($ VSub_At '$@'))})
                    (command.SimpleCommand
                      words: [{(sed)} {(DQ ('s/ .*//'))}]
                      redirects: [
                        (redir.Redir
                          op: <Redir_Great '>'>
                          fd: 16777215
                          arg_word: {(patch-id_) (DQ ($ VSub_DollarName '$patch_name'))}
                        )
                      ]
                    )
                  ]
                  negated: F
                )
                (C {(test_line_count)} {(-gt)} {(0)} {(patch-id_) (DQ ($ VSub_DollarName '$patch_name'))})
              ]
            )
          ]
        )
    )
    (command.FuncDef
      name: get_top_diff
      body: 
        (command.BraceGroup
          children: [
            (C {(git)} {(log)} {(-p)} {(-1)} {(DQ ($ VSub_At '$@'))} {(-O)} {(bar-then-foo)} {(--)})
          ]
        )
    )
    (command.FuncDef
      name: get_patch_id
      body: 
        (command.BraceGroup
          children: [
            (command.Pipeline
              children: [
                (C {(get_top_diff)} {(DQ ($ VSub_Number '$1'))})
                (C {(calc_patch_id)} {(DQ ($ VSub_At '$@'))})
              ]
              negated: F
            )
          ]
        )
    )
    (C {(test_expect_success)} {(SQ <'patch-id detects equality'>)} 
      {
        (SQ <'\n'> <'\tget_patch_id master &&\n'> <'\tget_patch_id same &&\n'> 
          <'\ttest_cmp patch-id_master patch-id_same\n'>
        )
      }
    )
    (C {(test_expect_success)} {(SQ <'patch-id detects inequality'>)} 
      {
        (SQ <'\n'> <'\tget_patch_id master &&\n'> <'\tget_patch_id notsame &&\n'> 
          <'\t! test_cmp patch-id_master patch-id_notsame\n'>
        )
      }
    )
    (C {(test_expect_success)} {(SQ <'patch-id supports git-format-patch output'>)} 
      {
        (SQ <'\n'> <'\tget_patch_id master &&\n'> <'\tgit checkout same &&\n'> 
          <'\tgit format-patch -1 --stdout | calc_patch_id same &&\n'> <'\ttest_cmp patch-id_master patch-id_same &&\n'> 
          <'\tset $(git format-patch -1 --stdout | git patch-id) &&\n'> <'\ttest "$2" = $(git rev-parse HEAD)\n'>
        )
      }
    )
    (C {(test_expect_success)} {(SQ <'whitespace is irrelevant in footer'>)} 
      {
        (SQ <'\n'> <'\tget_patch_id master &&\n'> <'\tgit checkout same &&\n'> 
          <'\tgit format-patch -1 --stdout | sed "s/ \\$//" | calc_patch_id same &&\n'> <'\ttest_cmp patch-id_master patch-id_same\n'>
        )
      }
    )
    (command.FuncDef
      name: cmp_patch_id
      body: 
        (command.BraceGroup
          children: [
            (command.If
              arms: [
                (if_arm
                  cond: [(C {(test)} {(DQ ($ VSub_Number '$1'))} {(Lit_Other '=')} {(DQ (relevant))})]
                  action: [
                    (command.Pipeline
                      children: [
                        (C {(test_cmp)} {(patch-id_) (DQ ($ VSub_Number '$2'))} 
                          {(patch-id_) (DQ ($ VSub_Number '$3'))}
                        )
                      ]
                      negated: T
                    )
                  ]
                )
              ]
              else_action: [
                (C {(test_cmp)} {(patch-id_) (DQ ($ VSub_Number '$2'))} 
                  {(patch-id_) (DQ ($ VSub_Number '$3'))}
                )
              ]
            )
          ]
        )
    )
    (command.FuncDef
      name: test_patch_id_file_order
      body: 
        (command.BraceGroup
          children: [
            (command.Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (lhs_expr.LhsName name:relevant)
                  op: Equal
                  rhs: {(DQ ($ VSub_Number '$1'))}
                )
              ]
            )
            (C {(shift)})
            (command.Assignment
              keyword: Assign_None
              pairs: [
                (assign_pair
                  lhs: (lhs_expr.LhsName name:name)
                  op: Equal
                  rhs: {(DQ (order-) (${ VSub_Number 1) (-) ($ VSub_DollarName '$relevant'))}
                )
              ]
            )
            (C {(shift)})
            (command.AndOr
              ops: [Op_DAmp Op_DAmp Op_DAmp]
              children: [
                (command.Pipeline
                  children: [
                    (C {(get_top_diff)} {(DQ (master))})
                    (C {(calc_patch_id)} {(DQ ($ VSub_DollarName '$name'))} {(DQ ($ VSub_At '$@'))})
                  ]
                  negated: F
                )
                (C {(git)} {(checkout)} {(same)})
                (command.Pipeline
                  children: [
                    (C {(git)} {(format-patch)} {(-1)} {(--stdout)} {(-O)} {(foo-then-bar)})
                    (C {(calc_patch_id)} {(DQ (ordered-) ($ VSub_DollarName '$name'))} 
                      {(DQ ($ VSub_At '$@'))}
                    )
                  ]
                  negated: F
                )
                (C {(cmp_patch_id)} {($ VSub_DollarName '$relevant')} {(DQ ($ VSub_DollarName '$name'))} 
                  {(DQ (ordered-) ($ VSub_DollarName '$name'))}
                )
              ]
            )
          ]
        )
    )
    (command.FuncDef
      name: test_patch_id
      body: (command.BraceGroup children:[(C {(test_patch_id_file_order)} {(DQ ($ VSub_At '$@'))})])
    )
    (C {(test_expect_success)} {(SQ <'file order is irrelevant with --stable'>)} 
      {(SQ <'\n'> <'\ttest_patch_id_file_order irrelevant --stable --stable\n'>)}
    )
    (C {(test_expect_success)} {(SQ <'file order is relevant with --unstable'>)} 
      {(SQ <'\n'> <'\ttest_patch_id_file_order relevant --unstable --unstable\n'>)}
    )
    (C {(test_expect_success)} {(SQ <'default is unstable'>)} 
      {(SQ <'\n'> <'\ttest_patch_id relevant default\n'>)}
    )
    (C {(test_expect_success)} {(SQ <'patchid.stable = true is stable'>)} 
      {
        (SQ <'\n'> <'\ttest_config patchid.stable true &&\n'> 
          <'\ttest_patch_id irrelevant patchid.stable=true\n'>
        )
      }
    )
    (C {(test_expect_success)} {(SQ <'patchid.stable = false is unstable'>)} 
      {
        (SQ <'\n'> <'\ttest_config patchid.stable false &&\n'> 
          <'\ttest_patch_id relevant patchid.stable=false\n'>
        )
      }
    )
    (C {(test_expect_success)} {(SQ <'--unstable overrides patchid.stable = true'>)} 
      {
        (SQ <'\n'> <'\ttest_config patchid.stable true &&\n'> 
          <'\ttest_patch_id relevant patchid.stable=true--unstable --unstable\n'>
        )
      }
    )
    (C {(test_expect_success)} {(SQ <'--stable overrides patchid.stable = false'>)} 
      {
        (SQ <'\n'> <'\ttest_config patchid.stable false &&\n'> 
          <'\ttest_patch_id irrelevant patchid.stable=false--stable --stable\n'>
        )
      }
    )
    (C {(test_expect_success)} {(SQ <'patch-id supports git-format-patch MIME output'>)} 
      {
        (SQ <'\n'> <'\tget_patch_id master &&\n'> <'\tgit checkout same &&\n'> 
          <'\tgit format-patch -1 --attach --stdout | calc_patch_id same &&\n'> <'\ttest_cmp patch-id_master patch-id_same\n'>
        )
      }
    )
    (C {(test_expect_success)} {(SQ <'patch-id respects config from subdir'>)} 
      {
        (SQ <'\n'> <'\ttest_config patchid.stable true &&\n'> <'\tmkdir subdir &&\n'> <'\n'> 
          <'\t# copy these because test_patch_id() looks for them in\n'> <'\t# the current directory\n'> <'\tcp bar-then-foo foo-then-bar subdir &&\n'> <'\n'> <'\t(\n'> 
          <'\t\tcd subdir &&\n'> <'\t\ttest_patch_id irrelevant patchid.stable=true\n'> <'\t)\n'>
        )
      }
    )
    (command.SimpleCommand
      words: [{(cat)}]
      redirects: [
        (redir.Redir op:<Redir_Great '>'> fd:16777215 arg_word:{(nonl)})
        (redir.HereDoc
          op: <Redir_DLess '<<'>
          fd: 16777215
          here_begin: {(word_part.EscapedLiteralPart token:<Lit_EscapedChar '\\E'>) (OF)}
          here_end_span_id: 575
          stdin_parts: [
            ('diff --git i/a w/a\n')
            ('index e69de29..2e65efe 100644\n')
            ('--- i/a\n')
            ('+++ w/a\n')
            ('@@ -0,0 +1 @@\n')
            ('+a\n')
            ('\\ No newline at end of file\n')
            ('diff --git i/b w/b\n')
            ('index e69de29..6178079 100644\n')
            ('--- i/b\n')
            ('+++ w/b\n')
            ('@@ -0,0 +1 @@\n')
            ('+b\n')
          ]
        )
      ]
    )
    (command.SimpleCommand
      words: [{(cat)}]
      redirects: [
        (redir.Redir op:<Redir_Great '>'> fd:16777215 arg_word:{(withnl)})
        (redir.HereDoc
          op: <Redir_DLess '<<'>
          fd: 16777215
          here_begin: {(word_part.EscapedLiteralPart token:<Lit_EscapedChar '\\E'>) (OF)}
          here_end_span_id: 598
          stdin_parts: [
            ('diff --git i/a w/a\n')
            ('index e69de29..7898192 100644\n')
            ('--- i/a\n')
            ('+++ w/a\n')
            ('@@ -0,0 +1 @@\n')
            ('+a\n')
            ('diff --git i/b w/b\n')
            ('index e69de29..6178079 100644\n')
            ('--- i/b\n')
            ('+++ w/b\n')
            ('@@ -0,0 +1 @@\n')
            ('+b\n')
          ]
        )
      ]
    )
    (C {(test_expect_success)} {(SQ <'patch-id handles no-nl-at-eof markers'>)} 
      {
        (SQ <'\n'> <'\tcat nonl | calc_patch_id nonl &&\n'> 
          <'\tcat withnl | calc_patch_id withnl &&\n'> <'\ttest_cmp patch-id_nonl patch-id_withnl\n'>
        )
      }
    )
    (C {(test_done)})
  ]
)