test_cmp expect dst/push-cert-status
'
+test_expect_success GPG 'inconsistent push options in signed push not allowed' '
+ # First, invoke receive-pack with dummy input to obtain its preamble.
+ prepare_dst &&
+ git -C dst config receive.certnonceseed sekrit &&
+ git -C dst config receive.advertisepushoptions 1 &&
+ printf xxxx | test_might_fail git receive-pack dst >preamble &&
+
+ # Then, invoke push. Simulate a receive-pack that sends the preamble we
+ # obtained, followed by a dummy packet.
+ write_script myscript <<-\EOF &&
+ cat preamble &&
+ printf xxxx &&
+ cat >push
+ EOF
+ test_might_fail git push --push-option="foo" --push-option="bar" \
+ --receive-pack="\"$(pwd)/myscript\"" --signed dst --delete ff &&
+
+ # Replay the push output on a fresh dst, checking that ff is truly
+ # deleted.
+ prepare_dst &&
+ git -C dst config receive.certnonceseed sekrit &&
+ git -C dst config receive.advertisepushoptions 1 &&
+ git receive-pack dst <push &&
+ test_must_fail git -C dst rev-parse ff &&
+
+ # Tweak the push output to make the push option outside the cert
+ # different, then replay it on a fresh dst, checking that ff is not
+ # deleted.
+ perl -pe "s/([^ ])bar/\$1baz/" push >push.tweak &&
+ prepare_dst &&
+ git -C dst config receive.certnonceseed sekrit &&
+ git -C dst config receive.advertisepushoptions 1 &&
+ git receive-pack dst <push.tweak >out &&
+ git -C dst rev-parse ff &&
+ grep "inconsistent push options" out
+'
+
+test_expect_success GPG 'fail without key and heed user.signingkey' '
+ prepare_dst &&
+ mkdir -p dst/.git/hooks &&
+ git -C dst config receive.certnonceseed sekrit &&
+ write_script dst/.git/hooks/post-receive <<-\EOF &&
+ # discard the update list
+ cat >/dev/null
+ # record the push certificate
+ if test -n "${GIT_PUSH_CERT-}"
+ then
+ git cat-file blob $GIT_PUSH_CERT >../push-cert
+ fi &&
+
+ cat >../push-cert-status <<E_O_F
+ SIGNER=${GIT_PUSH_CERT_SIGNER-nobody}
+ KEY=${GIT_PUSH_CERT_KEY-nokey}
+ STATUS=${GIT_PUSH_CERT_STATUS-nostatus}
+ NONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus}
+ NONCE=${GIT_PUSH_CERT_NONCE-nononce}
+ E_O_F
+
+ EOF
+
+ unset GIT_COMMITTER_EMAIL &&
+ git config user.email hasnokey@nowhere.com &&
+ test_must_fail git push --signed dst noop ff +noff &&
+ git config user.signingkey committer@example.com &&
+ git push --signed dst noop ff +noff &&
+
+ (
+ cat <<-\EOF &&
+ SIGNER=C O Mitter <committer@example.com>
+ KEY=13B6F51ECDDE430D
+ STATUS=G
+ NONCE_STATUS=OK
+ EOF
+ sed -n -e "s/^nonce /NONCE=/p" -e "/^$/q" dst/push-cert
+ ) >expect &&
+
+ grep "$(git rev-parse noop ff) refs/heads/ff" dst/push-cert &&
+ grep "$(git rev-parse noop noff) refs/heads/noff" dst/push-cert &&
+ test_cmp expect dst/push-cert-status
+'
+
test_done