(CommandList children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:test_description) op: Equal rhs: {(SQ <"concurrent git svn dcommit">)} spids: [13] ) ] spids: [13] ) (C {(.)} {(./lib-git-svn.sh)}) (C {(test_expect_success)} {(SQ <"setup svn repository">)} { (SQ <"\n"> <"\tsvn_cmd checkout \"$svnrepo\" work.svn &&\n"> <"\t(\n"> <"\t\tcd work.svn &&\n"> <"\t\techo >file && echo > auto_updated_file\n"> <"\t\tsvn_cmd add file auto_updated_file &&\n"> <"\t\tsvn_cmd commit -m \"initial commit\"\n"> <"\t) &&\n"> <"\tsvn_cmd checkout \"$svnrepo\" work-auto-commits.svn\n"> ) } ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:N) op:Equal rhs:{(0)} spids:[43])] spids: [43] ) (FuncDef name: next_N body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:N) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithWord w:{($ VSub_Name "$N")}) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [54 63] ) } spids: [53] ) ] spids: [53] ) ] spids: [50] ) spids: [46 49] ) (FuncDef name: setup_hook body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:hook_type) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [108] ) ] spids: [108] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:skip_revs) op: Equal rhs: {(DQ ($ VSub_Number "$2"))} spids: [117] ) ] spids: [117] ) (AndOr children: [ (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$hook_type"))} {(Lit_Other "=")} {(DQ (pre-commit))} {(Lit_Other "]")} ) (AndOr children: [ (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$hook_type"))} {(Lit_Other "=")} {(DQ (post-commit))} {(Lit_Other "]")} ) (BraceGroup children: [ (Sentence child: (SimpleCommand words: [ {(echo)} {(DQ ("ERROR: invalid argument (") ($ VSub_Name "$hook_type") (")"))} {(DQ ("passed to setup_hook"))} ] redirects: [ (Redir op_id: Redir_GreatAnd fd: -1 arg_word: {(2)} spids: [173] ) ] ) terminator: <Op_Semi ";"> ) (Sentence child: (ControlFlow token:<ControlFlow_Return return> arg_word:{(1)}) terminator: <Op_Semi ";"> ) ] spids: [157] ) ] op_id: Op_DPipe ) ] op_id: Op_DPipe ) (SimpleCommand words: [{(echo)} {(DQ ("cnt=") ($ VSub_Name "$skip_revs"))}] redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(DQ ($ VSub_Name "$hook_type") (-counter))} spids: [193] ) ] ) (C {(rm)} {(-f)} {(DQ ($ VSub_Name "$rawsvnrepo") (/hooks/)) (Lit_Other "*") (-commit)}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:hook) op: Equal rhs: {(DQ ($ VSub_Name "$rawsvnrepo") (/hooks/) ($ VSub_Name "$hook_type"))} spids: [216] ) ] spids: [216] ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(DQ ($ VSub_Name "$hook"))} spids: [226] ) (HereDoc op_id: Redir_DLessDash fd: -1 body: {("#!/bin/sh\n") ("set -e\n") ("cd \"$1/..\" # \"$1\" is repository location\n") ("exec >> svn-hook.log 2>&1\n") ("hook=\"$(basename \"$0\")\"\n") ("echo \"*** Executing $hook $@\"\n") ("set -x\n") (". ./$hook-counter\n") ("cnt=\"$(($cnt - 1))\"\n") ("echo \"cnt=$cnt\" > ./$hook-counter\n") ("[ \"$cnt\" = \"0\" ] || exit 0\n") } do_expansion: False here_end: EOF1 was_filled: True spids: [232] ) ] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$hook_type"))} {(Lit_Other "=")} {(DQ (pre-commit))} {(Lit_Other "]")} ) terminator: <Op_Semi ";"> ) ] action: [ (SimpleCommand words: [{(echo)} {(DQ ("echo 'commit disallowed' >&2; exit 1"))}] redirects: [ (Redir op_id: Redir_DGreat fd: -1 arg_word: {(DQ ($ VSub_Name "$hook"))} spids: [265] ) ] ) ] spids: [-1 256] ) ] else_action: [ (SimpleCommand words: [ {(echo)} { (DQ ("PATH=") (EscapedLiteralPart token:<Lit_EscapedChar "\\\"">) ($ VSub_Name "$PATH") (EscapedLiteralPart token:<Lit_EscapedChar "\\\"">) ("; export PATH") ) } ] redirects: [ (Redir op_id: Redir_DGreat fd: -1 arg_word: {(DQ ($ VSub_Name "$hook"))} spids: [284] ) ] ) (SimpleCommand words: [ {(echo)} { (DQ ("svnconf=") (EscapedLiteralPart token:<Lit_EscapedChar "\\\"">) ($ VSub_Name "$svnconf") (EscapedLiteralPart token:<Lit_EscapedChar "\\\"">) ) } ] redirects: [ (Redir op_id: Redir_DGreat fd: -1 arg_word: {(DQ ($ VSub_Name "$hook"))} spids: [299] ) ] ) (SimpleCommand words: [{(cat)}] redirects: [ (Redir op_id: Redir_DGreat fd: -1 arg_word: {(DQ ($ VSub_Name "$hook"))} spids: [307] ) (HereDoc op_id: Redir_DLessDash fd: -1 body: {("cd work-auto-commits.svn\n") ("svn up --config-dir \"$svnconf\"\n") ("echo \"$$\" >> auto_updated_file\n") ("svn commit --config-dir \"$svnconf\" \\\n") ("-m \"auto-committing concurrent change\"\n") ("exit 0\n") } do_expansion: False here_end: EOF2 was_filled: True spids: [312] ) ] ) ] spids: [271 319] ) (C {(chmod)} {(755)} {(DQ ($ VSub_Name "$hook"))}) ] spids: [105] ) spids: [101 104] ) (FuncDef name: check_contents body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:gitdir) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [340] ) ] spids: [340] ) (AndOr children: [ (Subshell child: (AndOr children: [(C {(cd)} {(../work.svn)}) (C {(svn_cmd)} {(up)})] op_id: Op_DAmp ) spids: [346 356] ) (AndOr children: [ (C {(test_cmp)} {(file)} {(../work.svn/file)}) (C {(test_cmp)} {(auto_updated_file)} {(../work.svn/auto_updated_file)}) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] spids: [337] ) spids: [333 336] ) (C {(test_expect_success)} {(SQ <"check if post-commit hook creates a concurrent commit">)} { (SQ <"\n"> <"\tsetup_hook post-commit 1 &&\n"> <"\t(\n"> <"\t\tcd work.svn &&\n"> <"\t\tcp auto_updated_file au_file_saved &&\n"> <"\t\techo 1 >> file &&\n"> <"\t\tsvn_cmd commit -m \"changing file\" &&\n"> <"\t\tsvn_cmd up &&\n"> <"\t\ttest_must_fail test_cmp auto_updated_file au_file_saved\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SQ <"check if pre-commit hook fails">)} { (SQ <"\n"> <"\tsetup_hook pre-commit 2 &&\n"> <"\t(\n"> <"\t\tcd work.svn &&\n"> <"\t\techo 2 >> file &&\n"> <"\t\tsvn_cmd commit -m \"changing file once again\" &&\n"> <"\t\techo 3 >> file &&\n"> <"\t\ttest_must_fail svn_cmd commit -m \"this commit should fail\" &&\n"> <"\t\tsvn_cmd revert file\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SQ <"dcommit error handling">)} { (SQ <"\n"> <"\tsetup_hook pre-commit 2 &&\n"> <"\tnext_N && git svn clone \"$svnrepo\" work$N.git &&\n"> <"\t(\n"> <"\t\tcd work$N.git &&\n"> <"\t\techo 1 >> file && git commit -am \"commit change $N.1\" &&\n"> <"\t\techo 2 >> file && git commit -am \"commit change $N.2\" &&\n"> <"\t\techo 3 >> file && git commit -am \"commit change $N.3\" &&\n"> <"\t\t# should fail to dcommit 2nd and 3rd change\n"> <"\t\t# but still should leave the repository in reasonable state\n"> <"\t\ttest_must_fail git svn dcommit &&\n"> <"\t\tgit update-index --refresh &&\n"> <"\t\tgit show HEAD~2 | grep -q git-svn-id &&\n"> <"\t\t! git show HEAD~1 | grep -q git-svn-id &&\n"> <"\t\t! git show HEAD | grep -q git-svn-id\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SQ <"dcommit concurrent change in non-changed file">)} { (SQ <"\n"> <"\tsetup_hook post-commit 2 &&\n"> <"\tnext_N && git svn clone \"$svnrepo\" work$N.git &&\n"> <"\t(\n"> <"\t\tcd work$N.git &&\n"> <"\t\techo 1 >> file && git commit -am \"commit change $N.1\" &&\n"> <"\t\techo 2 >> file && git commit -am \"commit change $N.2\" &&\n"> <"\t\techo 3 >> file && git commit -am \"commit change $N.3\" &&\n"> <"\t\t# should rebase and leave the repository in reasonable state\n"> <"\t\tgit svn dcommit &&\n"> <"\t\tgit update-index --refresh &&\n"> <"\t\tcheck_contents &&\n"> <"\t\tgit show HEAD~3 | grep -q git-svn-id &&\n"> <"\t\tgit show HEAD~2 | grep -q git-svn-id &&\n"> <"\t\tgit show HEAD~1 | grep -q auto-committing &&\n"> <"\t\tgit show HEAD | grep -q git-svn-id\n"> <"\t)\n"> ) } ) (FuncDef name: delete_first_line body: (BraceGroup children: [ (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:file) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [482] ) ] spids: [482] ) (AndOr children: [ (SimpleCommand words: [{(sed)} {(1d)}] redirects: [ (Redir op_id: Redir_Less fd: -1 arg_word: {(DQ ($ VSub_Name "$file"))} spids: [494] ) (Redir op_id: Redir_Great fd: -1 arg_word: {(DQ (${ VSub_Name file) (.tmp))} spids: [500] ) ] ) (AndOr children: [ (C {(rm)} {(DQ ($ VSub_Name "$file"))}) (C {(mv)} {(DQ (${ VSub_Name file) (.tmp))} {(DQ ($ VSub_Name "$file"))}) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) ] spids: [479] ) spids: [475 478] ) (C {(test_expect_success)} {(SQ <"dcommit concurrent non-conflicting change">)} { (SQ <"\n"> <"\tsetup_hook post-commit 2 &&\n"> <"\tnext_N && git svn clone \"$svnrepo\" work$N.git &&\n"> <"\t(\n"> <"\t\tcd work$N.git &&\n"> <"\t\tcat file >> auto_updated_file &&\n"> <"\t\t\tgit commit -am \"commit change $N.1\" &&\n"> <"\t\tdelete_first_line auto_updated_file &&\n"> <"\t\t\tgit commit -am \"commit change $N.2\" &&\n"> <"\t\tdelete_first_line auto_updated_file &&\n"> <"\t\t\tgit commit -am \"commit change $N.3\" &&\n"> <"\t\t# should rebase and leave the repository in reasonable state\n"> <"\t\tgit svn dcommit &&\n"> <"\t\tgit update-index --refresh &&\n"> <"\t\tcheck_contents &&\n"> <"\t\tgit show HEAD~3 | grep -q git-svn-id &&\n"> <"\t\tgit show HEAD~2 | grep -q git-svn-id &&\n"> <"\t\tgit show HEAD~1 | grep -q auto-committing &&\n"> <"\t\tgit show HEAD | grep -q git-svn-id\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SQ <"dcommit --no-rebase concurrent non-conflicting change">)} { (SQ <"\n"> <"\tsetup_hook post-commit 2 &&\n"> <"\tnext_N && git svn clone \"$svnrepo\" work$N.git &&\n"> <"\t(\n"> <"\t\tcd work$N.git &&\n"> <"\t\tcat file >> auto_updated_file &&\n"> <"\t\t\tgit commit -am \"commit change $N.1\" &&\n"> <"\t\tdelete_first_line auto_updated_file &&\n"> <"\t\t\tgit commit -am \"commit change $N.2\" &&\n"> <"\t\tdelete_first_line auto_updated_file &&\n"> <"\t\t\tgit commit -am \"commit change $N.3\" &&\n"> <"\t\t# should fail as rebase is needed\n"> <"\t\ttest_must_fail git svn dcommit --no-rebase &&\n"> <"\t\t# but should leave HEAD unchanged\n"> <"\t\tgit update-index --refresh &&\n"> <"\t\t! git show HEAD~2 | grep -q git-svn-id &&\n"> <"\t\t! git show HEAD~1 | grep -q git-svn-id &&\n"> <"\t\t! git show HEAD | grep -q git-svn-id\n"> <"\t)\n"> ) } ) (C {(test_expect_success)} {(SQ <"dcommit fails on concurrent conflicting change">)} { (SQ <"\n"> <"\tsetup_hook post-commit 1 &&\n"> <"\tnext_N && git svn clone \"$svnrepo\" work$N.git &&\n"> <"\t(\n"> <"\t\tcd work$N.git &&\n"> <"\t\techo a >> file &&\n"> <"\t\t\tgit commit -am \"commit change $N.1\" &&\n"> <"\t\techo b >> auto_updated_file &&\n"> <"\t\t\tgit commit -am \"commit change $N.2\" &&\n"> <"\t\techo c >> auto_updated_file &&\n"> <"\t\t\tgit commit -am \"commit change $N.3\" &&\n"> <"\t\ttest_must_fail git svn dcommit && # rebase should fail\n"> <"\t\ttest_must_fail git update-index --refresh\n"> <"\t)\n"> ) } ) (C {(test_done)}) ] )