mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-08 12:14:16 +00:00
Advertise and support side-band-64k when calling receive-pack
This commit is contained in:
parent
1ac10aae1d
commit
b8c325806f
@ -88,6 +88,7 @@ typedef git_pkt_data git_pkt_progress;
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
enum git_pkt_type type;
|
enum git_pkt_type type;
|
||||||
|
int len;
|
||||||
char error[GIT_FLEX_ARRAY];
|
char error[GIT_FLEX_ARRAY];
|
||||||
} git_pkt_err;
|
} git_pkt_err;
|
||||||
|
|
||||||
|
@ -122,6 +122,7 @@ static int err_pkt(git_pkt **out, const char *line, size_t len)
|
|||||||
GITERR_CHECK_ALLOC(pkt);
|
GITERR_CHECK_ALLOC(pkt);
|
||||||
|
|
||||||
pkt->type = GIT_PKT_ERR;
|
pkt->type = GIT_PKT_ERR;
|
||||||
|
pkt->len = (int)len;
|
||||||
memcpy(pkt->error, line, len);
|
memcpy(pkt->error, line, len);
|
||||||
pkt->error[len] = '\0';
|
pkt->error[len] = '\0';
|
||||||
|
|
||||||
@ -166,6 +167,25 @@ static int progress_pkt(git_pkt **out, const char *line, size_t len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sideband_error_pkt(git_pkt **out, const char *line, size_t len)
|
||||||
|
{
|
||||||
|
git_pkt_err *pkt;
|
||||||
|
|
||||||
|
line++;
|
||||||
|
len--;
|
||||||
|
pkt = git__malloc(sizeof(git_pkt_err) + len + 1);
|
||||||
|
GITERR_CHECK_ALLOC(pkt);
|
||||||
|
|
||||||
|
pkt->type = GIT_PKT_ERR;
|
||||||
|
pkt->len = (int)len;
|
||||||
|
memcpy(pkt->error, line, len);
|
||||||
|
pkt->error[len] = '\0';
|
||||||
|
|
||||||
|
*out = (git_pkt *)pkt;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse an other-ref line.
|
* Parse an other-ref line.
|
||||||
*/
|
*/
|
||||||
@ -380,6 +400,8 @@ int git_pkt_parse_line(
|
|||||||
ret = data_pkt(head, line, len);
|
ret = data_pkt(head, line, len);
|
||||||
else if (*line == GIT_SIDE_BAND_PROGRESS)
|
else if (*line == GIT_SIDE_BAND_PROGRESS)
|
||||||
ret = progress_pkt(head, line, len);
|
ret = progress_pkt(head, line, len);
|
||||||
|
else if (*line == GIT_SIDE_BAND_ERROR)
|
||||||
|
ret = sideband_error_pkt(head, line, len);
|
||||||
else if (!git__prefixcmp(line, "ACK"))
|
else if (!git__prefixcmp(line, "ACK"))
|
||||||
ret = ack_pkt(head, line, len);
|
ret = ack_pkt(head, line, len);
|
||||||
else if (!git__prefixcmp(line, "NAK"))
|
else if (!git__prefixcmp(line, "NAK"))
|
||||||
|
@ -536,7 +536,8 @@ static int gen_pktline(git_buf *buf, git_push *push)
|
|||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
++len; /* '\0' */
|
++len; /* '\0' */
|
||||||
if (push->report_status)
|
if (push->report_status)
|
||||||
len += strlen(GIT_CAP_REPORT_STATUS);
|
len += strlen(GIT_CAP_REPORT_STATUS) + 1;
|
||||||
|
len += strlen(GIT_CAP_SIDE_BAND_64K) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
git_oid_fmt(old_id, &spec->roid);
|
git_oid_fmt(old_id, &spec->roid);
|
||||||
@ -546,8 +547,13 @@ static int gen_pktline(git_buf *buf, git_push *push)
|
|||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
git_buf_putc(buf, '\0');
|
git_buf_putc(buf, '\0');
|
||||||
if (push->report_status)
|
/* Core git always starts their capabilities string with a space */
|
||||||
|
if (push->report_status) {
|
||||||
|
git_buf_putc(buf, ' ');
|
||||||
git_buf_printf(buf, GIT_CAP_REPORT_STATUS);
|
git_buf_printf(buf, GIT_CAP_REPORT_STATUS);
|
||||||
|
}
|
||||||
|
git_buf_putc(buf, ' ');
|
||||||
|
git_buf_printf(buf, GIT_CAP_SIDE_BAND_64K);
|
||||||
}
|
}
|
||||||
|
|
||||||
git_buf_putc(buf, '\n');
|
git_buf_putc(buf, '\n');
|
||||||
@ -557,6 +563,74 @@ static int gen_pktline(git_buf *buf, git_push *push)
|
|||||||
return git_buf_oom(buf) ? -1 : 0;
|
return git_buf_oom(buf) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int add_push_report_pkt(git_push *push, git_pkt *pkt)
|
||||||
|
{
|
||||||
|
push_status *status;
|
||||||
|
|
||||||
|
switch (pkt->type) {
|
||||||
|
case GIT_PKT_OK:
|
||||||
|
status = git__malloc(sizeof(push_status));
|
||||||
|
GITERR_CHECK_ALLOC(status);
|
||||||
|
status->msg = NULL;
|
||||||
|
status->ref = git__strdup(((git_pkt_ok *)pkt)->ref);
|
||||||
|
if (!status->ref ||
|
||||||
|
git_vector_insert(&push->status, status) < 0) {
|
||||||
|
git_push_status_free(status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GIT_PKT_NG:
|
||||||
|
status = git__calloc(sizeof(push_status), 1);
|
||||||
|
GITERR_CHECK_ALLOC(status);
|
||||||
|
status->ref = git__strdup(((git_pkt_ng *)pkt)->ref);
|
||||||
|
status->msg = git__strdup(((git_pkt_ng *)pkt)->msg);
|
||||||
|
if (!status->ref || !status->msg ||
|
||||||
|
git_vector_insert(&push->status, status) < 0) {
|
||||||
|
git_push_status_free(status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GIT_PKT_UNPACK:
|
||||||
|
push->unpack_ok = ((git_pkt_unpack *)pkt)->unpack_ok;
|
||||||
|
break;
|
||||||
|
case GIT_PKT_FLUSH:
|
||||||
|
return GIT_ITEROVER;
|
||||||
|
default:
|
||||||
|
giterr_set(GITERR_NET, "report-status: protocol error");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt)
|
||||||
|
{
|
||||||
|
git_pkt *pkt;
|
||||||
|
const char *line = data_pkt->data, *line_end;
|
||||||
|
size_t line_len = data_pkt->len;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
while (line_len > 0) {
|
||||||
|
error = git_pkt_parse_line(&pkt, line, &line_end, line_len);
|
||||||
|
|
||||||
|
if (error < 0)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
/* Advance in the buffer */
|
||||||
|
line_len -= (line_end - line);
|
||||||
|
line = line_end;
|
||||||
|
|
||||||
|
error = add_push_report_pkt(push, pkt);
|
||||||
|
|
||||||
|
git_pkt_free(pkt);
|
||||||
|
|
||||||
|
if (error < 0 && GIT_ITEROVER != error)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int parse_report(gitno_buffer *buf, git_push *push)
|
static int parse_report(gitno_buffer *buf, git_push *push)
|
||||||
{
|
{
|
||||||
git_pkt *pkt;
|
git_pkt *pkt;
|
||||||
@ -586,46 +660,33 @@ static int parse_report(gitno_buffer *buf, git_push *push)
|
|||||||
|
|
||||||
gitno_consume(buf, line_end);
|
gitno_consume(buf, line_end);
|
||||||
|
|
||||||
if (pkt->type == GIT_PKT_OK) {
|
error = 0;
|
||||||
push_status *status = git__malloc(sizeof(push_status));
|
|
||||||
GITERR_CHECK_ALLOC(status);
|
|
||||||
status->ref = git__strdup(((git_pkt_ok *)pkt)->ref);
|
|
||||||
status->msg = NULL;
|
|
||||||
git_pkt_free(pkt);
|
|
||||||
if (git_vector_insert(&push->status, status) < 0) {
|
|
||||||
git__free(status);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pkt->type == GIT_PKT_NG) {
|
switch (pkt->type) {
|
||||||
push_status *status = git__malloc(sizeof(push_status));
|
case GIT_PKT_DATA:
|
||||||
GITERR_CHECK_ALLOC(status);
|
/* This is a sideband packet which contains other packets */
|
||||||
status->ref = git__strdup(((git_pkt_ng *)pkt)->ref);
|
error = add_push_report_sideband_pkt(push, (git_pkt_data *)pkt);
|
||||||
status->msg = git__strdup(((git_pkt_ng *)pkt)->msg);
|
break;
|
||||||
git_pkt_free(pkt);
|
case GIT_PKT_ERR:
|
||||||
if (git_vector_insert(&push->status, status) < 0) {
|
giterr_set(GITERR_NET, "report-status: Error reported: %s",
|
||||||
git__free(status);
|
((git_pkt_err *)pkt)->error);
|
||||||
return -1;
|
error = -1;
|
||||||
}
|
break;
|
||||||
continue;
|
case GIT_PKT_PROGRESS:
|
||||||
}
|
break;
|
||||||
|
default:
|
||||||
if (pkt->type == GIT_PKT_UNPACK) {
|
error = add_push_report_pkt(push, pkt);
|
||||||
push->unpack_ok = ((git_pkt_unpack *)pkt)->unpack_ok;
|
break;
|
||||||
git_pkt_free(pkt);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pkt->type == GIT_PKT_FLUSH) {
|
|
||||||
git_pkt_free(pkt);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
git_pkt_free(pkt);
|
git_pkt_free(pkt);
|
||||||
giterr_set(GITERR_NET, "report-status: protocol error");
|
|
||||||
return -1;
|
/* add_push_report_pkt returns GIT_ITEROVER when it receives a flush */
|
||||||
|
if (GIT_ITEROVER == error)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (error < 0)
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user