@matheusbsbs / matheus-bagliano / commits / 3e63b21ace
Fork 0

upload-pack: Implement no-done capability

If the client requests both multi_ack_detailed and no-done then upload-pack is free to immediately send a PACK following its first 'ACK %s ready' message. The upload-pack response actually winds up being: ACK %s common ... (maybe more) ... ACK %s ready NAK ACK %s PACK.... the pack stream .... For smart HTTP connections this saves one HTTP RPC, reducing the overall latency for a trivial fetch. For git:// and ssh:// a no-done option slightly reduces latency by removing one server->client->server round-trip at the end of the common ancestor negotiation. 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 3e63b21aced116badd30a279c479535449a63560
1 file changed +16 -4
upload-pack.c
+16 -4
@@ -27,6 +27,7 @@ static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=<
27 static unsigned long oldest_have;
28
29 static int multi_ack, nr_our_refs;
30 +static int no_done;
31 static int use_thin_pack, use_ofs_delta, use_include_tag;
32 static int no_progress, daemon_mode;
33 static int shallow_nr;
@@ -431,6 +432,7 @@ static int get_common_commits(void)
432 char last_hex[41];
433 int got_common = 0;
434 int got_other = 0;
435 + int sent_ready = 0;
436
437 save_commit_buffer = 0;
438
@@ -440,10 +442,17 @@ static int get_common_commits(void)
442
443 if (!len) {
444 if (multi_ack == 2 && got_common
443 - && !got_other && ok_to_give_up())
445 + && !got_other && ok_to_give_up()) {
446 + sent_ready = 1;
447 packet_write(1, "ACK %s ready\n", last_hex);
448 + }
449 if (have_obj.nr == 0 || multi_ack)
450 packet_write(1, "NAK\n");
451 +
452 + if (no_done && sent_ready) {
453 + packet_write(1, "ACK %s\n", last_hex);
454 + return 0;
455 + }
456 if (stateless_rpc)
457 exit(0);
458 got_common = 0;
@@ -457,9 +466,10 @@ static int get_common_commits(void)
466 got_other = 1;
467 if (multi_ack && ok_to_give_up()) {
468 const char *hex = sha1_to_hex(sha1);
460 - if (multi_ack == 2)
469 + if (multi_ack == 2) {
470 + sent_ready = 1;
471 packet_write(1, "ACK %s ready\n", hex);
462 - else
472 + } else
473 packet_write(1, "ACK %s continue\n", hex);
474 }
475 break;
@@ -535,6 +545,8 @@ static void receive_needs(void)
545 multi_ack = 2;
546 else if (strstr(line+45, "multi_ack"))
547 multi_ack = 1;
548 + if (strstr(line+45, "no-done"))
549 + no_done = 1;
550 if (strstr(line+45, "thin-pack"))
551 use_thin_pack = 1;
552 if (strstr(line+45, "ofs-delta"))
@@ -628,7 +640,7 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
640 {
641 static const char *capabilities = "multi_ack thin-pack side-band"
642 " side-band-64k ofs-delta shallow no-progress"
631 - " include-tag multi_ack_detailed";
643 + " include-tag multi_ack_detailed no-done";
644 struct object *o = parse_object(sha1);
645
646 if (!o)