(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_description)
          op: assign_op.Equal
          rhs: {(SQ <'git patch-id'>)}
          spids: [4]
        )
      ]
    )
    (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.ShFunction
      name: calc_patch_id
      body: 
        (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
                          op: <Id.Redir_Great '>'>
                          loc: (redir_loc.Fd fd:1)
                          arg: {<patch-id_> (DQ ($ Id.VSub_DollarName '$patch_name'))}
                        )
                      ]
                      do_fork: T
                    )
                  ]
                  negated: F
                )
                (C {<test_line_count>} {<-gt>} {<0>} 
                  {<patch-id_> (DQ ($ Id.VSub_DollarName '$patch_name'))}
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: get_top_diff
      body: 
        (BraceGroup
          children: [
            (C {<git>} {<log>} {<-p>} {<-1>} {(DQ ($ Id.VSub_At '$@'))} {<-O>} {<bar-then-foo>} {<-->})
          ]
        )
    )
    (command.ShFunction
      name: get_patch_id
      body: 
        (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 <'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.ShFunction
      name: cmp_patch_id
      body: 
        (BraceGroup
          children: [
            (command.If
              arms: [
                (if_arm
                  cond: 
                    (condition.Shell
                      commands: [
                        (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: 
        (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: (BraceGroup children:[(C {<test_patch_id_file_order>} {(DQ ($ Id.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.Simple
      words: [{<cat>}]
      redirects: [
        (redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<nonl>})
        (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: 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'>
              ]
            )
        )
      ]
      do_fork: T
    )
    (command.Simple
      words: [{<cat>}]
      redirects: [
        (redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<withnl>})
        (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: 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'>
              ]
            )
        )
      ]
      do_fork: T
    )
    (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>})
  ]
)