diff options
Diffstat (limited to 'src/libgit2/transports/smart_pkt.c')
-rw-r--r-- | src/libgit2/transports/smart_pkt.c | 96 |
1 files changed, 88 insertions, 8 deletions
diff --git a/src/libgit2/transports/smart_pkt.c b/src/libgit2/transports/smart_pkt.c index 5fce42175..ec9764a87 100644 --- a/src/libgit2/transports/smart_pkt.c +++ b/src/libgit2/transports/smart_pkt.c @@ -436,6 +436,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_SHA1_HEXSIZE) { + git_oid__fromstr(&pkt->oid, line + 1, GIT_OID_SHA1); + line += GIT_OID_SHA1_HEXSIZE + 1; + len -= GIT_OID_SHA1_HEXSIZE + 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_SHA1_HEXSIZE) { + git_oid__fromstr(&pkt->oid, line + 1, GIT_OID_SHA1); + line += GIT_OID_SHA1_HEXSIZE + 1; + len -= GIT_OID_SHA1_HEXSIZE + 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]; @@ -566,6 +610,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, data); @@ -638,6 +686,9 @@ static int buffer_want_with_caps( if (caps->ofs_delta) git_str_puts(&str, GIT_CAP_OFS_DELTA " "); + if (caps->shallow) + git_str_puts(&str, GIT_CAP_SHALLOW " "); + if (git_str_oom(&str)) return -1; @@ -668,8 +719,7 @@ static int buffer_want_with_caps( */ int git_pkt_buffer_wants( - const git_remote_head * const *refs, - size_t count, + const git_fetch_negotiation *wants, transport_smart_caps *caps, git_str *buf) { @@ -679,7 +729,7 @@ int git_pkt_buffer_wants( size_t oid_hexsize, want_len, i = 0; #ifdef GIT_EXPERIMENTAL_SHA256 - oid_type = count > 0 ? refs[0]->oid.type : GIT_OID_SHA1; + oid_type = wants->count > 0 ? wants->refs[0]->oid.type : GIT_OID_SHA1; #else oid_type = GIT_OID_SHA1; #endif @@ -690,20 +740,20 @@ int git_pkt_buffer_wants( oid_hexsize + 1 /* LF */; 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, oid_type, buf) < 0) + if (buffer_want_with_caps(wants->refs[i], caps, oid_type, buf) < 0) return -1; i++; } - for (; i < count; ++i) { - head = refs[i]; + for (; i < wants->count; ++i) { + head = wants->refs[i]; if (head->local) continue; @@ -718,6 +768,36 @@ 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_SHA1_HEXSIZE]; + git_str shallow_buf = GIT_STR_INIT; + + git_oid_fmt(oid, git_shallowarray_get(wants->shallow_roots, i)); + git_str_puts(&shallow_buf, "shallow "); + git_str_put(&shallow_buf, oid, GIT_OID_SHA1_HEXSIZE); + git_str_putc(&shallow_buf, '\n'); + + git_str_printf(buf, "%04x%s", (unsigned int)git_str_len(&shallow_buf) + 4, git_str_cstr(&shallow_buf)); + + git_str_dispose(&shallow_buf); + + if (git_str_oom(buf)) + return -1; + } + + if (wants->depth > 0) { + git_str deepen_buf = GIT_STR_INIT; + + git_str_printf(&deepen_buf, "deepen %d\n", wants->depth); + git_str_printf(buf,"%04x%s", (unsigned int)git_str_len(&deepen_buf) + 4, git_str_cstr(&deepen_buf)); + + git_str_dispose(&deepen_buf); + + if (git_str_oom(buf)) + return -1; + } + return git_pkt_buffer_flush(buf); } |