diff options
author | Shawn O. Pearce <spearce@spearce.org> | 2011-03-14 17:59:40 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2011-03-15 12:14:35 -0700 |
commit | 3e63b21aced116badd30a279c479535449a63560 (patch) | |
tree | 665e66ec370b0f53c3e5634c1e27f6f4cff81d86 /upload-pack.c | |
parent | 49bee717f7080f99d3405682cc43ad525dde0973 (diff) | |
download | git-3e63b21aced116badd30a279c479535449a63560.tar.gz |
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>
Diffstat (limited to 'upload-pack.c')
-rw-r--r-- | upload-pack.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/upload-pack.c b/upload-pack.c index 11c3849a79..5924f6f988 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -27,6 +27,7 @@ static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=< static unsigned long oldest_have; static int multi_ack, nr_our_refs; +static int no_done; static int use_thin_pack, use_ofs_delta, use_include_tag; static int no_progress, daemon_mode; static int shallow_nr; @@ -431,6 +432,7 @@ static int get_common_commits(void) char last_hex[41]; int got_common = 0; int got_other = 0; + int sent_ready = 0; save_commit_buffer = 0; @@ -440,10 +442,17 @@ static int get_common_commits(void) if (!len) { if (multi_ack == 2 && got_common - && !got_other && ok_to_give_up()) + && !got_other && ok_to_give_up()) { + sent_ready = 1; packet_write(1, "ACK %s ready\n", last_hex); + } if (have_obj.nr == 0 || multi_ack) packet_write(1, "NAK\n"); + + if (no_done && sent_ready) { + packet_write(1, "ACK %s\n", last_hex); + return 0; + } if (stateless_rpc) exit(0); got_common = 0; @@ -457,9 +466,10 @@ static int get_common_commits(void) got_other = 1; if (multi_ack && ok_to_give_up()) { const char *hex = sha1_to_hex(sha1); - if (multi_ack == 2) + if (multi_ack == 2) { + sent_ready = 1; packet_write(1, "ACK %s ready\n", hex); - else + } else packet_write(1, "ACK %s continue\n", hex); } break; @@ -535,6 +545,8 @@ static void receive_needs(void) multi_ack = 2; else if (strstr(line+45, "multi_ack")) multi_ack = 1; + if (strstr(line+45, "no-done")) + no_done = 1; if (strstr(line+45, "thin-pack")) use_thin_pack = 1; if (strstr(line+45, "ofs-delta")) @@ -628,7 +640,7 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo { static const char *capabilities = "multi_ack thin-pack side-band" " side-band-64k ofs-delta shallow no-progress" - " include-tag multi_ack_detailed"; + " include-tag multi_ack_detailed no-done"; struct object *o = parse_object(sha1); if (!o) |