@matheusbsbs / matheus-bagliano / commits / 761ecf0bc7
Fork 0

fetch-pack: Implement no-done capability

If enabled on the connection "multi_ack_detailed no-done" as a pair allows the remote upload-pack process to send a PACK down to the client as soon as a "ACK %s ready" message was also sent. Over git:// and ssh:// where a bi-directional stream is in place this has very little difference over the classical version that waits for the client to send a "done\n" line by itself. It does slightly reduce the latency involved to start the pack stream as there is one less round-trip from client->server required. Over smart HTTP this avoids needing to send a final RPC that has all of the prior common objects. Instead the server is able to return a pack as soon as its ready to. For many common users the smart HTTP fetch is now just 2 requests: GET .../info/refs, and a POST .../git-upload-pack to not only negotiate but also receive the pack stream. Only users who have more than 32 local unshared commits with the remote will need additional requests to negotiate a common merge base. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Shawn O. Pearce committed Mar 14, 2011 at 17:59 UTC 761ecf0bc7b6cddf311f00877c59e6381cdbdeea
1 file changed +15 -3
builtin/fetch-pack.c
+15 -3
@@ -14,6 +14,7 @@ static int transfer_unpack_limit = -1;
14 static int fetch_unpack_limit = -1;
15 static int unpack_limit = 100;
16 static int prefer_ofs_delta = 1;
17 +static int no_done = 0;
18 static struct fetch_pack_args args = {
19 /* .uploadpack = */ "git-upload-pack",
20 };
@@ -225,6 +226,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,
226 const unsigned char *sha1;
227 unsigned in_vain = 0;
228 int got_continue = 0;
229 + int got_ready = 0;
230 struct strbuf req_buf = STRBUF_INIT;
231 size_t state_len = 0;
232
@@ -262,6 +264,7 @@ static int find_common(int fd[2], unsigned char *result_sha1,
264 struct strbuf c = STRBUF_INIT;
265 if (multi_ack == 2) strbuf_addstr(&c, " multi_ack_detailed");
266 if (multi_ack == 1) strbuf_addstr(&c, " multi_ack");
267 + if (no_done) strbuf_addstr(&c, " no-done");
268 if (use_sideband == 2) strbuf_addstr(&c, " side-band-64k");
269 if (use_sideband == 1) strbuf_addstr(&c, " side-band");
270 if (args.use_thin_pack) strbuf_addstr(&c, " thin-pack");
@@ -379,8 +382,10 @@ static int find_common(int fd[2], unsigned char *result_sha1,
382 retval = 0;
383 in_vain = 0;
384 got_continue = 1;
382 - if (ack == ACK_ready)
385 + if (ack == ACK_ready) {
386 rev_list = NULL;
387 + got_ready = 1;
388 + }
389 break;
390 }
391 }
@@ -394,8 +399,10 @@ static int find_common(int fd[2], unsigned char *result_sha1,
399 }
400 }
401 done:
397 - packet_buf_write(&req_buf, "done\n");
398 - send_request(fd[1], &req_buf);
402 + if (!got_ready || !no_done) {
403 + packet_buf_write(&req_buf, "done\n");
404 + send_request(fd[1], &req_buf);
405 + }
406 if (args.verbose)
407 fprintf(stderr, "done\n");
408 if (retval != 0) {
@@ -698,6 +705,11 @@ static struct ref *do_fetch_pack(int fd[2],
705 if (args.verbose)
706 fprintf(stderr, "Server supports multi_ack_detailed\n");
707 multi_ack = 2;
708 + if (server_supports("no-done")) {
709 + if (args.verbose)
710 + fprintf(stderr, "Server supports no-done\n");
711 + no_done = 1;
712 + }
713 }
714 else if (server_supports("multi_ack")) {
715 if (args.verbose)