(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:test_description)
          op: assign_op.Equal
          rhs: {(SQ <'signed push'>)}
          spids: [4]
        )
      ]
    )
    (C {<.>} {<'./test-lib.sh'>})
    (C {<.>} {(DQ ($ Id.VSub_DollarName '$TEST_DIRECTORY')) <'/lib-gpg.sh'>})
    (command.ShFunction
      name: prepare_dst
      body: 
        (BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DAmp Id.Op_DAmp]
              children: [
                (C {<rm>} {<-fr>} {<dst>})
                (C {<test_create_repo>} {<dst>})
                (C {<git>} {<push>} {<dst>} {<master> <Id.Lit_Colon ':'> <noop>} 
                  {<master> <Id.Lit_Colon ':'> <ff>} {<master> <Id.Lit_Colon ':'> <noff>}
                )
              ]
            )
          ]
        )
    )
    (C {<test_expect_success>} {<setup>} 
      {
        (SQ <'\n'> <'\t# master, ff and noff branches pointing at the same commit\n'> 
          <'\ttest_tick &&\n'> <'\tgit commit --allow-empty -m initial &&\n'> <'\n'> <'\tgit checkout -b noop &&\n'> 
          <'\tgit checkout -b ff &&\n'> <'\tgit checkout -b noff &&\n'> <'\n'> <'\t# noop stays the same, ff advances, noff rewrites\n'> 
          <'\ttest_tick &&\n'> <'\tgit commit --allow-empty --amend -m rewritten &&\n'> <'\tgit checkout ff &&\n'> <'\n'> 
          <'\ttest_tick &&\n'> <'\tgit commit --allow-empty -m second\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'unsigned push does not send push certificate'>)} 
      {
        (SQ <'\n'> <'\tprepare_dst &&\n'> <'\tmkdir -p dst/.git/hooks &&\n'> 
          <'\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n'> <'\t# discard the update list\n'> <'\tcat >/dev/null\n'> <'\t# record the push certificate\n'> 
          <'\tif test -n "${GIT_PUSH_CERT-}"\n'> <'\tthen\n'> <'\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n'> <'\tfi\n'> <'\tEOF\n'> <'\n'> 
          <'\tgit push dst noop ff +noff &&\n'> <'\t! test -f dst/push-cert\n'>
        )
      }
    )
    (C {<test_expect_success>} {(SQ <'talking with a receiver without push certificate support'>)} 
      {
        (SQ <'\n'> <'\tprepare_dst &&\n'> <'\tmkdir -p dst/.git/hooks &&\n'> 
          <'\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n'> <'\t# discard the update list\n'> <'\tcat >/dev/null\n'> <'\t# record the push certificate\n'> 
          <'\tif test -n "${GIT_PUSH_CERT-}"\n'> <'\tthen\n'> <'\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n'> <'\tfi\n'> <'\tEOF\n'> <'\n'> 
          <'\tgit push dst noop ff +noff &&\n'> <'\t! test -f dst/push-cert\n'>
        )
      }
    )
    (C {<test_expect_success>} 
      {(SQ <'push --signed fails with a receiver without push certificate support'>)} 
      {
        (SQ <'\n'> <'\tprepare_dst &&\n'> <'\tmkdir -p dst/.git/hooks &&\n'> 
          <'\ttest_must_fail git push --signed dst noop ff +noff 2>err &&\n'> <'\ttest_i18ngrep "the receiving end does not support" err\n'>
        )
      }
    )
    (C {<test_expect_success>} {<GPG>} {(SQ <'no certificate for a signed push with no update'>)} 
      {
        (SQ <'\n'> <'\tprepare_dst &&\n'> <'\tmkdir -p dst/.git/hooks &&\n'> 
          <'\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n'> <'\tif test -n "${GIT_PUSH_CERT-}"\n'> <'\tthen\n'> 
          <'\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n'> <'\tfi\n'> <'\tEOF\n'> <'\tgit push dst noop &&\n'> <'\t! test -f dst/push-cert\n'>
        )
      }
    )
    (C {<test_expect_success>} {<GPG>} {(SQ <'signed push sends push certificate'>)} 
      {
        (SQ <'\n'> <'\tprepare_dst &&\n'> <'\tmkdir -p dst/.git/hooks &&\n'> 
          <'\tgit -C dst config receive.certnonceseed sekrit &&\n'> <'\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n'> <'\t# discard the update list\n'> 
          <'\tcat >/dev/null\n'> <'\t# record the push certificate\n'> <'\tif test -n "${GIT_PUSH_CERT-}"\n'> <'\tthen\n'> 
          <'\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n'> <'\tfi &&\n'> <'\n'> <'\tcat >../push-cert-status <<E_O_F\n'> 
          <'\tSIGNER=${GIT_PUSH_CERT_SIGNER-nobody}\n'> <'\tKEY=${GIT_PUSH_CERT_KEY-nokey}\n'> <'\tSTATUS=${GIT_PUSH_CERT_STATUS-nostatus}\n'> 
          <'\tNONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}\n'> <'\tNONCE=${GIT_PUSH_CERT_NONCE-nononce}\n'> <'\tE_O_F\n'> <'\n'> <'\tEOF\n'> <'\n'> 
          <'\tgit push --signed dst noop ff +noff &&\n'> <'\n'> <'\t(\n'> <'\t\tcat <<-\\EOF &&\n'> <'\t\tSIGNER=C O Mitter <committer@example.com>\n'> 
          <'\t\tKEY=13B6F51ECDDE430D\n'> <'\t\tSTATUS=G\n'> <'\t\tNONCE_STATUS=OK\n'> <'\t\tEOF\n'> 
          <'\t\tsed -n -e "s/^nonce /NONCE=/p" -e "/^$/q" dst/push-cert\n'> <'\t) >expect &&\n'> <'\n'> <'\tgrep "$(git rev-parse noop ff) refs/heads/ff" dst/push-cert &&\n'> 
          <'\tgrep "$(git rev-parse noop noff) refs/heads/noff" dst/push-cert &&\n'> <'\ttest_cmp expect dst/push-cert-status\n'>
        )
      }
    )
    (C {<test_expect_success>} {<GPG>} {(SQ <'fail without key and heed user.signingkey'>)} 
      {
        (SQ <'\n'> <'\tprepare_dst &&\n'> <'\tmkdir -p dst/.git/hooks &&\n'> 
          <'\tgit -C dst config receive.certnonceseed sekrit &&\n'> <'\twrite_script dst/.git/hooks/post-receive <<-\\EOF &&\n'> <'\t# discard the update list\n'> 
          <'\tcat >/dev/null\n'> <'\t# record the push certificate\n'> <'\tif test -n "${GIT_PUSH_CERT-}"\n'> <'\tthen\n'> 
          <'\t\tgit cat-file blob $GIT_PUSH_CERT >../push-cert\n'> <'\tfi &&\n'> <'\n'> <'\tcat >../push-cert-status <<E_O_F\n'> 
          <'\tSIGNER=${GIT_PUSH_CERT_SIGNER-nobody}\n'> <'\tKEY=${GIT_PUSH_CERT_KEY-nokey}\n'> <'\tSTATUS=${GIT_PUSH_CERT_STATUS-nostatus}\n'> 
          <'\tNONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}\n'> <'\tNONCE=${GIT_PUSH_CERT_NONCE-nononce}\n'> <'\tE_O_F\n'> <'\n'> <'\tEOF\n'> <'\n'> 
          <'\tunset GIT_COMMITTER_EMAIL &&\n'> <'\tgit config user.email hasnokey@nowhere.com &&\n'> 
          <'\ttest_must_fail git push --signed dst noop ff +noff &&\n'> <'\tgit config user.signingkey committer@example.com &&\n'> 
          <'\tgit push --signed dst noop ff +noff &&\n'> <'\n'> <'\t(\n'> <'\t\tcat <<-\\EOF &&\n'> <'\t\tSIGNER=C O Mitter <committer@example.com>\n'> 
          <'\t\tKEY=13B6F51ECDDE430D\n'> <'\t\tSTATUS=G\n'> <'\t\tNONCE_STATUS=OK\n'> <'\t\tEOF\n'> 
          <'\t\tsed -n -e "s/^nonce /NONCE=/p" -e "/^$/q" dst/push-cert\n'> <'\t) >expect &&\n'> <'\n'> <'\tgrep "$(git rev-parse noop ff) refs/heads/ff" dst/push-cert &&\n'> 
          <'\tgrep "$(git rev-parse noop noff) refs/heads/noff" dst/push-cert &&\n'> <'\ttest_cmp expect dst/push-cert-status\n'>
        )
      }
    )
    (C {<test_done>})
  ]
)