From: Junio C Hamano Date: Tue, 29 Mar 2011 21:09:02 +0000 (-0700) Subject: Merge branches 'sp/maint-fetch-pack-stop-early' and 'sp/maint-upload-pack-stop-early' X-Git-Tag: v1.7.5-rc0~6 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/2eee1393f39953d27b63070fdb5c533082f28f0c?ds=inline;hp=-c Merge branches 'sp/maint-fetch-pack-stop-early' and 'sp/maint-upload-pack-stop-early' * sp/maint-fetch-pack-stop-early: enable "no-done" extension only when fetching over smart-http * sp/maint-upload-pack-stop-early: enable "no-done" extension only when serving over smart-http --- 2eee1393f39953d27b63070fdb5c533082f28f0c diff --combined builtin/fetch-pack.c index bf9990ce15,52707a80ad,b999413934..65a8727453 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@@@ -1,4 -1,4 -1,4 +1,4 @@@@ --#include "cache.h" ++#include "builtin.h" #include "refs.h" #include "pkt-line.h" #include "commit.h" @@@@ -9,13 -9,12 -9,11 +9,13 @@@@ #include "fetch-pack.h" #include "remote.h" #include "run-command.h" ++#include "transport.h" static int transfer_unpack_limit = -1; static int fetch_unpack_limit = -1; static int unpack_limit = 100; static int prefer_ofs_delta = 1; +static int no_done = 0; static struct fetch_pack_args args = { /* .uploadpack = */ "git-upload-pack", }; @@@@ -219,39 -218,15 -217,14 +219,39 @@@@ static void send_request(int fd, struc safe_write(fd, buf->buf, buf->len); } ++static void insert_one_alternate_ref(const struct ref *ref, void *unused) ++{ ++ rev_list_insert_ref(NULL, ref->old_sha1, 0, NULL); ++} ++ ++static void insert_alternate_refs(void) ++{ ++ foreach_alt_odb(refs_from_alternate_cb, insert_one_alternate_ref); ++} ++ ++#define INITIAL_FLUSH 16 ++#define LARGE_FLUSH 1024 ++ ++static int next_flush(int count) ++{ ++ if (count < INITIAL_FLUSH * 2) ++ count += INITIAL_FLUSH; ++ else if (count < LARGE_FLUSH) ++ count <<= 1; ++ else ++ count += LARGE_FLUSH; ++ return count; ++} ++ static int find_common(int fd[2], unsigned char *result_sha1, struct ref *refs) { int fetching; -- int count = 0, flushes = 0, retval; ++ int count = 0, flushes = 0, flush_at = INITIAL_FLUSH, retval; const unsigned char *sha1; unsigned in_vain = 0; int got_continue = 0; + int got_ready = 0; struct strbuf req_buf = STRBUF_INIT; size_t state_len = 0; @@@@ -262,7 -237,6 -235,6 +262,7 @@@@ marked = 1; for_each_ref(rev_list_insert_ref, NULL); ++ insert_alternate_refs(); fetching = 0; for ( ; refs ; refs = refs->next) { @@@@ -290,7 -264,7 -262,6 +290,7 @@@@ struct strbuf c = STRBUF_INIT; if (multi_ack == 2) strbuf_addstr(&c, " multi_ack_detailed"); if (multi_ack == 1) strbuf_addstr(&c, " multi_ack"); + if (no_done) strbuf_addstr(&c, " no-done"); if (use_sideband == 2) strbuf_addstr(&c, " side-band-64k"); if (use_sideband == 1) strbuf_addstr(&c, " side-band"); if (args.use_thin_pack) strbuf_addstr(&c, " thin-pack"); @@@@ -361,20 -335,19 -332,19 +361,20 @@@@ if (args.verbose) fprintf(stderr, "have %s\n", sha1_to_hex(sha1)); in_vain++; -- if (!(31 & ++count)) { ++ if (flush_at <= ++count) { int ack; packet_buf_flush(&req_buf); send_request(fd[1], &req_buf); strbuf_setlen(&req_buf, state_len); flushes++; ++ flush_at = next_flush(count); /* * We keep one window "ahead" of the other side, and * will wait for an ACK only on the next one */ -- if (!args.stateless_rpc && count == 32) ++ if (!args.stateless_rpc && count == INITIAL_FLUSH) continue; consume_shallow_list(fd[0]); @@@@ -409,10 -382,10 -379,6 +409,10 @@@@ retval = 0; in_vain = 0; got_continue = 1; + if (ack == ACK_ready) { + rev_list = NULL; + got_ready = 1; + } break; } } @@@@ -426,10 -399,10 -392,8 +426,10 @@@@ } } done: - packet_buf_write(&req_buf, "done\n"); - send_request(fd[1], &req_buf); + if (!got_ready || !no_done) { + packet_buf_write(&req_buf, "done\n"); + send_request(fd[1], &req_buf); + } if (args.verbose) fprintf(stderr, "done\n"); if (retval != 0) { @@@@ -732,11 -705,12 -696,6 +732,12 @@@@ static struct ref *do_fetch_pack(int fd if (args.verbose) fprintf(stderr, "Server supports multi_ack_detailed\n"); multi_ack = 2; + if (server_supports("no-done")) { + if (args.verbose) + fprintf(stderr, "Server supports no-done\n"); - no_done = 1; + + if (args.stateless_rpc) + + no_done = 1; + } } else if (server_supports("multi_ack")) { if (args.verbose) @@@@ -845,8 -819,6 -804,6 +846,8 @@@@ int cmd_fetch_pack(int argc, const cha char **pack_lockfile_ptr = NULL; struct child_process *conn; ++ packet_trace_identity("fetch-pack"); ++ nr_heads = 0; heads = NULL; for (i = 1; i < argc; i++) { diff --combined upload-pack.c index 72aa661f8d,b40a43f27d,a247fb9e27..bba053f0aa --- a/upload-pack.c +++ b/upload-pack.c @@@@ -27,7 -27,6 -27,7 +27,7 @@@@ static const char upload_pack_usage[] 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; @@@@ -430,9 -429,6 -430,9 +430,9 @@@@ static int get_common_commits(void static char line[1000]; unsigned char sha1[20]; char last_hex[41]; + int got_common = 0; + int got_other = 0; + int sent_ready = 0; save_commit_buffer = 0; @@@@ -441,40 -437,25 -441,40 +441,40 @@@@ reset_timeout(); if (!len) { + if (multi_ack == 2 && got_common + && !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; + got_other = 0; continue; } strip(line, len); if (!prefixcmp(line, "have ")) { switch (got_sha1(line+5, sha1)) { case -1: /* they have what we do not */ + 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; default: + got_common = 1; memcpy(last_hex, sha1_to_hex(sha1), 41); if (multi_ack == 2) packet_write(1, "ACK %s common\n", last_hex); @@@@ -545,8 -526,6 -545,8 +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")) @@@@ -640,15 -619,15 -640,16 +640,16 @@@@ static int send_ref(const char *refname { static const char *capabilities = "multi_ack thin-pack side-band" " side-band-64k ofs-delta shallow no-progress" - " include-tag multi_ack_detailed no-done"; + " include-tag multi_ack_detailed"; struct object *o = parse_object(sha1); if (!o) die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1)); if (capabilities) -- packet_write(1, "%s %s%c%s\n", sha1_to_hex(sha1), refname, -- 0, capabilities); ++ packet_write(1, "%s %s%c%s%s\n", sha1_to_hex(sha1), refname, ++ 0, capabilities, ++ stateless_rpc ? " no-done" : ""); else packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname); capabilities = NULL; @@@@ -703,7 -682,6 -704,6 +704,7 @@@@ int main(int argc, char **argv int i; int strict = 0; ++ packet_trace_identity("upload-pack"); git_extract_argv0_path(argv[0]); read_replace_refs = 0;