aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-05-24 21:48:34 -0700
committerJunio C Hamano <junkio@cox.net>2006-05-24 22:30:56 -0700
commitf061e5fdd6a65216976a8bd547b2340e6297217b (patch)
treefac4d3a1626241087c74d06f191bbeab00a9549f
parented90cbf5f681c0144909457be3f4792b47604a5b (diff)
downloadgit-f061e5fdd6a65216976a8bd547b2340e6297217b.tar.gz
git-f061e5fdd6a65216976a8bd547b2340e6297217b.tar.xz
fetch-pack: give up after getting too many "ack continue"
If your repository have more roots than the remote repository you ask an object for, the remote upload-pack keeps responding "ack continue" until it fills up its received-have buffer (currently 256 entries). Usually this is not a problem because the requester stops traversing the ancestry chain from the commit it gets "ack continue" for, but this mechanism does not work as a roadblock when it traverses down the path to the root the other side does not have. Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r--fetch-pack.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/fetch-pack.c b/fetch-pack.c
index 8daa93d02..837134855 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -18,6 +18,12 @@ 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;
@@ -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);
@@ -172,6 +180,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 +209,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: