(command.CommandList children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:test_description) op: assign_op.Equal rhs: {(SQ <'pushing to a repository using the atomic push option'>)} spids: [4] ) ] ) (C {<.>} {<'./test-lib.sh'>}) (command.ShFunction name: mk_repo_pair body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp] children: [ (C {<rm>} {<-rf>} {<workbench>} {<upstream>}) (C {<test_create_repo>} {<upstream>}) (C {<test_create_repo>} {<workbench>}) (command.Subshell child: (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<cd>} {<upstream>}) (C {<git>} {<config>} {<receive.denyCurrentBranch>} {<warn>}) ] ) ) (command.Subshell child: (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<cd>} {<workbench>}) (C {<git>} {<remote>} {<add>} {<up>} {<'../upstream'>}) ] ) ) ] ) ] ) ) (command.ShFunction name: test_refs body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp] children: [ (C {<test>} {($ Id.VSub_Pound '$#')} {<Id.Lit_Equals '='>} {<2>}) (command.Simple words: [ {<git>} {<-C>} {<upstream>} {<rev-parse>} {<--verify>} {(DQ ($ Id.VSub_Number '$1'))} ] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<expect>})] do_fork: T ) (command.Simple words: [ {<git>} {<-C>} {<workbench>} {<rev-parse>} {<--verify>} {(DQ ($ Id.VSub_Number '$2'))} ] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<actual>})] do_fork: T ) (C {<test_cmp>} {<expect>} {<actual>}) ] ) ] ) ) (C {<test_expect_success>} {(SQ <'atomic push works for a single branch'>)} { (SQ <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd workbench &&\n'> <'\t\ttest_commit one &&\n'> <'\t\tgit push --mirror up &&\n'> <'\t\ttest_commit two &&\n'> <'\t\tgit push --atomic up master\n'> <'\t) &&\n'> <'\ttest_refs master master\n'> ) } ) (C {<test_expect_success>} {(SQ <'atomic push works for two branches'>)} { (SQ <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd workbench &&\n'> <'\t\ttest_commit one &&\n'> <'\t\tgit branch second &&\n'> <'\t\tgit push --mirror up &&\n'> <'\t\ttest_commit two &&\n'> <'\t\tgit checkout second &&\n'> <'\t\ttest_commit three &&\n'> <'\t\tgit push --atomic up master second\n'> <'\t) &&\n'> <'\ttest_refs master master &&\n'> <'\ttest_refs second second\n'> ) } ) (C {<test_expect_success>} {(SQ <'atomic push works in combination with --mirror'>)} { (SQ <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd workbench &&\n'> <'\t\ttest_commit one &&\n'> <'\t\tgit checkout -b second &&\n'> <'\t\ttest_commit two &&\n'> <'\t\tgit push --atomic --mirror up\n'> <'\t) &&\n'> <'\ttest_refs master master &&\n'> <'\ttest_refs second second\n'> ) } ) (C {<test_expect_success>} {(SQ <'atomic push works in combination with --force'>)} { (SQ <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd workbench &&\n'> <'\t\ttest_commit one &&\n'> <'\t\tgit branch second master &&\n'> <'\t\ttest_commit two_a &&\n'> <'\t\tgit checkout second &&\n'> <'\t\ttest_commit two_b &&\n'> <'\t\ttest_commit three_b &&\n'> <'\t\ttest_commit four &&\n'> <'\t\tgit push --mirror up &&\n'> <'\t\t# The actual test is below\n'> <'\t\tgit checkout master &&\n'> <'\t\ttest_commit three_a &&\n'> <'\t\tgit checkout second &&\n'> <'\t\tgit reset --hard HEAD^ &&\n'> <'\t\tgit push --force --atomic up master second\n'> <'\t) &&\n'> <'\ttest_refs master master &&\n'> <'\ttest_refs second second\n'> ) } ) (C {<test_expect_success>} {(SQ <'atomic push fails if one branch fails'>)} { (SQ <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd workbench &&\n'> <'\t\ttest_commit one &&\n'> <'\t\tgit checkout -b second master &&\n'> <'\t\ttest_commit two &&\n'> <'\t\ttest_commit three &&\n'> <'\t\ttest_commit four &&\n'> <'\t\tgit push --mirror up &&\n'> <'\t\tgit reset --hard HEAD~2 &&\n'> <'\t\ttest_commit five &&\n'> <'\t\tgit checkout master &&\n'> <'\t\ttest_commit six &&\n'> <'\t\ttest_must_fail git push --atomic --all up\n'> <'\t) &&\n'> <'\ttest_refs master HEAD@{7} &&\n'> <'\ttest_refs second HEAD@{4}\n'> ) } ) (C {<test_expect_success>} {(SQ <'atomic push fails if one tag fails remotely'>)} { (SQ <'\n'> <'\t# prepare the repo\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd workbench &&\n'> <'\t\ttest_commit one &&\n'> <'\t\tgit checkout -b second master &&\n'> <'\t\ttest_commit two &&\n'> <'\t\tgit push --mirror up\n'> <'\t) &&\n'> <'\t# a third party modifies the server side:\n'> <'\t(\n'> <'\t\tcd upstream &&\n'> <'\t\tgit checkout second &&\n'> <'\t\tgit tag test_tag second\n'> <'\t) &&\n'> <'\t# see if we can now push both branches.\n'> <'\t(\n'> <'\t\tcd workbench &&\n'> <'\t\tgit checkout master &&\n'> <'\t\ttest_commit three &&\n'> <'\t\tgit checkout second &&\n'> <'\t\ttest_commit four &&\n'> <'\t\tgit tag test_tag &&\n'> <'\t\ttest_must_fail git push --tags --atomic up master second\n'> <'\t) &&\n'> <'\ttest_refs master HEAD@{3} &&\n'> <'\ttest_refs second HEAD@{1}\n'> ) } ) (C {<test_expect_success>} {(SQ <'atomic push obeys update hook preventing a branch to be pushed'>)} { (SQ <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd workbench &&\n'> <'\t\ttest_commit one &&\n'> <'\t\tgit checkout -b second master &&\n'> <'\t\ttest_commit two &&\n'> <'\t\tgit push --mirror up\n'> <'\t) &&\n'> <'\t(\n'> <'\t\tcd upstream &&\n'> <'\t\tHOOKDIR="$(git rev-parse --git-dir)/hooks" &&\n'> <'\t\tHOOK="$HOOKDIR/update" &&\n'> <'\t\tmkdir -p "$HOOKDIR" &&\n'> <'\t\twrite_script "$HOOK" <<-\\EOF\n'> <'\t\t\t# only allow update to master from now on\n'> <'\t\t\ttest "$1" = "refs/heads/master"\n'> <'\t\tEOF\n'> <'\t) &&\n'> <'\t(\n'> <'\t\tcd workbench &&\n'> <'\t\tgit checkout master &&\n'> <'\t\ttest_commit three &&\n'> <'\t\tgit checkout second &&\n'> <'\t\ttest_commit four &&\n'> <'\t\ttest_must_fail git push --atomic up master second\n'> <'\t) &&\n'> <'\ttest_refs master HEAD@{3} &&\n'> <'\ttest_refs second HEAD@{1}\n'> ) } ) (C {<test_expect_success>} {(SQ <'atomic push is not advertised if configured'>)} { (SQ <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd upstream\n'> <'\t\tgit config receive.advertiseatomic 0\n'> <'\t) &&\n'> <'\t(\n'> <'\t\tcd workbench &&\n'> <'\t\ttest_commit one &&\n'> <'\t\tgit push --mirror up &&\n'> <'\t\ttest_commit two &&\n'> <'\t\ttest_must_fail git push --atomic up master\n'> <'\t) &&\n'> <'\ttest_refs master HEAD@{1}\n'> ) } ) (C {<test_done>}) ] )