(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_description)
          op: assign_op.Equal
          rhs: {(SQ <'undoing resolution'>)}
          spids: [4]
        )
      ]
    )
    (C {<.>} {<'./test-lib.sh'>})
    (command.ShFunction
      name: check_resolve_undo
      body: 
        (BraceGroup
          children: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:msg)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number '$1')}
                  spids: [23]
                )
              ]
            )
            (C {<shift>})
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp]
              children: [
                (command.WhileUntil
                  keyword: <Id.KW_While while>
                  cond: 
                    (condition.Shell
                      commands: [
                        (command.Case
                          to_match: {($ Id.VSub_Pound '$#')}
                          arms: [
                            (case_arm
                              pat_list: [{<0>}]
                              action: [(command.ControlFlow token:<Id.ControlFlow_Break break>)]
                              spids: [39 40 44 -1]
                            )
                            (case_arm
                              pat_list: [{<1>} {<2>} {<3>}]
                              action: [(C {<die>} {(DQ <'Bug in check-resolve-undo test'>)})]
                              spids: [47 52 60 -1]
                            )
                          ]
                        )
                      ]
                    )
                  body: 
                    (command.DoGroup
                      children: [
                        (command.ShAssignment
                          pairs: [
                            (assign_pair
                              lhs: (sh_lhs_expr.Name name:path)
                              op: assign_op.Equal
                              rhs: {($ Id.VSub_Number '$1')}
                              spids: [69]
                            )
                          ]
                        )
                        (C {<shift>})
                        (command.ForEach
                          iter_names: [stage]
                          iterable: (for_iter.Words words:[{<1>} {<2>} {<3>}])
                          body: 
                            (command.DoGroup
                              children: [
                                (command.ShAssignment
                                  pairs: [
                                    (assign_pair
                                      lhs: (sh_lhs_expr.Name name:sha1)
                                      op: assign_op.Equal
                                      rhs: {($ Id.VSub_Number '$1')}
                                      spids: [92]
                                    )
                                  ]
                                )
                                (C {<shift>})
                                (command.Case
                                  to_match: {(DQ ($ Id.VSub_DollarName '$sha1'))}
                                  arms: [
                                    (case_arm
                                      pat_list: [{(SQ )}]
                                      action: [
                                        (command.ControlFlow
                                          token: <Id.ControlFlow_Continue continue>
                                        )
                                      ]
                                      spids: [108 110 114 -1]
                                    )
                                  ]
                                )
                                (command.ShAssignment
                                  pairs: [
                                    (assign_pair
                                      lhs: (sh_lhs_expr.Name name:sha1)
                                      op: assign_op.Equal
                                      rhs: 
                                        {
                                          (command_sub
                                            left_token: <Id.Left_DollarParen '$('>
                                            child: 
                                              (C {<git>} {<rev-parse>} {<--verify>} 
                                                {(DQ ($ Id.VSub_DollarName '$sha1'))}
                                              )
                                          )
                                        }
                                      spids: [120]
                                    )
                                  ]
                                )
                                (C {<printf>} 
                                  {
                                    (DQ <'100644 %s %s'> <Id.Lit_BadBackslash '\\'> <'t%s'> 
                                      <Id.Lit_BadBackslash '\\'> <n>
                                    )
                                  } {($ Id.VSub_DollarName '$sha1')} {($ Id.VSub_DollarName '$stage')} {($ Id.VSub_DollarName '$path')}
                                )
                              ]
                            )
                        )
                      ]
                    )
                  redirects: [
                    (redir
                      op: <Id.Redir_Great '>'>
                      loc: (redir_loc.Fd fd:1)
                      arg: {(DQ ($ Id.VSub_DollarName '$msg') <.expect>)}
                    )
                  ]
                )
                (command.Simple
                  words: [{<git>} {<ls-files>} {<--resolve-undo>}]
                  redirects: [
                    (redir
                      op: <Id.Redir_Great '>'>
                      loc: (redir_loc.Fd fd:1)
                      arg: {(DQ ($ Id.VSub_DollarName '$msg') <.actual>)}
                    )
                  ]
                  do_fork: T
                )
                (C {<test_cmp>} {(DQ ($ Id.VSub_DollarName '$msg') <.expect>)} 
                  {(DQ ($ Id.VSub_DollarName '$msg') <.actual>)}
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: prime_resolve_undo
      body: 
        (BraceGroup
          children: [
            (command.AndOr
              ops: [
                Id.Op_DAmp
                Id.Op_DAmp
                Id.Op_DAmp
                Id.Op_DAmp
                Id.Op_DAmp
                Id.Op_DAmp
                Id.Op_DAmp
                Id.Op_DAmp
                Id.Op_DAmp
              ]
              children: [
                (C {<git>} {<reset>} {<--hard>})
                (C {<git>} {<checkout>} {<second> <Id.Lit_Other '^'> <0>})
                (C {<test_tick>})
                (C {<test_must_fail>} {<git>} {<merge>} {<third> <Id.Lit_Other '^'> <0>})
                (C {<echo>} {<merge>} {<does>} {<not>} {<leave>} {<anything>})
                (C {<check_resolve_undo>} {<empty>})
                (command.Simple
                  words: [{<echo>} {<different>}]
                  redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<'fi/le'>})]
                  do_fork: T
                )
                (C {<git>} {<add>} {<'fi/le'>})
                (C {<echo>} {<resolving>} {<records>})
                (C {<check_resolve_undo>} {<recorded>} {<'fi/le'>} 
                  {<initial> <Id.Lit_Colon ':'> <'fi/le'>} {<second> <Id.Lit_Colon ':'> <'fi/le'>} {<third> <Id.Lit_Colon ':'> <'fi/le'>}
                )
              ]
            )
          ]
        )
    )
    (C {<test_expect_success>} {<setup>} 
      {
        (SQ <'\n'> <'\tmkdir fi &&\n'> <'\tprintf "a\\0a" >binary &&\n'> <'\tgit add binary &&\n'> 
          <'\ttest_commit initial fi/le first &&\n'> <'\tgit branch side &&\n'> <'\tgit branch another &&\n'> <'\tprintf "a\\0b" >binary &&\n'> 
          <'\tgit add binary &&\n'> <'\ttest_commit second fi/le second &&\n'> <'\tgit checkout side &&\n'> 
          <'\ttest_commit third fi/le third &&\n'> <'\tgit branch add-add &&\n'> <'\tgit checkout another &&\n'> 
          <'\ttest_commit fourth fi/le fourth &&\n'> <'\tgit checkout add-add &&\n'> <'\ttest_commit fifth add-differently &&\n'> 
          <'\tgit checkout master\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'add records switch clears'>)} 
      {
        (SQ <'\n'> <'\tprime_resolve_undo &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m merged &&\n'> 
          <'\techo committing keeps &&\n'> <'\tcheck_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&\n'> 
          <'\tgit checkout second^0 &&\n'> <'\techo switching clears &&\n'> <'\tcheck_resolve_undo cleared\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'rm records reset clears'>)} 
      {
        (SQ <'\n'> <'\tprime_resolve_undo &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m merged &&\n'> 
          <'\techo committing keeps &&\n'> <'\tcheck_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&\n'> <'\n'> 
          <'\techo merge clears upfront &&\n'> <'\ttest_must_fail git merge fourth^0 &&\n'> <'\tcheck_resolve_undo nuked &&\n'> <'\n'> 
          <'\tgit rm -f fi/le &&\n'> <'\techo resolving records &&\n'> 
          <'\tcheck_resolve_undo recorded fi/le initial:fi/le HEAD:fi/le fourth:fi/le &&\n'> <'\n'> <'\tgit reset --hard &&\n'> <'\techo resetting discards &&\n'> 
          <'\tcheck_resolve_undo discarded\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'plumbing clears'>)} 
      {
        (SQ <'\n'> <'\tprime_resolve_undo &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m merged &&\n'> 
          <'\techo committing keeps &&\n'> <'\tcheck_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&\n'> <'\n'> 
          <'\techo plumbing clear &&\n'> <'\tgit update-index --clear-resolve-undo &&\n'> <'\tcheck_resolve_undo cleared\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'add records checkout -m undoes'>)} 
      {
        (SQ <'\n'> <'\tprime_resolve_undo &&\n'> <'\tgit diff HEAD &&\n'> 
          <'\tgit checkout --conflict=merge fi/le &&\n'> <'\techo checkout used the record and removed it &&\n'> <'\tcheck_resolve_undo removed &&\n'> 
          <'\techo the index and the work tree is unmerged again &&\n'> <'\tgit diff >actual &&\n'> <'\tgrep "^++<<<<<<<" actual\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'unmerge with plumbing'>)} 
      {
        (SQ <'\n'> <'\tprime_resolve_undo &&\n'> <'\tgit update-index --unresolve fi/le &&\n'> 
          <'\tgit ls-files -u >actual &&\n'> <'\ttest_line_count = 3 actual\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'rerere and rerere forget'>)} 
      {
        (SQ <'\n'> <'\tmkdir .git/rr-cache &&\n'> <'\tprime_resolve_undo &&\n'> 
          <'\techo record the resolution &&\n'> <'\tgit rerere &&\n'> <'\trerere_id=$(cd .git/rr-cache && echo */postimage) &&\n'> 
          <'\trerere_id=${rerere_id%/postimage} &&\n'> <'\ttest -f .git/rr-cache/$rerere_id/postimage &&\n'> <'\tgit checkout -m fi/le &&\n'> 
          <'\techo resurrect the conflict &&\n'> <'\tgrep "^=======" fi/le &&\n'> <'\techo reresolve the conflict &&\n'> <'\tgit rerere &&\n'> 
          <'\ttest "z$(cat fi/le)" = zdifferent &&\n'> <'\techo register the resolution again &&\n'> <'\tgit add fi/le &&\n'> 
          <'\tcheck_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&\n'> <'\ttest -z "$(git ls-files -u)" &&\n'> <'\tgit rerere forget fi/le &&\n'> 
          <'\t! test -f .git/rr-cache/$rerere_id/postimage &&\n'> <'\ttr "\\0" "\\n" <.git/MERGE_RR >actual &&\n'> <'\techo "$rerere_id\tfi/le" >expect &&\n'> 
          <'\ttest_cmp expect actual\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'rerere and rerere forget (subdirectory)'>)} 
      {
        (SQ <'\n'> <'\trm -fr .git/rr-cache &&\n'> <'\tmkdir .git/rr-cache &&\n'> 
          <'\tprime_resolve_undo &&\n'> <'\techo record the resolution &&\n'> <'\t(cd fi && git rerere) &&\n'> 
          <'\trerere_id=$(cd .git/rr-cache && echo */postimage) &&\n'> <'\trerere_id=${rerere_id%/postimage} &&\n'> <'\ttest -f .git/rr-cache/$rerere_id/postimage &&\n'> 
          <'\t(cd fi && git checkout -m le) &&\n'> <'\techo resurrect the conflict &&\n'> <'\tgrep "^=======" fi/le &&\n'> 
          <'\techo reresolve the conflict &&\n'> <'\t(cd fi && git rerere) &&\n'> <'\ttest "z$(cat fi/le)" = zdifferent &&\n'> 
          <'\techo register the resolution again &&\n'> <'\t(cd fi && git add le) &&\n'> 
          <'\tcheck_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&\n'> <'\ttest -z "$(git ls-files -u)" &&\n'> <'\t(cd fi && git rerere forget le) &&\n'> 
          <'\t! test -f .git/rr-cache/$rerere_id/postimage &&\n'> <'\ttr "\\0" "\\n" <.git/MERGE_RR >actual &&\n'> <'\techo "$rerere_id\tfi/le" >expect &&\n'> 
          <'\ttest_cmp expect actual\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'rerere forget (binary)'>)} 
      {
        (SQ <'\n'> <'\tgit checkout -f side &&\n'> <'\tprintf "a\\0c" >binary &&\n'> 
          <'\tgit commit -a -m binary &&\n'> <'\ttest_must_fail git merge second &&\n'> <'\tgit rerere forget binary\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'rerere forget (add-add conflict)'>)} 
      {
        (SQ <'\n'> <'\tgit checkout -f master &&\n'> <'\techo master >add-differently &&\n'> 
          <'\tgit add add-differently &&\n'> <'\tgit commit -m "add differently" &&\n'> <'\ttest_must_fail git merge fifth &&\n'> 
          <'\tgit rerere forget add-differently 2>actual &&\n'> <'\ttest_i18ngrep "no remembered" actual\n'>
        )
      }
    )
    (C {<test_done>})
  ]
)