X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=fetch-pack.c;h=b7824dbed4e10d912a0977865e24e21ff9295aae;hb=82f930deadc9a7990cbc0988255e6a5afd641f4b;hp=8daa93d024158e6d8daff304db57ac80d1803c65;hpb=22f7c8cc9179dec90a7d735330455347b92b7777;p=git.git diff --git a/fetch-pack.c b/fetch-pack.c index 8daa93d02..b7824dbed 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -18,8 +18,14 @@ static const char *exec = "git-upload-pack"; #define SEEN (1U << 3) #define POPPED (1U << 4) +/* + * After sending this many "have"s if we do not get any new ACK , we + * give up traversing our history. + */ +#define MAX_IN_VAIN 256 + static struct commit_list *rev_list = NULL; -static int non_common_revs = 0, multi_ack = 0, use_thin_pack = 0; +static int non_common_revs = 0, multi_ack = 0, use_thin_pack = 0, use_sideband; static void rev_list_push(struct commit *commit, int mark) { @@ -40,7 +46,7 @@ static int rev_list_insert_ref(const char *path, const unsigned char *sha1) { struct object *o = deref_tag(parse_object(sha1), path, 0); - if (o && o->type == commit_type) + if (o && o->type == OBJ_COMMIT) rev_list_push((struct commit *)o, SEEN); return 0; @@ -134,6 +140,8 @@ static int find_common(int fd[2], unsigned char *result_sha1, int fetching; int count = 0, flushes = 0, retval; const unsigned char *sha1; + unsigned in_vain = 0; + int got_continue = 0; for_each_ref(rev_list_insert_ref); @@ -157,9 +165,14 @@ static int find_common(int fd[2], unsigned char *result_sha1, continue; } - packet_write(fd[1], "want %s%s%s\n", sha1_to_hex(remote), - (multi_ack ? " multi_ack" : ""), - (use_thin_pack ? " thin-pack" : "")); + if (!fetching) + packet_write(fd[1], "want %s%s%s%s\n", + sha1_to_hex(remote), + (multi_ack ? " multi_ack" : ""), + (use_sideband ? " side-band" : ""), + (use_thin_pack ? " thin-pack" : "")); + else + packet_write(fd[1], "want %s\n", sha1_to_hex(remote)); fetching++; } packet_flush(fd[1]); @@ -172,6 +185,7 @@ static int find_common(int fd[2], unsigned char *result_sha1, packet_write(fd[1], "have %s\n", sha1_to_hex(sha1)); if (verbose) fprintf(stderr, "have %s\n", sha1_to_hex(sha1)); + in_vain++; if (!(31 & ++count)) { int ack; @@ -200,9 +214,16 @@ static int find_common(int fd[2], unsigned char *result_sha1, lookup_commit(result_sha1); mark_common(commit, 0, 1); retval = 0; + in_vain = 0; + got_continue = 1; } } while (ack); flushes--; + if (got_continue && MAX_IN_VAIN < in_vain) { + if (verbose) + fprintf(stderr, "giving up\n"); + break; /* give up */ + } } } done: @@ -235,14 +256,14 @@ static int mark_complete(const char *path, const unsigned char *sha1) { struct object *o = parse_object(sha1); - while (o && o->type == tag_type) { + while (o && o->type == OBJ_TAG) { struct tag *t = (struct tag *) o; if (!t->tagged) break; /* broken repository */ o->flags |= COMPLETE; o = parse_object(t->tagged->sha1); } - if (o && o->type == commit_type) { + if (o && o->type == OBJ_COMMIT) { struct commit *commit = (struct commit *)o; commit->object.flags |= COMPLETE; insert_by_date(commit, &complete); @@ -336,7 +357,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match) * in sync with the other side at some time after * that (it is OK if we guess wrong here). */ - if (o->type == commit_type) { + if (o->type == OBJ_COMMIT) { struct commit *commit = (struct commit *)o; if (!cutoff || cutoff < commit->date) cutoff = commit->date; @@ -355,7 +376,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match) struct object *o = deref_tag(lookup_object(ref->old_sha1), NULL, 0); - if (!o || o->type != commit_type || !(o->flags & COMPLETE)) + if (!o || o->type != OBJ_COMMIT || !(o->flags & COMPLETE)) continue; if (!(o->flags & SEEN)) { @@ -405,6 +426,11 @@ static int fetch_pack(int fd[2], int nr_match, char **match) fprintf(stderr, "Server supports multi_ack\n"); multi_ack = 1; } + if (server_supports("side-band")) { + if (verbose) + fprintf(stderr, "Server supports side-band\n"); + use_sideband = 1; + } if (!ref) { packet_flush(fd[1]); die("no matching remote head"); @@ -421,9 +447,9 @@ static int fetch_pack(int fd[2], int nr_match, char **match) fprintf(stderr, "warning: no common commits\n"); if (keep_pack) - status = receive_keep_pack(fd, "git-fetch-pack", quiet); + status = receive_keep_pack(fd, "git-fetch-pack", quiet, use_sideband); else - status = receive_unpack_pack(fd, "git-fetch-pack", quiet); + status = receive_unpack_pack(fd, "git-fetch-pack", quiet, use_sideband); if (status) die("git-fetch-pack: fetch failed.");