Commit 0437d991 by Carlos Martín Nieto Committed by Vicent Marti

Use common capabilities

Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
parent 48a65a07
...@@ -269,13 +269,35 @@ int git_pkt_send_flush(int s) ...@@ -269,13 +269,35 @@ int git_pkt_send_flush(int s)
return gitno_send(s, flush, STRLEN(flush), 0); return gitno_send(s, flush, STRLEN(flush), 0);
} }
static int send_want_with_caps(git_remote_head *head, git_transport_caps *caps, int fd)
{
char capstr[20]; /* Longer than we need */
char oid[GIT_OID_HEXSZ +1] = {0}, *cmd;
int error, len;
if (caps->ofs_delta)
strcpy(capstr, GIT_CAP_OFS_DELTA);
len = STRLEN("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + strlen(capstr) + 1 /* LF */;
cmd = git__malloc(len + 1);
if (cmd == NULL)
return GIT_ENOMEM;
git_oid_fmt(oid, &head->oid);
memset(cmd, 0x0, len + 1);
snprintf(cmd, len + 1, "%04xwant %s%c%s\n", len, oid, 0, capstr);
error = gitno_send(fd, cmd, len, 0);
free(cmd);
return error;
}
/* /*
* All "want" packets have the same length and format, so what we do * All "want" packets have the same length and format, so what we do
* is overwrite the OID each time. * is overwrite the OID each time.
*/ */
#define WANT_PREFIX "0032want " #define WANT_PREFIX "0032want "
int git_pkt_send_wants(git_headarray *refs, int fd) int git_pkt_send_wants(git_headarray *refs, git_transport_caps *caps, int fd)
{ {
unsigned int i; unsigned int i;
int ret = GIT_SUCCESS; int ret = GIT_SUCCESS;
...@@ -286,10 +308,18 @@ int git_pkt_send_wants(git_headarray *refs, int fd) ...@@ -286,10 +308,18 @@ int git_pkt_send_wants(git_headarray *refs, int fd)
buf[sizeof(buf) - 2] = '\n'; buf[sizeof(buf) - 2] = '\n';
buf[sizeof(buf) - 1] = '\0'; buf[sizeof(buf) - 1] = '\0';
for (i = 0; i < refs->len; ++i) { if (refs->len > 0 && caps->common) {
/* Some capabilities are active, so we need to send what we support */
send_want_with_caps(refs->heads[0], caps, fd);
i = 1;
} else {
i = 0;
}
for (; i < refs->len; ++i) {
head = refs->heads[i]; head = refs->heads[i];
if (head->type != GIT_WHN_WANT) if (head->type != GIT_WHN_WANT)
continue; continue; /* FIXME: return? refs shouldn't have any other type */
git_oid_fmt(buf + STRLEN(WANT_PREFIX), &head->oid); git_oid_fmt(buf + STRLEN(WANT_PREFIX), &head->oid);
gitno_send(fd, buf, STRLEN(buf), 0); gitno_send(fd, buf, STRLEN(buf), 0);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define INCLUDE_pkt_h__ #define INCLUDE_pkt_h__
#include "common.h" #include "common.h"
#include "transport.h"
#include "git2/net.h" #include "git2/net.h"
enum git_pkt_type { enum git_pkt_type {
...@@ -76,7 +77,7 @@ typedef struct { ...@@ -76,7 +77,7 @@ typedef struct {
int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t len); int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t len);
int git_pkt_send_flush(int s); int git_pkt_send_flush(int s);
int git_pkt_send_done(int s); int git_pkt_send_done(int s);
int git_pkt_send_wants(git_headarray *refs, int fd); int git_pkt_send_wants(git_headarray *refs, git_transport_caps *caps, int fd);
int git_pkt_send_have(git_oid *oid, int fd); int git_pkt_send_have(git_oid *oid, int fd);
void git_pkt_free(git_pkt *pkt); void git_pkt_free(git_pkt *pkt);
......
...@@ -5,6 +5,13 @@ ...@@ -5,6 +5,13 @@
#include "git2/net.h" #include "git2/net.h"
#include "vector.h" #include "vector.h"
#define GIT_CAP_OFS_DELTA "ofs-delta"
typedef struct git_transport_caps {
int common:1,
ofs_delta:1;
} git_transport_caps;
/* /*
* A day in the life of a network operation * A day in the life of a network operation
* ======================================== * ========================================
......
...@@ -41,6 +41,7 @@ typedef struct { ...@@ -41,6 +41,7 @@ typedef struct {
int socket; int socket;
git_vector refs; git_vector refs;
git_remote_head **heads; git_remote_head **heads;
git_transport_caps caps;
} transport_git; } transport_git;
/* /*
...@@ -218,6 +219,36 @@ static int store_refs(transport_git *t) ...@@ -218,6 +219,36 @@ static int store_refs(transport_git *t)
return error; return error;
} }
static int detect_caps(transport_git *t)
{
git_vector *refs = &t->refs;
git_pkt_ref *pkt;
git_transport_caps *caps = &t->caps;
const char *ptr;
pkt = git_vector_get(refs, 0);
/* No refs or capabilites, odd but not a problem */
if (pkt == NULL || pkt->capabilities == NULL)
return GIT_SUCCESS;
ptr = pkt->capabilities;
while (ptr != NULL && *ptr != '\0') {
if (*ptr == ' ')
ptr++;
if(!git__prefixcmp(ptr, GIT_CAP_OFS_DELTA)) {
caps->common = caps->ofs_delta = 1;
ptr += STRLEN(GIT_CAP_OFS_DELTA);
continue;
}
/* We don't know this capability, so skip it */
ptr = strchr(ptr, ' ');
}
return GIT_SUCCESS;
}
/* /*
* Since this is a network connection, we need to parse and store the * Since this is a network connection, we need to parse and store the
* pkt-lines at this stage and keep them there. * pkt-lines at this stage and keep them there.
...@@ -242,6 +273,10 @@ static int git_connect(git_transport *transport, int direction) ...@@ -242,6 +273,10 @@ static int git_connect(git_transport *transport, int direction)
t->parent.connected = 1; t->parent.connected = 1;
error = store_refs(t); error = store_refs(t);
if (error < GIT_SUCCESS)
return error;
error = detect_caps(t);
cleanup: cleanup:
if (error < GIT_SUCCESS) { if (error < GIT_SUCCESS) {
...@@ -280,7 +315,7 @@ static int git_send_wants(git_transport *transport, git_headarray *array) ...@@ -280,7 +315,7 @@ static int git_send_wants(git_transport *transport, git_headarray *array)
{ {
transport_git *t = (transport_git *) transport; transport_git *t = (transport_git *) transport;
return git_pkt_send_wants(array, t->socket); return git_pkt_send_wants(array, &t->caps, t->socket);
} }
static int git_send_have(git_transport *transport, git_oid *oid) static int git_send_have(git_transport *transport, git_oid *oid)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment