(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>}) ] )