(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_description)
          op: assign_op.Equal
          rhs: 
            {
              (SQ <'test cherry-pick and revert with conflicts\n'> <'\n'> <'  -\n'> 
                <'  + picked: rewrites foo to c\n'> <'  + base: rewrites foo to b\n'> <'  + initial: writes foo as a, unrelated as unrelated\n'> <'\n'>
              )
            }
          spids: [4]
        )
      ]
    )
    (C {<.>} {<'./test-lib.sh'>})
    (command.ShFunction
      name: pristine_detach
      body: 
        (BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp]
              children: [
                (C {<git>} {<checkout>} {<-f>} {(DQ ($ Id.VSub_Number '$1') <'^0'>)})
                (C {<git>} {<read-tree>} {<-u>} {<--reset>} {<HEAD>})
                (C {<git>} {<clean>} {<-d>} {<-f>} {<-f>} {<-q>} {<-x>})
              ]
            )
          ]
        )
    )
    (C {<test_expect_success>} {<setup>} 
      {
        (SQ <'\n'> <'\n'> <'\techo unrelated >unrelated &&\n'> <'\tgit add unrelated &&\n'> 
          <'\ttest_commit initial foo a &&\n'> <'\ttest_commit base foo b &&\n'> <'\ttest_commit picked foo c &&\n'> 
          <'\ttest_commit --signoff picked-signed foo d &&\n'> <'\tgit config advice.detachedhead false\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'failed cherry-pick does not advance HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\n'> <'\thead=$(git rev-parse HEAD) &&\n'> 
          <'\ttest_must_fail git cherry-pick picked &&\n'> <'\tnewhead=$(git rev-parse HEAD) &&\n'> <'\n'> <'\ttest "$head" = "$newhead"\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'advice from failed cherry-pick'>)} 
      {
        (DQ <'\n'> <'\tpristine_detach initial &&\n'> <'\n'> <'\tpicked='> 
          (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\$'>) <'(git rev-parse --short picked) &&\n'> <'\tcat <<-EOF >expected &&\n'> <'\terror: could not apply '> 
          (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\$'>) <'picked... picked\n'> <'\thint: after resolving the conflicts, mark the corrected paths\n'> 
          <'\thint: with \'git add <paths>\' or \'git rm <paths>\'\n'> <'\thint: and commit the result with \'git commit\'\n'> <'\tEOF\n'> 
          <'\ttest_must_fail git cherry-pick picked 2>actual &&\n'> <'\n'> <'\ttest_i18ncmp expected actual\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'advice from failed cherry-pick --no-commit'>)} 
      {
        (DQ <'\n'> <'\tpristine_detach initial &&\n'> <'\n'> <'\tpicked='> 
          (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\$'>) <'(git rev-parse --short picked) &&\n'> <'\tcat <<-EOF >expected &&\n'> <'\terror: could not apply '> 
          (word_part.EscapedLiteral token:<Id.Lit_EscapedChar '\\$'>) <'picked... picked\n'> <'\thint: after resolving the conflicts, mark the corrected paths\n'> 
          <'\thint: with \'git add <paths>\' or \'git rm <paths>\'\n'> <'\tEOF\n'> <'\ttest_must_fail git cherry-pick --no-commit picked 2>actual &&\n'> <'\n'> 
          <'\ttest_i18ncmp expected actual\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'failed cherry-pick sets CHERRY_PICK_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\ttest_must_fail git cherry-pick picked &&\n'> 
          <'\ttest_cmp_rev picked CHERRY_PICK_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'successful cherry-pick does not set CHERRY_PICK_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tgit cherry-pick base &&\n'> 
          <'\ttest_must_fail git rev-parse --verify CHERRY_PICK_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cherry-pick --no-commit does not set CHERRY_PICK_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tgit cherry-pick --no-commit base &&\n'> 
          <'\ttest_must_fail git rev-parse --verify CHERRY_PICK_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\techo foo > foo &&\n'> 
          <'\ttest_must_fail git cherry-pick base &&\n'> <'\ttest_must_fail git rev-parse --verify CHERRY_PICK_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} 
      {(SQ <'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\techo foo > foo &&\n'> 
          <'\ttest_must_fail git cherry-pick --strategy=resolve base &&\n'> <'\ttest_must_fail git rev-parse --verify CHERRY_PICK_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'GIT_CHERRY_PICK_HELP suppresses CHERRY_PICK_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\t(\n'> 
          <'\t\tGIT_CHERRY_PICK_HELP="and then do something else" &&\n'> <'\t\texport GIT_CHERRY_PICK_HELP &&\n'> <'\t\ttest_must_fail git cherry-pick picked\n'> <'\t) &&\n'> 
          <'\ttest_must_fail git rev-parse --verify CHERRY_PICK_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'git reset clears CHERRY_PICK_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\n'> 
          <'\ttest_must_fail git cherry-pick picked &&\n'> <'\tgit reset &&\n'> <'\n'> <'\ttest_must_fail git rev-parse --verify CHERRY_PICK_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'failed commit does not clear CHERRY_PICK_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\n'> 
          <'\ttest_must_fail git cherry-pick picked &&\n'> <'\ttest_must_fail git commit &&\n'> <'\n'> <'\ttest_cmp_rev picked CHERRY_PICK_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'cancelled commit does not clear CHERRY_PICK_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\n'> 
          <'\ttest_must_fail git cherry-pick picked &&\n'> <'\techo resolved >foo &&\n'> <'\tgit add foo &&\n'> <'\tgit update-index --refresh -q &&\n'> 
          <'\ttest_must_fail git diff-index --exit-code HEAD &&\n'> <'\t(\n'> <'\t\tGIT_EDITOR=false &&\n'> <'\t\texport GIT_EDITOR &&\n'> 
          <'\t\ttest_must_fail git commit\n'> <'\t) &&\n'> <'\n'> <'\ttest_cmp_rev picked CHERRY_PICK_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'successful commit clears CHERRY_PICK_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\n'> 
          <'\ttest_must_fail git cherry-pick picked &&\n'> <'\techo resolved >foo &&\n'> <'\tgit add foo &&\n'> <'\tgit commit &&\n'> <'\n'> 
          <'\ttest_must_fail git rev-parse --verify CHERRY_PICK_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'failed cherry-pick produces dirty index'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\n'> 
          <'\ttest_must_fail git cherry-pick picked &&\n'> <'\n'> <'\ttest_must_fail git update-index --refresh -q &&\n'> 
          <'\ttest_must_fail git diff-index --exit-code HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'failed cherry-pick registers participants in index'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\t{\n'> <'\t\tgit checkout base -- foo &&\n'> 
          <'\t\tgit ls-files --stage foo &&\n'> <'\t\tgit checkout initial -- foo &&\n'> <'\t\tgit ls-files --stage foo &&\n'> 
          <'\t\tgit checkout picked -- foo &&\n'> <'\t\tgit ls-files --stage foo\n'> <'\t} > stages &&\n'> <'\tsed "\n'> <'\t\t1 s/ 0\t/ 1\t/\n'> 
          <'\t\t2 s/ 0\t/ 2\t/\n'> <'\t\t3 s/ 0\t/ 3\t/\n'> <'\t" < stages > expected &&\n'> <'\tgit read-tree -u --reset HEAD &&\n'> 
          <'\n'> <'\ttest_must_fail git cherry-pick picked &&\n'> <'\tgit ls-files --stage --unmerged > actual &&\n'> 
          <'\n'> <'\ttest_cmp expected actual\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'failed cherry-pick describes conflict in work tree'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tcat <<-EOF > expected &&\n'> 
          <'\t<<<<<<< HEAD\n'> <'\ta\n'> <'\t=======\n'> <'\tc\n'> <'\t>>>>>>> objid picked\n'> <'\tEOF\n'> <'\n'> 
          <'\ttest_must_fail git cherry-pick picked &&\n'> <'\n'> <'\tsed "s/[a-f0-9]*\\.\\.\\./objid/" foo > actual &&\n'> <'\ttest_cmp expected actual\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'diff3 -m style'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tgit config merge.conflictstyle diff3 &&\n'> 
          <'\tcat <<-EOF > expected &&\n'> <'\t<<<<<<< HEAD\n'> <'\ta\n'> <'\t||||||| parent of objid picked\n'> <'\tb\n'> <'\t=======\n'> <'\tc\n'> 
          <'\t>>>>>>> objid picked\n'> <'\tEOF\n'> <'\n'> <'\ttest_must_fail git cherry-pick picked &&\n'> <'\n'> 
          <'\tsed "s/[a-f0-9]*\\.\\.\\./objid/" foo > actual &&\n'> <'\ttest_cmp expected actual\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'revert also handles conflicts sanely'>)} 
      {
        (SQ <'\n'> <'\tgit config --unset merge.conflictstyle &&\n'> <'\tpristine_detach initial &&\n'> 
          <'\tcat <<-EOF > expected &&\n'> <'\t<<<<<<< HEAD\n'> <'\ta\n'> <'\t=======\n'> <'\tb\n'> <'\t>>>>>>> parent of objid picked\n'> 
          <'\tEOF\n'> <'\t{\n'> <'\t\tgit checkout picked -- foo &&\n'> <'\t\tgit ls-files --stage foo &&\n'> 
          <'\t\tgit checkout initial -- foo &&\n'> <'\t\tgit ls-files --stage foo &&\n'> <'\t\tgit checkout base -- foo &&\n'> 
          <'\t\tgit ls-files --stage foo\n'> <'\t} > stages &&\n'> <'\tsed "\n'> <'\t\t1 s/ 0\t/ 1\t/\n'> <'\t\t2 s/ 0\t/ 2\t/\n'> 
          <'\t\t3 s/ 0\t/ 3\t/\n'> <'\t" < stages > expected-stages &&\n'> <'\tgit read-tree -u --reset HEAD &&\n'> <'\n'> 
          <'\thead=$(git rev-parse HEAD) &&\n'> <'\ttest_must_fail git revert picked &&\n'> <'\tnewhead=$(git rev-parse HEAD) &&\n'> 
          <'\tgit ls-files --stage --unmerged > actual-stages &&\n'> <'\n'> <'\ttest "$head" = "$newhead" &&\n'> <'\ttest_must_fail git update-index --refresh -q &&\n'> 
          <'\ttest_must_fail git diff-index --exit-code HEAD &&\n'> <'\ttest_cmp expected-stages actual-stages &&\n'> 
          <'\tsed "s/[a-f0-9]*\\.\\.\\./objid/" foo > actual &&\n'> <'\ttest_cmp expected actual\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'failed revert sets REVERT_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\ttest_must_fail git revert picked &&\n'> 
          <'\ttest_cmp_rev picked REVERT_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'successful revert does not set REVERT_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach base &&\n'> <'\tgit revert base &&\n'> 
          <'\ttest_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&\n'> <'\ttest_must_fail git rev-parse --verify REVERT_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'revert --no-commit sets REVERT_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach base &&\n'> <'\tgit revert --no-commit base &&\n'> 
          <'\ttest_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&\n'> <'\ttest_cmp_rev base REVERT_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'revert w/dirty tree does not set REVERT_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach base &&\n'> <'\techo foo > foo &&\n'> 
          <'\ttest_must_fail git revert base &&\n'> <'\ttest_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&\n'> 
          <'\ttest_must_fail git rev-parse --verify REVERT_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'GIT_CHERRY_PICK_HELP does not suppress REVERT_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\t(\n'> 
          <'\t\tGIT_CHERRY_PICK_HELP="and then do something else" &&\n'> <'\t\tGIT_REVERT_HELP="and then do something else, again" &&\n'> 
          <'\t\texport GIT_CHERRY_PICK_HELP GIT_REVERT_HELP &&\n'> <'\t\ttest_must_fail git revert picked\n'> <'\t) &&\n'> 
          <'\ttest_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&\n'> <'\ttest_cmp_rev picked REVERT_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'git reset clears REVERT_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\ttest_must_fail git revert picked &&\n'> 
          <'\tgit reset &&\n'> <'\ttest_must_fail git rev-parse --verify REVERT_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'failed commit does not clear REVERT_HEAD'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\ttest_must_fail git revert picked &&\n'> 
          <'\ttest_must_fail git commit &&\n'> <'\ttest_cmp_rev picked REVERT_HEAD\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'revert conflict, diff3 -m style'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\tgit config merge.conflictstyle diff3 &&\n'> 
          <'\tcat <<-EOF > expected &&\n'> <'\t<<<<<<< HEAD\n'> <'\ta\n'> <'\t||||||| objid picked\n'> <'\tc\n'> <'\t=======\n'> <'\tb\n'> 
          <'\t>>>>>>> parent of objid picked\n'> <'\tEOF\n'> <'\n'> <'\ttest_must_fail git revert picked &&\n'> <'\n'> 
          <'\tsed "s/[a-f0-9]*\\.\\.\\./objid/" foo > actual &&\n'> <'\ttest_cmp expected actual\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'failed cherry-pick does not forget -s'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> 
          <'\ttest_must_fail git cherry-pick -s picked &&\n'> <'\ttest_i18ngrep -e "Signed-off-by" .git/MERGE_MSG\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'commit after failed cherry-pick does not add duplicated -s'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> 
          <'\ttest_must_fail git cherry-pick -s picked-signed &&\n'> <'\tgit commit -a -s &&\n'> <'\ttest $(git show -s |grep -c "Signed-off-by") = 1\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'commit after failed cherry-pick adds -s at the right place'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\ttest_must_fail git cherry-pick picked &&\n'> 
          <'\n'> <'\tgit commit -a -s &&\n'> <'\n'> <'\t# Do S-o-b and Conflicts appear in the right order?\n'> 
          <'\tcat <<-\\EOF >expect &&\n'> <'\tSigned-off-by: C O Mitter <committer@example.com>\n'> <'\t# Conflicts:\n'> <'\tEOF\n'> 
          <'\tgrep -e "^# Conflicts:" -e '>
        ) <Id.Lit_Other '^'> <Signed-off-by> 
        (SQ <' <.git/COMMIT_EDITMSG >actual &&\n'> <'\ttest_cmp expect actual &&\n'> <'\n'> 
          <'\tcat <<-\\EOF >expected &&\n'> <'\tpicked\n'> <'\n'> <'\tSigned-off-by: C O Mitter <committer@example.com>\n'> <'\tEOF\n'> <'\n'> 
          <'\tgit show -s --pretty=format:%B >actual &&\n'> <'\ttest_cmp expected actual\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'commit --amend -s places the sign-off at the right place'>)} 
      {
        (SQ <'\n'> <'\tpristine_detach initial &&\n'> <'\ttest_must_fail git cherry-pick picked &&\n'> 
          <'\n'> <'\t# emulate old-style conflicts block\n'> <'\tmv .git/MERGE_MSG .git/MERGE_MSG+ &&\n'> 
          <'\tsed -e "/^# Conflicts:/,\\$s/^# *//" <.git/MERGE_MSG+ >.git/MERGE_MSG &&\n'> <'\n'> <'\tgit commit -a &&\n'> <'\tgit commit --amend -s &&\n'> <'\n'> 
          <'\t# Do S-o-b and Conflicts appear in the right order?\n'> <'\tcat <<-\\EOF >expect &&\n'> <'\tSigned-off-by: C O Mitter <committer@example.com>\n'> 
          <'\tConflicts:\n'> <'\tEOF\n'> <'\tgrep -e "^Conflicts:" -e '>
        ) <Id.Lit_Other '^'> <Signed-off-by> 
        (SQ <' <.git/COMMIT_EDITMSG >actual &&\n'> <'\ttest_cmp expect actual\n'>)
      }
    )
    (C {<test_done>})
  ]
)