(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 mirror repository'>)}
          spids: [4]
        )
      ]
    )
    (C {<.>} {<'./test-lib.sh'>})
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:D)
          op: assign_op.Equal
          rhs: {(command_sub left_token:<Id.Left_DollarParen '$('> child:(C {<pwd>}))}
          spids: [15]
        )
      ]
    )
    (command.ShFunction
      name: invert
      body: 
        (BraceGroup
          children: [
            (command.If
              arms: [
                (if_arm
                  cond: 
                    (condition.Shell
                      commands: [
                        (command.Sentence
                          child: (C {(DQ ($ Id.VSub_At '$@'))})
                          terminator: <Id.Op_Semi _>
                        )
                      ]
                    )
                  action: [(command.ControlFlow token:<Id.ControlFlow_Return return> arg_word:{<1>})]
                  spids: [29 36]
                )
              ]
              else_action: [(command.ControlFlow token:<Id.ControlFlow_Return return> arg_word:{<0>})]
            )
          ]
        )
    )
    (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>} {<master>} {<mirror>})
                (C {<mkdir>} {<mirror>})
                (command.Subshell
                  child: 
                    (command.AndOr
                      ops: [Id.Op_DAmp Id.Op_DAmp]
                      children: [
                        (C {<cd>} {<mirror>})
                        (C {<git>} {<init>})
                        (C {<git>} {<config>} {<receive.denyCurrentBranch>} {<warn>})
                      ]
                    )
                )
                (C {<mkdir>} {<master>})
                (command.Subshell
                  child: 
                    (command.AndOr
                      ops: [Id.Op_DAmp Id.Op_DAmp]
                      children: [
                        (C {<cd>} {<master>})
                        (C {<git>} {<init>})
                        (C {<git>} {<remote>} {<add>} {($ Id.VSub_Number '$1')} {<up>} {<'../mirror'>})
                      ]
                    )
                )
              ]
            )
          ]
        )
    )
    (C {<test_expect_success>} {(SQ <'push mirror creates new branches'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd master &&\n'> 
          <'\t\techo one >foo && git add foo && git commit -m one &&\n'> <'\t\tgit push --mirror up\n'> <'\t) &&\n'> 
          <'\tmaster_master=$(cd master && git show-ref -s --verify refs/heads/master) &&\n'> <'\tmirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) &&\n'> 
          <'\ttest "$master_master" = "$mirror_master"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'push mirror updates existing branches'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd master &&\n'> 
          <'\t\techo one >foo && git add foo && git commit -m one &&\n'> <'\t\tgit push --mirror up &&\n'> <'\t\techo two >foo && git add foo && git commit -m two &&\n'> 
          <'\t\tgit push --mirror up\n'> <'\t) &&\n'> <'\tmaster_master=$(cd master && git show-ref -s --verify refs/heads/master) &&\n'> 
          <'\tmirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) &&\n'> <'\ttest "$master_master" = "$mirror_master"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'push mirror force updates existing branches'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd master &&\n'> 
          <'\t\techo one >foo && git add foo && git commit -m one &&\n'> <'\t\tgit push --mirror up &&\n'> <'\t\techo two >foo && git add foo && git commit -m two &&\n'> 
          <'\t\tgit push --mirror up &&\n'> <'\t\tgit reset --hard HEAD^\n'> <'\t\tgit push --mirror up\n'> <'\t) &&\n'> 
          <'\tmaster_master=$(cd master && git show-ref -s --verify refs/heads/master) &&\n'> <'\tmirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) &&\n'> 
          <'\ttest "$master_master" = "$mirror_master"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'push mirror removes branches'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd master &&\n'> 
          <'\t\techo one >foo && git add foo && git commit -m one &&\n'> <'\t\tgit branch remove master &&\n'> <'\t\tgit push --mirror up &&\n'> <'\t\tgit branch -D remove\n'> 
          <'\t\tgit push --mirror up\n'> <'\t) &&\n'> <'\t(\n'> <'\t\tcd mirror &&\n'> 
          <'\t\tinvert git show-ref -s --verify refs/heads/remove\n'> <'\t)\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'push mirror adds, updates and removes branches together'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd master &&\n'> 
          <'\t\techo one >foo && git add foo && git commit -m one &&\n'> <'\t\tgit branch remove master &&\n'> <'\t\tgit push --mirror up &&\n'> 
          <'\t\tgit branch -D remove &&\n'> <'\t\tgit branch add master &&\n'> <'\t\techo two >foo && git add foo && git commit -m two &&\n'> 
          <'\t\tgit push --mirror up\n'> <'\t) &&\n'> <'\tmaster_master=$(cd master && git show-ref -s --verify refs/heads/master) &&\n'> 
          <'\tmaster_add=$(cd master && git show-ref -s --verify refs/heads/add) &&\n'> <'\tmirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) &&\n'> 
          <'\tmirror_add=$(cd mirror && git show-ref -s --verify refs/heads/add) &&\n'> <'\ttest "$master_master" = "$mirror_master" &&\n'> <'\ttest "$master_add" = "$mirror_add" &&\n'> 
          <'\t(\n'> <'\t\tcd mirror &&\n'> <'\t\tinvert git show-ref -s --verify refs/heads/remove\n'> <'\t)\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'push mirror creates new tags'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd master &&\n'> 
          <'\t\techo one >foo && git add foo && git commit -m one &&\n'> <'\t\tgit tag -f tmaster master &&\n'> <'\t\tgit push --mirror up\n'> <'\t) &&\n'> 
          <'\tmaster_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) &&\n'> <'\tmirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) &&\n'> 
          <'\ttest "$master_master" = "$mirror_master"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'push mirror updates existing tags'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd master &&\n'> 
          <'\t\techo one >foo && git add foo && git commit -m one &&\n'> <'\t\tgit tag -f tmaster master &&\n'> <'\t\tgit push --mirror up &&\n'> 
          <'\t\techo two >foo && git add foo && git commit -m two &&\n'> <'\t\tgit tag -f tmaster master &&\n'> <'\t\tgit push --mirror up\n'> <'\t) &&\n'> 
          <'\tmaster_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) &&\n'> <'\tmirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) &&\n'> 
          <'\ttest "$master_master" = "$mirror_master"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'push mirror force updates existing tags'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd master &&\n'> 
          <'\t\techo one >foo && git add foo && git commit -m one &&\n'> <'\t\tgit tag -f tmaster master &&\n'> <'\t\tgit push --mirror up &&\n'> 
          <'\t\techo two >foo && git add foo && git commit -m two &&\n'> <'\t\tgit tag -f tmaster master &&\n'> <'\t\tgit push --mirror up &&\n'> 
          <'\t\tgit reset --hard HEAD^\n'> <'\t\tgit tag -f tmaster master &&\n'> <'\t\tgit push --mirror up\n'> <'\t) &&\n'> 
          <'\tmaster_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) &&\n'> <'\tmirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) &&\n'> 
          <'\ttest "$master_master" = "$mirror_master"\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'push mirror removes tags'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd master &&\n'> 
          <'\t\techo one >foo && git add foo && git commit -m one &&\n'> <'\t\tgit tag -f tremove master &&\n'> <'\t\tgit push --mirror up &&\n'> <'\t\tgit tag -d tremove\n'> 
          <'\t\tgit push --mirror up\n'> <'\t) &&\n'> <'\t(\n'> <'\t\tcd mirror &&\n'> 
          <'\t\tinvert git show-ref -s --verify refs/tags/tremove\n'> <'\t)\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'push mirror adds, updates and removes tags together'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd master &&\n'> 
          <'\t\techo one >foo && git add foo && git commit -m one &&\n'> <'\t\tgit tag -f tmaster master &&\n'> <'\t\tgit tag -f tremove master &&\n'> 
          <'\t\tgit push --mirror up &&\n'> <'\t\tgit tag -d tremove &&\n'> <'\t\tgit tag tadd master &&\n'> 
          <'\t\techo two >foo && git add foo && git commit -m two &&\n'> <'\t\tgit tag -f tmaster master &&\n'> <'\t\tgit push --mirror up\n'> <'\t) &&\n'> 
          <'\tmaster_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) &&\n'> <'\tmaster_add=$(cd master && git show-ref -s --verify refs/tags/tadd) &&\n'> 
          <'\tmirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) &&\n'> <'\tmirror_add=$(cd mirror && git show-ref -s --verify refs/tags/tadd) &&\n'> 
          <'\ttest "$master_master" = "$mirror_master" &&\n'> <'\ttest "$master_add" = "$mirror_add" &&\n'> <'\t(\n'> <'\t\tcd mirror &&\n'> 
          <'\t\tinvert git show-ref -s --verify refs/tags/tremove\n'> <'\t)\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'remote.foo.mirror adds and removes branches'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tmk_repo_pair --mirror &&\n'> <'\t(\n'> <'\t\tcd master &&\n'> 
          <'\t\techo one >foo && git add foo && git commit -m one &&\n'> <'\t\tgit branch keep master &&\n'> <'\t\tgit branch remove master &&\n'> <'\t\tgit push up &&\n'> 
          <'\t\tgit branch -D remove\n'> <'\t\tgit push up\n'> <'\t) &&\n'> <'\t(\n'> <'\t\tcd mirror &&\n'> 
          <'\t\tgit show-ref -s --verify refs/heads/keep &&\n'> <'\t\tinvert git show-ref -s --verify refs/heads/remove\n'> <'\t)\n'> <'\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'remote.foo.mirror=no has no effect'>)} 
      {
        (SQ <'\n'> <'\n'> <'\tmk_repo_pair &&\n'> <'\t(\n'> <'\t\tcd master &&\n'> 
          <'\t\techo one >foo && git add foo && git commit -m one &&\n'> <'\t\tgit config --add remote.up.mirror no &&\n'> <'\t\tgit branch keep master &&\n'> 
          <'\t\tgit push --mirror up &&\n'> <'\t\tgit branch -D keep &&\n'> <'\t\tgit push up :\n'> <'\t) &&\n'> <'\t(\n'> <'\t\tcd mirror &&\n'> 
          <'\t\tgit show-ref -s --verify refs/heads/keep\n'> <'\t)\n'> <'\n'>
        )
      }
    )
    (C {<test_done>})
  ]
)