send-pack: send feature request on push-cert packet

We would want to update the interim protocol so that we do not send the usual update commands when the push certificate feature is in use, as the same information is in the certificate. Once that happens, the push-cert packet may become the only protocol command, but then there is no packet to put the feature request behind, like we always did. As we have prepared the receiving end that understands the push-cert feature to accept the feature request on the first protocol packet (other than "shallow ", which was an unfortunate historical mistake that has to come before everything else), we can give the feature request on the push-cert packet instead of the first update protocol packet, in preparation for the next step to actually update to the final protocol. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Aug 18, 2014 at 13:46 UTC 20a7558f31e44e26ddbb8aa55bfd9316a6b67f82
2 files changed +21 -5
send-pack.c
+8 -5
@@ -225,9 +225,10 @@ static const char *next_line(const char *line, size_t len)
225 return nl + 1;
226 }
227
228 -static void generate_push_cert(struct strbuf *req_buf,
229 - const struct ref *remote_refs,
230 - struct send_pack_args *args)
228 +static int generate_push_cert(struct strbuf *req_buf,
229 + const struct ref *remote_refs,
230 + struct send_pack_args *args,
231 + const char *cap_string)
232 {
233 const struct ref *ref;
234 char stamp[60];
@@ -256,7 +257,7 @@ static void generate_push_cert(struct strbuf *req_buf,
257 if (sign_buffer(&cert, &cert, signing_key))
258 die(_("failed to sign the push certificate"));
259
259 - packet_buf_write(req_buf, "push-cert\n");
260 + packet_buf_write(req_buf, "push-cert%c%s", 0, cap_string);
261 for (cp = cert.buf; cp < cert.buf + cert.len; cp = np) {
262 np = next_line(cp, cert.buf + cert.len - cp);
263 packet_buf_write(req_buf,
@@ -267,6 +268,7 @@ static void generate_push_cert(struct strbuf *req_buf,
268 free_return:
269 free(signing_key);
270 strbuf_release(&cert);
271 + return update_seen;
272 }
273
274 int send_pack(struct send_pack_args *args,
@@ -335,7 +337,8 @@ int send_pack(struct send_pack_args *args,
337 advertise_shallow_grafts_buf(&req_buf);
338
339 if (!args->dry_run && args->push_cert)
338 - generate_push_cert(&req_buf, remote_refs, args);
340 + cmds_sent = generate_push_cert(&req_buf, remote_refs, args,
341 + cap_buf.buf);
342
343 /*
344 * Clear the status for each ref and see if we need to send
t/t5534-push-signed.sh
+13
@@ -73,6 +73,19 @@ test_expect_success 'push --signed fails with a receiver without push certificat
73 test_i18ngrep "the receiving end does not support" err
74 '
75
76 +test_expect_success GPG 'no certificate for a signed push with no update' '
77 + prepare_dst &&
78 + mkdir -p dst/.git/hooks &&
79 + write_script dst/.git/hooks/post-receive <<-\EOF &&
80 + if test -n "${GIT_PUSH_CERT-}"
81 + then
82 + git cat-file blob $GIT_PUSH_CERT >../push-cert
83 + fi
84 + EOF
85 + git push dst noop &&
86 + ! test -f dst/push-cert
87 +'
88 +
89 test_expect_success GPG 'signed push sends push certificate' '
90 prepare_dst &&
91 mkdir -p dst/.git/hooks &&