(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:'git patch-id' span_id:6))}
          spids: [4]
        )
      ]
    )
    (C {(.)} {(./test-lib.sh)})
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:setup span_id:18))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:22) 
          (Token id:Id.Lit_Chars val:'\tas="a a a a a a a a" && # eight a\n' span_id:23) (Token id:Id.Lit_Chars val:'\ttest_write_lines $as >foo &&\n' span_id:24) 
          (Token id:Id.Lit_Chars val:'\ttest_write_lines $as >bar &&\n' span_id:25) (Token id:Id.Lit_Chars val:'\tgit add foo bar &&\n' span_id:26) 
          (Token id:Id.Lit_Chars val:'\tgit commit -a -m initial &&\n' span_id:27) (Token id:Id.Lit_Chars val:'\ttest_write_lines $as b >foo &&\n' span_id:28) 
          (Token id:Id.Lit_Chars val:'\ttest_write_lines $as b >bar &&\n' span_id:29) (Token id:Id.Lit_Chars val:'\tgit commit -a -m first &&\n' span_id:30) 
          (Token id:Id.Lit_Chars val:'\tgit checkout -b same master &&\n' span_id:31) (Token id:Id.Lit_Chars val:'\tgit commit --amend -m same-msg &&\n' span_id:32) 
          (Token id:Id.Lit_Chars val:'\tgit checkout -b notsame master &&\n' span_id:33) (Token id:Id.Lit_Chars val:'\techo c >foo &&\n' span_id:34) 
          (Token id:Id.Lit_Chars val:'\techo c >bar &&\n' span_id:35) (Token id:Id.Lit_Chars val:'\tgit commit --amend -a -m notsame-msg &&\n' span_id:36) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_write_lines bar foo >bar-then-foo &&\n'
            span_id: 37
          ) (Token id:Id.Lit_Chars val:'\ttest_write_lines foo bar >foo-then-bar\n' span_id:38)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'patch-id output is well-formed' span_id:45))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:49) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit log -p -1 | git patch-id >output &&\n'
            span_id: 50
          ) (Token id:Id.Lit_Chars val:'\tgrep "^[a-f0-9]\\{40\\} $(git rev-parse HEAD)$" output\n' span_id:51)
        )
      }
    )
    (command.ShFunction
      name: calc_patch_id
      body: 
        (command.BraceGroup
          children: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:patch_name)
                  op: assign_op.Equal
                  rhs: {(DQ ($ Id.VSub_Number '$1'))}
                  spids: [66]
                )
              ]
            )
            (C {(shift)})
            (command.AndOr
              ops: [Id.Op_DAmp]
              children: [
                (command.Pipeline
                  children: [
                    (C {(git)} {(patch-id)} {(DQ ($ Id.VSub_At '$@'))})
                    (command.Simple
                      words: [{(sed)} {(DQ ('s/ .*//'))}]
                      redirects: [
                        (redir.Redir
                          op: (Token id:Id.Redir_Great val:'>' span_id:92)
                          fd: -1
                          arg_word: {(patch-id_) (DQ ($ Id.VSub_DollarName '$patch_name'))}
                        )
                      ]
                    )
                  ]
                  negated: F
                )
                (C {(test_line_count)} {(-gt)} {(0)} 
                  {(patch-id_) (DQ ($ Id.VSub_DollarName '$patch_name'))}
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: get_top_diff
      body: 
        (command.BraceGroup
          children: [
            (C {(git)} {(log)} {(-p)} {(-1)} {(DQ ($ Id.VSub_At '$@'))} {(-O)} {(bar-then-foo)} {(--)})
          ]
        )
    )
    (command.ShFunction
      name: get_patch_id
      body: 
        (command.BraceGroup
          children: [
            (command.Pipeline
              children: [
                (C {(get_top_diff)} {(DQ ($ Id.VSub_Number '$1'))})
                (C {(calc_patch_id)} {(DQ ($ Id.VSub_At '$@'))})
              ]
              negated: F
            )
          ]
        )
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'patch-id detects equality' span_id:172))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:176) 
          (Token id:Id.Lit_Chars val:'\tget_patch_id master &&\n' span_id:177) (Token id:Id.Lit_Chars val:'\tget_patch_id same &&\n' span_id:178) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_cmp patch-id_master patch-id_same\n'
            span_id: 179
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'patch-id detects inequality' span_id:186))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:190) 
          (Token id:Id.Lit_Chars val:'\tget_patch_id master &&\n' span_id:191) (Token id:Id.Lit_Chars val:'\tget_patch_id notsame &&\n' span_id:192) 
          (Token
            id: Id.Lit_Chars
            val: '\t! test_cmp patch-id_master patch-id_notsame\n'
            span_id: 193
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'patch-id supports git-format-patch output' span_id:200))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:204) 
          (Token id:Id.Lit_Chars val:'\tget_patch_id master &&\n' span_id:205) (Token id:Id.Lit_Chars val:'\tgit checkout same &&\n' span_id:206) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit format-patch -1 --stdout | calc_patch_id same &&\n'
            span_id: 207
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp patch-id_master patch-id_same &&\n' span_id:208) 
          (Token
            id: Id.Lit_Chars
            val: '\tset $(git format-patch -1 --stdout | git patch-id) &&\n'
            span_id: 209
          ) (Token id:Id.Lit_Chars val:'\ttest "$2" = $(git rev-parse HEAD)\n' span_id:210)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'whitespace is irrelevant in footer' span_id:217))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:221) 
          (Token id:Id.Lit_Chars val:'\tget_patch_id master &&\n' span_id:222) (Token id:Id.Lit_Chars val:'\tgit checkout same &&\n' span_id:223) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit format-patch -1 --stdout | sed "s/ \\$//" | calc_patch_id same &&\n'
            span_id: 224
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp patch-id_master patch-id_same\n' span_id:225)
        )
      }
    )
    (command.ShFunction
      name: cmp_patch_id
      body: 
        (command.BraceGroup
          children: [
            (command.If
              arms: [
                (if_arm
                  cond: [
                    (C {(test)} {(DQ ($ Id.VSub_Number '$1'))} {(Id.Lit_Equals '=')} {(DQ (relevant))})
                  ]
                  action: [
                    (command.Pipeline
                      children: [
                        (C {(test_cmp)} {(patch-id_) (DQ ($ Id.VSub_Number '$2'))} 
                          {(patch-id_) (DQ ($ Id.VSub_Number '$3'))}
                        )
                      ]
                      negated: T
                    )
                  ]
                  spids: [237 253]
                )
              ]
              else_action: [
                (C {(test_cmp)} {(patch-id_) (DQ ($ Id.VSub_Number '$2'))} 
                  {(patch-id_) (DQ ($ Id.VSub_Number '$3'))}
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: test_patch_id_file_order
      body: 
        (command.BraceGroup
          children: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:relevant)
                  op: assign_op.Equal
                  rhs: {(DQ ($ Id.VSub_Number '$1'))}
                  spids: [300]
                )
              ]
            )
            (C {(shift)})
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:name)
                  op: assign_op.Equal
                  rhs: {(DQ (order-) (${ Id.VSub_Number 1) (-) ($ Id.VSub_DollarName '$relevant'))}
                  spids: [309]
                )
              ]
            )
            (C {(shift)})
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp]
              children: [
                (command.Pipeline
                  children: [
                    (C {(get_top_diff)} {(DQ (master))})
                    (C {(calc_patch_id)} {(DQ ($ Id.VSub_DollarName '$name'))} {(DQ ($ Id.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-) ($ Id.VSub_DollarName '$name'))} 
                      {(DQ ($ Id.VSub_At '$@'))}
                    )
                  ]
                  negated: F
                )
                (C {(cmp_patch_id)} {($ Id.VSub_DollarName '$relevant')} 
                  {(DQ ($ Id.VSub_DollarName '$name'))} {(DQ (ordered-) ($ Id.VSub_DollarName '$name'))}
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: test_patch_id
      body: 
        (command.BraceGroup
          children: [(C {(test_patch_id_file_order)} {(DQ ($ Id.VSub_At '$@'))})]
        )
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'file order is irrelevant with --stable' span_id:428))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:432) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_patch_id_file_order irrelevant --stable --stable\n'
            span_id: 433
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'file order is relevant with --unstable' span_id:440))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:444) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_patch_id_file_order relevant --unstable --unstable\n'
            span_id: 445
          )
        )
      }
    )
    (C {(test_expect_success)} {(SQ (Token id:Id.Lit_Chars val:'default is unstable' span_id:455))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:459) 
          (Token id:Id.Lit_Chars val:'\ttest_patch_id relevant default\n' span_id:460)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'patchid.stable = true is stable' span_id:467))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:471) 
          (Token id:Id.Lit_Chars val:'\ttest_config patchid.stable true &&\n' span_id:472) (Token id:Id.Lit_Chars val:'\ttest_patch_id irrelevant patchid.stable=true\n' span_id:473)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'patchid.stable = false is unstable' span_id:480))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:484) 
          (Token id:Id.Lit_Chars val:'\ttest_config patchid.stable false &&\n' span_id:485) (Token id:Id.Lit_Chars val:'\ttest_patch_id relevant patchid.stable=false\n' span_id:486)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'--unstable overrides patchid.stable = true' span_id:493))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:497) 
          (Token id:Id.Lit_Chars val:'\ttest_config patchid.stable true &&\n' span_id:498) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_patch_id relevant patchid.stable=true--unstable --unstable\n'
            span_id: 499
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'--stable overrides patchid.stable = false' span_id:506))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:510) 
          (Token id:Id.Lit_Chars val:'\ttest_config patchid.stable false &&\n' span_id:511) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_patch_id irrelevant patchid.stable=false--stable --stable\n'
            span_id: 512
          )
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'patch-id supports git-format-patch MIME output' span_id:519))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:523) 
          (Token id:Id.Lit_Chars val:'\tget_patch_id master &&\n' span_id:524) (Token id:Id.Lit_Chars val:'\tgit checkout same &&\n' span_id:525) 
          (Token
            id: Id.Lit_Chars
            val: '\tgit format-patch -1 --attach --stdout | calc_patch_id same &&\n'
            span_id: 526
          ) (Token id:Id.Lit_Chars val:'\ttest_cmp patch-id_master patch-id_same\n' span_id:527)
        )
      }
    )
    (C {(test_expect_success)} 
      {(SQ (Token id:Id.Lit_Chars val:'patch-id respects config from subdir' span_id:534))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:538) 
          (Token id:Id.Lit_Chars val:'\ttest_config patchid.stable true &&\n' span_id:539) (Token id:Id.Lit_Chars val:'\tmkdir subdir &&\n' span_id:540) 
          (Token id:Id.Lit_Chars val:'\n' span_id:541) (Token id:Id.Lit_Chars val:'\t# copy these because test_patch_id() looks for them in\n' span_id:542) 
          (Token id:Id.Lit_Chars val:'\t# the current directory\n' span_id:543) (Token id:Id.Lit_Chars val:'\tcp bar-then-foo foo-then-bar subdir &&\n' span_id:544) 
          (Token id:Id.Lit_Chars val:'\n' span_id:545) (Token id:Id.Lit_Chars val:'\t(\n' span_id:546) 
          (Token id:Id.Lit_Chars val:'\t\tcd subdir &&\n' span_id:547) (Token id:Id.Lit_Chars val:'\t\ttest_patch_id irrelevant patchid.stable=true\n' span_id:548) 
          (Token id:Id.Lit_Chars val:'\t)\n' span_id:549)
        )
      }
    )
    (command.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir op:(Token id:Id.Redir_Great val:'>' span_id:555) fd:-1 arg_word:{(nonl)})
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:558)
          fd: -1
          here_begin: 
            {(word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\E' span_id:559)) 
              (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.Simple
      words: [{(cat)}]
      redirects: [
        (redir.Redir
          op: (Token id:Id.Redir_Great val:'>' span_id:579)
          fd: -1
          arg_word: {(withnl)}
        )
        (redir.HereDoc
          op: (Token id:Id.Redir_DLess val:'<<' span_id:582)
          fd: -1
          here_begin: 
            {(word_part.EscapedLiteral token:(Token id:Id.Lit_EscapedChar val:'\\E' span_id:583)) 
              (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 (Token id:Id.Lit_Chars val:'patch-id handles no-nl-at-eof markers' span_id:603))} 
      {
        (SQ (Token id:Id.Lit_Chars val:'\n' span_id:607) 
          (Token id:Id.Lit_Chars val:'\tcat nonl | calc_patch_id nonl &&\n' span_id:608) (Token id:Id.Lit_Chars val:'\tcat withnl | calc_patch_id withnl &&\n' span_id:609) 
          (Token
            id: Id.Lit_Chars
            val: '\ttest_cmp patch-id_nonl patch-id_withnl\n'
            span_id: 610
          )
        )
      }
    )
    (C {(test_done)})
  ]
)