summaryrefslogtreecommitdiff
path: root/src/transports/smart_pkt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transports/smart_pkt.c')
-rw-r--r--src/transports/smart_pkt.c90
1 files changed, 83 insertions, 7 deletions
diff --git a/src/transports/smart_pkt.c b/src/transports/smart_pkt.c
index 56b680d28..6a1e842ee 100644
--- a/src/transports/smart_pkt.c
+++ b/src/transports/smart_pkt.c
@@ -363,6 +363,50 @@ static int unpack_pkt(git_pkt **out, const char *line, size_t len)
return 0;
}
+static int shallow_pkt(git_pkt **out, const char *line, size_t len)
+{
+ git_pkt_shallow *pkt;
+
+ pkt = git__calloc(1, sizeof(git_pkt_shallow));
+ GIT_ERROR_CHECK_ALLOC(pkt);
+
+ pkt->type = GIT_PKT_SHALLOW;
+ line += 7;
+ len -= 7;
+
+ if (len >= GIT_OID_HEXSZ) {
+ git_oid_fromstr(&pkt->oid, line + 1);
+ line += GIT_OID_HEXSZ + 1;
+ len -= GIT_OID_HEXSZ + 1;
+ }
+
+ *out = (git_pkt *) pkt;
+
+ return 0;
+}
+
+static int unshallow_pkt(git_pkt **out, const char *line, size_t len)
+{
+ git_pkt_shallow *pkt;
+
+ pkt = git__calloc(1, sizeof(git_pkt_shallow));
+ GIT_ERROR_CHECK_ALLOC(pkt);
+
+ pkt->type = GIT_PKT_UNSHALLOW;
+ line += 9;
+ len -= 9;
+
+ if (len >= GIT_OID_HEXSZ) {
+ git_oid_fromstr(&pkt->oid, line + 1);
+ line += GIT_OID_HEXSZ + 1;
+ len -= GIT_OID_HEXSZ + 1;
+ }
+
+ *out = (git_pkt *) pkt;
+
+ return 0;
+}
+
static int parse_len(size_t *out, const char *line, size_t linelen)
{
char num[PKT_LEN_SIZE + 1];
@@ -489,6 +533,10 @@ int git_pkt_parse_line(
error = ng_pkt(pkt, line, len);
else if (!git__prefixncmp(line, len, "unpack"))
error = unpack_pkt(pkt, line, len);
+ else if (!git__prefixcmp(line, "shallow"))
+ error = shallow_pkt(pkt, line, len);
+ else if (!git__prefixcmp(line, "unshallow"))
+ error = unshallow_pkt(pkt, line, len);
else
error = ref_pkt(pkt, line, len);
@@ -554,6 +602,9 @@ static int buffer_want_with_caps(const git_remote_head *head, transport_smart_ca
if (caps->ofs_delta)
git_buf_puts(&str, GIT_CAP_OFS_DELTA " ");
+ if (caps->shallow)
+ git_buf_puts(&str, GIT_CAP_SHALLOW " ");
+
if (git_buf_oom(&str))
return -1;
@@ -583,8 +634,7 @@ static int buffer_want_with_caps(const git_remote_head *head, transport_smart_ca
*/
int git_pkt_buffer_wants(
- const git_remote_head * const *refs,
- size_t count,
+ const git_fetch_negotiation *wants,
transport_smart_caps *caps,
git_buf *buf)
{
@@ -592,22 +642,22 @@ int git_pkt_buffer_wants(
const git_remote_head *head;
if (caps->common) {
- for (; i < count; ++i) {
- head = refs[i];
+ for (; i < wants->count; ++i) {
+ head = wants->refs[i];
if (!head->local)
break;
}
- if (buffer_want_with_caps(refs[i], caps, buf) < 0)
+ if (buffer_want_with_caps(wants->refs[i], caps, buf) < 0)
return -1;
i++;
}
- for (; i < count; ++i) {
+ for (; i < wants->count; ++i) {
char oid[GIT_OID_HEXSZ];
- head = refs[i];
+ head = wants->refs[i];
if (head->local)
continue;
@@ -619,6 +669,32 @@ int git_pkt_buffer_wants(
return -1;
}
+ /* Tell the server about our shallow objects */
+ for (i = 0; i < git_shallowarray_count(wants->shallow_roots); i++) {
+ char oid[GIT_OID_HEXSZ];
+ git_buf shallow_buf = GIT_BUF_INIT;
+
+ git_oid_fmt(oid, git_shallowarray_get(wants->shallow_roots, i));
+ git_buf_puts(&shallow_buf, "shallow ");
+ git_buf_put(&shallow_buf, oid, GIT_OID_HEXSZ);
+ git_buf_putc(&shallow_buf, '\n');
+
+ git_buf_printf(buf, "%04x%s", (unsigned int)git_buf_len(&shallow_buf) + 4, git_buf_cstr(&shallow_buf));
+
+ if (git_buf_oom(buf))
+ return -1;
+ }
+
+ if (wants->depth > 0) {
+ git_buf deepen_buf = GIT_BUF_INIT;
+
+ git_buf_printf(&deepen_buf, "deepen %d\n", wants->depth);
+ git_buf_printf(buf,"%04x%s", (unsigned int)git_buf_len(&deepen_buf) + 4, git_buf_cstr(&deepen_buf));
+
+ if (git_buf_oom(buf))
+ return -1;
+ }
+
return git_pkt_buffer_flush(buf);
}