Enable shallow clones and deepen requests using protocol version 2 if
the server 'fetch' command supports the 'shallow' feature.
Signed-off-by: Brandon Williams
---
connect.c| 22 +++
connect.h| 2 ++
fetch-pack.c | 69 +++-
3 files changed, 92 insertions(+), 1 deletion(-)
diff --git a/connect.c b/connect.c
index 7cb1f1df7..9577528f3 100644
--- a/connect.c
+++ b/connect.c
@@ -82,6 +82,28 @@ int server_supports_v2(const char *c, int die_on_error)
return 0;
}
+int server_supports_feature(const char *c, const char *feature,
+ int die_on_error)
+{
+ int i;
+
+ for (i = 0; i < server_capabilities_v2.argc; i++) {
+ const char *out;
+ if (skip_prefix(server_capabilities_v2.argv[i], c, ) &&
+ (!*out || *(out++) == '=')) {
+ if (parse_feature_request(out, feature))
+ return 1;
+ else
+ break;
+ }
+ }
+
+ if (die_on_error)
+ die("server doesn't support feature '%s'", feature);
+
+ return 0;
+}
+
static void process_capabilities_v2(struct packet_reader *reader)
{
while (packet_reader_read(reader) == PACKET_READ_NORMAL)
diff --git a/connect.h b/connect.h
index 8898d4495..0e69c6709 100644
--- a/connect.h
+++ b/connect.h
@@ -17,5 +17,7 @@ struct packet_reader;
extern enum protocol_version discover_version(struct packet_reader *reader);
extern int server_supports_v2(const char *c, int die_on_error);
+extern int server_supports_feature(const char *c, const char *feature,
+ int die_on_error);
#endif
diff --git a/fetch-pack.c b/fetch-pack.c
index 4fb5805dd..c0807e219 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -1008,6 +1008,26 @@ static struct ref *do_fetch_pack(struct fetch_pack_args
*args,
return ref;
}
+static void add_shallow_requests(struct strbuf *req_buf,
+const struct fetch_pack_args *args)
+{
+ if (is_repository_shallow())
+ write_shallow_commits(req_buf, 1, NULL);
+ if (args->depth > 0)
+ packet_buf_write(req_buf, "deepen %d", args->depth);
+ if (args->deepen_since) {
+ timestamp_t max_age = approxidate(args->deepen_since);
+ packet_buf_write(req_buf, "deepen-since %"PRItime, max_age);
+ }
+ if (args->deepen_not) {
+ int i;
+ for (i = 0; i < args->deepen_not->nr; i++) {
+ struct string_list_item *s = args->deepen_not->items +
i;
+ packet_buf_write(req_buf, "deepen-not %s", s->string);
+ }
+ }
+}
+
static void add_wants(const struct ref *wants, struct strbuf *req_buf)
{
for ( ; wants ; wants = wants->next) {
@@ -1090,6 +1110,10 @@ static int send_fetch_request(int fd_out, const struct
fetch_pack_args *args,
if (prefer_ofs_delta)
packet_buf_write(_buf, "ofs-delta");
+ /* Add shallow-info and deepen request */
+ if (server_supports_feature("fetch", "shallow", 1))
+ add_shallow_requests(_buf, args);
+
/* add wants */
add_wants(wants, _buf);
@@ -1119,7 +1143,7 @@ static int process_section_header(struct packet_reader
*reader,
int ret;
if (packet_reader_peek(reader) != PACKET_READ_NORMAL)
- die("error reading packet");
+ die("error reading section header '%s'", section);
ret = !strcmp(reader->line, section);
@@ -1174,6 +1198,43 @@ static int process_acks(struct packet_reader *reader,
struct oidset *common)
return received_ready ? 2 : (received_ack ? 1 : 0);
}
+static void receive_shallow_info(struct fetch_pack_args *args,
+struct packet_reader *reader)
+{
+ process_section_header(reader, "shallow-info", 0);
+ while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
+ const char *arg;
+ struct object_id oid;
+
+ if (skip_prefix(reader->line, "shallow ", )) {
+ if (get_oid_hex(arg, ))
+ die(_("invalid shallow line: %s"),
reader->line);
+ register_shallow();
+ continue;
+ }
+ if (skip_prefix(reader->line, "unshallow ", )) {
+ if (get_oid_hex(arg, ))
+ die(_("invalid unshallow line: %s"),
reader->line);
+ if (!lookup_object(oid.hash))
+ die(_("object not found: %s"), reader->line);
+ /* make sure that it is parsed as shallow */
+ if (!parse_object())
+ die(_("error in object: