summaryrefslogtreecommitdiff
path: root/src/transport_git.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport_git.c')
-rw-r--r--src/transport_git.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/src/transport_git.c b/src/transport_git.c
index 46678a28e..4a10f17cd 100644
--- a/src/transport_git.c
+++ b/src/transport_git.c
@@ -41,6 +41,7 @@ typedef struct {
int socket;
git_vector refs;
git_remote_head **heads;
+ git_transport_caps caps;
} transport_git;
/*
@@ -218,6 +219,36 @@ static int store_refs(transport_git *t)
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
* pkt-lines at this stage and keep them there.
@@ -242,6 +273,10 @@ static int git_connect(git_transport *transport, int direction)
t->parent.connected = 1;
error = store_refs(t);
+ if (error < GIT_SUCCESS)
+ return error;
+
+ error = detect_caps(t);
cleanup:
if (error < GIT_SUCCESS) {
@@ -280,7 +315,7 @@ static int git_send_wants(git_transport *transport, git_headarray *array)
{
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)