mirror of
https://github.com/git/git.git
synced 2025-12-12 20:36:24 +01:00
Merge branch 'jx/proc-receive-hook'
"git receive-pack" that accepts requests by "git push" learned to outsource most of the ref updates to the new "proc-receive" hook. * jx/proc-receive-hook: doc: add documentation for the proc-receive hook transport: parse report options for tracking refs t5411: test updates of remote-tracking branches receive-pack: new config receive.procReceiveRefs doc: add document for capability report-status-v2 New capability "report-status-v2" for git-push receive-pack: feed report options to post-receive receive-pack: add new proc-receive hook t5411: add basic test cases for proc-receive hook transport: not report a non-head push as a branch
This commit is contained in:
@@ -723,13 +723,61 @@ static int fetch(struct transport *transport,
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct push_update_ref_state {
|
||||
struct ref *hint;
|
||||
struct ref_push_report *report;
|
||||
int new_report;
|
||||
};
|
||||
|
||||
static int push_update_ref_status(struct strbuf *buf,
|
||||
struct ref **ref,
|
||||
struct push_update_ref_state *state,
|
||||
struct ref *remote_refs)
|
||||
{
|
||||
char *refname, *msg;
|
||||
int status, forced = 0;
|
||||
|
||||
if (starts_with(buf->buf, "option ")) {
|
||||
struct object_id old_oid, new_oid;
|
||||
const char *key, *val;
|
||||
char *p;
|
||||
|
||||
if (!state->hint || !(state->report || state->new_report))
|
||||
die(_("'option' without a matching 'ok/error' directive"));
|
||||
if (state->new_report) {
|
||||
if (!state->hint->report) {
|
||||
state->hint->report = xcalloc(1, sizeof(struct ref_push_report));
|
||||
state->report = state->hint->report;
|
||||
} else {
|
||||
state->report = state->hint->report;
|
||||
while (state->report->next)
|
||||
state->report = state->report->next;
|
||||
state->report->next = xcalloc(1, sizeof(struct ref_push_report));
|
||||
state->report = state->report->next;
|
||||
}
|
||||
state->new_report = 0;
|
||||
}
|
||||
key = buf->buf + 7;
|
||||
p = strchr(key, ' ');
|
||||
if (p)
|
||||
*p++ = '\0';
|
||||
val = p;
|
||||
if (!strcmp(key, "refname"))
|
||||
state->report->ref_name = xstrdup_or_null(val);
|
||||
else if (!strcmp(key, "old-oid") && val &&
|
||||
!parse_oid_hex(val, &old_oid, &val))
|
||||
state->report->old_oid = oiddup(&old_oid);
|
||||
else if (!strcmp(key, "new-oid") && val &&
|
||||
!parse_oid_hex(val, &new_oid, &val))
|
||||
state->report->new_oid = oiddup(&new_oid);
|
||||
else if (!strcmp(key, "forced-update"))
|
||||
state->report->forced_update = 1;
|
||||
/* Not update remote namespace again. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
state->report = NULL;
|
||||
state->new_report = 0;
|
||||
|
||||
if (starts_with(buf->buf, "ok ")) {
|
||||
status = REF_STATUS_OK;
|
||||
refname = buf->buf + 3;
|
||||
@@ -785,16 +833,16 @@ static int push_update_ref_status(struct strbuf *buf,
|
||||
}
|
||||
}
|
||||
|
||||
if (*ref)
|
||||
*ref = find_ref_by_name(*ref, refname);
|
||||
if (!*ref)
|
||||
*ref = find_ref_by_name(remote_refs, refname);
|
||||
if (!*ref) {
|
||||
if (state->hint)
|
||||
state->hint = find_ref_by_name(state->hint, refname);
|
||||
if (!state->hint)
|
||||
state->hint = find_ref_by_name(remote_refs, refname);
|
||||
if (!state->hint) {
|
||||
warning(_("helper reported unexpected status of %s"), refname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((*ref)->status != REF_STATUS_NONE) {
|
||||
if (state->hint->status != REF_STATUS_NONE) {
|
||||
/*
|
||||
* Earlier, the ref was marked not to be pushed, so ignore the ref
|
||||
* status reported by the remote helper if the latter is 'no match'.
|
||||
@@ -803,9 +851,11 @@ static int push_update_ref_status(struct strbuf *buf,
|
||||
return 1;
|
||||
}
|
||||
|
||||
(*ref)->status = status;
|
||||
(*ref)->forced_update |= forced;
|
||||
(*ref)->remote_status = msg;
|
||||
if (status == REF_STATUS_OK)
|
||||
state->new_report = 1;
|
||||
state->hint->status = status;
|
||||
state->hint->forced_update |= forced;
|
||||
state->hint->remote_status = msg;
|
||||
return !(status == REF_STATUS_OK);
|
||||
}
|
||||
|
||||
@@ -813,37 +863,57 @@ static int push_update_refs_status(struct helper_data *data,
|
||||
struct ref *remote_refs,
|
||||
int flags)
|
||||
{
|
||||
struct ref *ref;
|
||||
struct ref_push_report *report;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
struct ref *ref = remote_refs;
|
||||
int ret = 0;
|
||||
struct push_update_ref_state state = { remote_refs, NULL, 0 };
|
||||
|
||||
for (;;) {
|
||||
char *private;
|
||||
|
||||
if (recvline(data, &buf)) {
|
||||
ret = 1;
|
||||
break;
|
||||
strbuf_release(&buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!buf.len)
|
||||
break;
|
||||
|
||||
if (push_update_ref_status(&buf, &ref, remote_refs))
|
||||
continue;
|
||||
|
||||
if (flags & TRANSPORT_PUSH_DRY_RUN || !data->rs.nr || data->no_private_update)
|
||||
continue;
|
||||
|
||||
/* propagate back the update to the remote namespace */
|
||||
private = apply_refspecs(&data->rs, ref->name);
|
||||
if (!private)
|
||||
continue;
|
||||
update_ref("update by helper", private, &ref->new_oid, NULL,
|
||||
0, 0);
|
||||
free(private);
|
||||
push_update_ref_status(&buf, &state, remote_refs);
|
||||
}
|
||||
strbuf_release(&buf);
|
||||
return ret;
|
||||
|
||||
if (flags & TRANSPORT_PUSH_DRY_RUN || !data->rs.nr || data->no_private_update)
|
||||
return 0;
|
||||
|
||||
/* propagate back the update to the remote namespace */
|
||||
for (ref = remote_refs; ref; ref = ref->next) {
|
||||
char *private;
|
||||
|
||||
if (ref->status != REF_STATUS_OK)
|
||||
continue;
|
||||
|
||||
if (!ref->report) {
|
||||
private = apply_refspecs(&data->rs, ref->name);
|
||||
if (!private)
|
||||
continue;
|
||||
update_ref("update by helper", private, &(ref->new_oid),
|
||||
NULL, 0, 0);
|
||||
free(private);
|
||||
} else {
|
||||
for (report = ref->report; report; report = report->next) {
|
||||
private = apply_refspecs(&data->rs,
|
||||
report->ref_name
|
||||
? report->ref_name
|
||||
: ref->name);
|
||||
if (!private)
|
||||
continue;
|
||||
update_ref("update by helper", private,
|
||||
report->new_oid
|
||||
? report->new_oid
|
||||
: &(ref->new_oid),
|
||||
NULL, 0, 0);
|
||||
free(private);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_common_push_options(struct transport *transport,
|
||||
|
||||
Reference in New Issue
Block a user