summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2014-05-27 17:11:20 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2014-05-27 17:11:20 +0200
commit16b20526e1580f50b29f0dae87a30ebefe0a3c89 (patch)
treeb3af565a38cde5bf1e7fb833a93bf42fabbfc0d7
parentc83979ee2473f5210b8f7f65080ab948e219728d (diff)
downloadlibgit2-16b20526e1580f50b29f0dae87a30ebefe0a3c89.tar.gz
smart: add a pkt type for negotiation
This lets us model the have/want lines from the client.
-rw-r--r--src/transports/smart.h7
-rw-r--r--src/transports/smart_pkt.c27
2 files changed, 34 insertions, 0 deletions
diff --git a/src/transports/smart.h b/src/transports/smart.h
index 82144c582..36a6b178b 100644
--- a/src/transports/smart.h
+++ b/src/transports/smart.h
@@ -13,6 +13,7 @@
#include "netops.h"
#include "buffer.h"
#include "push.h"
+#include "oid.h"
#define GIT_SIDE_BAND_DATA 1
#define GIT_SIDE_BAND_PROGRESS 2
@@ -34,6 +35,7 @@ enum git_pkt_type {
GIT_PKT_FLUSH,
GIT_PKT_REF,
GIT_PKT_HAVE,
+ GIT_PKT_WANT,
GIT_PKT_ACK,
GIT_PKT_NAK,
GIT_PKT_PACK,
@@ -129,6 +131,11 @@ typedef struct {
char path[GIT_FLEX_ARRAY];
} git_pkt_request;
+typedef struct {
+ enum git_pkt_type type;
+ git_oid id;
+} git_pkt_have_want;
+
typedef struct transport_smart_caps {
int common:1,
ofs_delta:1,
diff --git a/src/transports/smart_pkt.c b/src/transports/smart_pkt.c
index 418457da0..2081f4ad5 100644
--- a/src/transports/smart_pkt.c
+++ b/src/transports/smart_pkt.c
@@ -351,6 +351,29 @@ static int request_pkt(git_pkt **out, const char *line, size_t len)
return 0;
}
+static int have_want_pkt(git_pkt **out, enum git_pkt_type type, const char *line, size_t len)
+{
+ git_pkt_have_want *pkt;
+ size_t min_len;
+
+ min_len = 5 /* 'have ' */ + GIT_OID_HEXSZ;
+
+ if (len < min_len) {
+ giterr_set(GITERR_NET, "have/want pkt too short");
+ return -1;
+ }
+
+ pkt = git__malloc(sizeof(*pkt));
+ GITERR_CHECK_ALLOC(pkt);
+
+ line += 5;
+ pkt->type = type;
+ git_oid_fromstr(&pkt->id, line);
+
+ *out = (git_pkt *) pkt;
+ return 0;
+}
+
static int32_t parse_len(const char *line)
{
char num[PKT_LEN_SIZE + 1];
@@ -456,6 +479,10 @@ int git_pkt_parse_line(
ret = ng_pkt(head, line, len);
else if (!git__prefixcmp(line, "unpack"))
ret = unpack_pkt(head, line, len);
+ else if (!git__prefixcmp(line, "have"))
+ ret = have_want_pkt(head, GIT_PKT_HAVE, line, len);
+ else if (!git__prefixcmp(line, "want"))
+ ret = have_want_pkt(head, GIT_PKT_WANT, line, len);
else if (!git__prefixcmp(line, "git-upload-pack"))
ret = request_pkt(head, line, len);
else if (!git__prefixcmp(line, "git-receive-pack"))