transport-helper: factor out push_update_refs_status

The update ref status part of push is useful for the export command
as well, factor it out into it's own function.

Also factor out push_update_ref_status to avoid a long loop without
an explicit condition with a non-trivial body.

Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Sverre Rabbelier 2011-07-16 15:03:34 +02:00 коммит произвёл Junio C Hamano
Родитель 82670a5cb5
Коммит d2e73c6f2a
1 изменённых файлов: 84 добавлений и 69 удалений

Просмотреть файл

@ -559,6 +559,88 @@ static int fetch(struct transport *transport,
return -1;
}
static void push_update_ref_status(struct strbuf *buf,
struct ref **ref,
struct ref *remote_refs)
{
char *refname, *msg;
int status;
if (!prefixcmp(buf->buf, "ok ")) {
status = REF_STATUS_OK;
refname = buf->buf + 3;
} else if (!prefixcmp(buf->buf, "error ")) {
status = REF_STATUS_REMOTE_REJECT;
refname = buf->buf + 6;
} else
die("expected ok/error, helper said '%s'\n", buf->buf);
msg = strchr(refname, ' ');
if (msg) {
struct strbuf msg_buf = STRBUF_INIT;
const char *end;
*msg++ = '\0';
if (!unquote_c_style(&msg_buf, msg, &end))
msg = strbuf_detach(&msg_buf, NULL);
else
msg = xstrdup(msg);
strbuf_release(&msg_buf);
if (!strcmp(msg, "no match")) {
status = REF_STATUS_NONE;
free(msg);
msg = NULL;
}
else if (!strcmp(msg, "up to date")) {
status = REF_STATUS_UPTODATE;
free(msg);
msg = NULL;
}
else if (!strcmp(msg, "non-fast forward")) {
status = REF_STATUS_REJECT_NONFASTFORWARD;
free(msg);
msg = NULL;
}
}
if (*ref)
*ref = find_ref_by_name(*ref, refname);
if (!*ref)
*ref = find_ref_by_name(remote_refs, refname);
if (!*ref) {
warning("helper reported unexpected status of %s", refname);
return;
}
if ((*ref)->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'.
*/
if (status == REF_STATUS_NONE)
return;
}
(*ref)->status = status;
(*ref)->remote_status = msg;
}
static void push_update_refs_status(struct helper_data *data,
struct ref *remote_refs)
{
struct strbuf buf = STRBUF_INIT;
struct ref *ref = remote_refs;
for (;;) {
recvline(data, &buf);
if (!buf.len)
break;
push_update_ref_status(&buf, &ref, remote_refs);
}
strbuf_release(&buf);
}
static int push_refs_with_push(struct transport *transport,
struct ref *remote_refs, int flags)
{
@ -613,76 +695,9 @@ static int push_refs_with_push(struct transport *transport,
strbuf_addch(&buf, '\n');
sendline(data, &buf);
ref = remote_refs;
while (1) {
char *refname, *msg;
int status;
recvline(data, &buf);
if (!buf.len)
break;
if (!prefixcmp(buf.buf, "ok ")) {
status = REF_STATUS_OK;
refname = buf.buf + 3;
} else if (!prefixcmp(buf.buf, "error ")) {
status = REF_STATUS_REMOTE_REJECT;
refname = buf.buf + 6;
} else
die("expected ok/error, helper said '%s'\n", buf.buf);
msg = strchr(refname, ' ');
if (msg) {
struct strbuf msg_buf = STRBUF_INIT;
const char *end;
*msg++ = '\0';
if (!unquote_c_style(&msg_buf, msg, &end))
msg = strbuf_detach(&msg_buf, NULL);
else
msg = xstrdup(msg);
strbuf_release(&msg_buf);
if (!strcmp(msg, "no match")) {
status = REF_STATUS_NONE;
free(msg);
msg = NULL;
}
else if (!strcmp(msg, "up to date")) {
status = REF_STATUS_UPTODATE;
free(msg);
msg = NULL;
}
else if (!strcmp(msg, "non-fast forward")) {
status = REF_STATUS_REJECT_NONFASTFORWARD;
free(msg);
msg = NULL;
}
}
if (ref)
ref = find_ref_by_name(ref, refname);
if (!ref)
ref = find_ref_by_name(remote_refs, refname);
if (!ref) {
warning("helper reported unexpected status of %s", refname);
continue;
}
if (ref->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'.
*/
if (status == REF_STATUS_NONE)
continue;
}
ref->status = status;
ref->remote_status = msg;
}
strbuf_release(&buf);
push_update_refs_status(data, remote_refs);
return 0;
}