New capability "report-status-v2" for git-push

The new introduced "proc-receive" hook may handle a command for a
pseudo-reference with a zero-old as its old-oid, while the hook may
create or update a reference with different name, different new-oid,
and different old-oid (the reference may exist already with a non-zero
old-oid).  Current "report-status" protocol cannot report the status for
such reference rewrite.

Add new capability "report-status-v2" and new report protocol which is
not backward compatible for report of git-push.

If a user pushes to a pseudo-reference "refs/for/master/topic", and
"receive-pack" creates two new references "refs/changes/23/123/1" and
"refs/changes/24/124/1", for client without the knowledge of
"report-status-v2", "receive-pack" will only send "ok/ng" directives in
the report, such as:

    ok ref/for/master/topic

But for client which has the knowledge of "report-status-v2",
"receive-pack" will use "option" directives to report more attributes
for the reference given by the above "ok/ng" directive.

    ok refs/for/master/topic
    option refname refs/changes/23/123/1
    option new-oid <new-oid>
    ok refs/for/master/topic
    option refname refs/changes/24/124/1
    option new-oid <new-oid>

The client will report two new created references to the end user.

Suggested-by: Junio C Hamano <gitster@pobox.com>
Suggested-by: Jeff King <peff@peff.net>
Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jiang Xin
2020-05-18 05:40:32 -04:00
committed by Junio C Hamano
parent 1e58de8c07
commit 5e4553bd38
15 changed files with 417 additions and 76 deletions

View File

@ -29,10 +29,12 @@ static struct send_pack_args args;
static void print_helper_status(struct ref *ref)
{
struct strbuf buf = STRBUF_INIT;
struct ref_push_report_options *options;
for (; ref; ref = ref->next) {
const char *msg = NULL;
const char *res;
int count = 0;
switch(ref->status) {
case REF_STATUS_NONE:
@ -86,14 +88,29 @@ static void print_helper_status(struct ref *ref)
strbuf_reset(&buf);
strbuf_addf(&buf, "%s %s", res, ref->name);
if (ref->remote_status)
msg = ref->remote_status;
if (ref->report.error_message)
msg = ref->report.error_message;
if (msg) {
strbuf_addch(&buf, ' ');
quote_two_c_style(&buf, "", msg, 0);
}
strbuf_addch(&buf, '\n');
for (options = ref->report.options; options; options = options->next) {
if (count++ > 0)
strbuf_addf(&buf, "ok %s\n", ref->name);
if (options->ref_name)
strbuf_addf(&buf, "option refname %s\n",
options->ref_name);
if (options->old_oid)
strbuf_addf(&buf, "option old-oid %s\n",
oid_to_hex(options->old_oid));
if (options->new_oid)
strbuf_addf(&buf, "option new-oid %s\n",
oid_to_hex(options->new_oid));
if (options->forced_update)
strbuf_addstr(&buf, "option forced-update\n");
}
write_or_die(1, buf.buf, buf.len);
}
strbuf_release(&buf);