summaryrefslogtreecommitdiff
path: root/send-pack.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2006-02-22 02:59:37 (GMT)
committerJunio C Hamano <junkio@cox.net>2006-02-22 09:47:32 (GMT)
commit797656e58ddbd82ac461a5142ed726db3a4d0ac0 (patch)
treecb900f7e451fc454f03e7c75c88ef3baf33a19cf /send-pack.c
parent50319850343dfe534939ee6b38507d5a8fc44b50 (diff)
downloadgit-797656e58ddbd82ac461a5142ed726db3a4d0ac0.zip
git-797656e58ddbd82ac461a5142ed726db3a4d0ac0.tar.gz
git-797656e58ddbd82ac461a5142ed726db3a4d0ac0.tar.bz2
send-pack: do not give up when remote has insanely large number of refs.
Stephen C. Tweedie noticed that we give up running rev-list when we see too many refs on the remote side. Limit the number of negative references we give to rev-list and continue. Not sending any negative references to rev-list is very bad -- we may be pushing a ref that is new to the other end. Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'send-pack.c')
-rw-r--r--send-pack.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/send-pack.c b/send-pack.c
index 990be3f..b58bbab 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -37,26 +37,44 @@ static void exec_pack_objects(void)
static void exec_rev_list(struct ref *refs)
{
+ struct ref *ref;
static char *args[1000];
- int i = 0;
+ int i = 0, j;
args[i++] = "rev-list"; /* 0 */
args[i++] = "--objects"; /* 1 */
- while (refs) {
- char *buf = malloc(100);
- if (i > 900)
+
+ /* First send the ones we care about most */
+ for (ref = refs; ref; ref = ref->next) {
+ if (900 < i)
die("git-rev-list environment overflow");
- if (!is_zero_sha1(refs->old_sha1) &&
- has_sha1_file(refs->old_sha1)) {
+ if (!is_zero_sha1(ref->new_sha1)) {
+ char *buf = malloc(100);
args[i++] = buf;
- snprintf(buf, 50, "^%s", sha1_to_hex(refs->old_sha1));
+ snprintf(buf, 50, "%s", sha1_to_hex(ref->new_sha1));
buf += 50;
+ if (!is_zero_sha1(ref->old_sha1) &&
+ has_sha1_file(ref->old_sha1)) {
+ args[i++] = buf;
+ snprintf(buf, 50, "^%s",
+ sha1_to_hex(ref->old_sha1));
+ }
}
- if (!is_zero_sha1(refs->new_sha1)) {
+ }
+
+ /* Then a handful of the remainder
+ * NEEDSWORK: we would be better off if used the newer ones first.
+ */
+ for (ref = refs, j = i + 16;
+ i < 900 && i < j && ref;
+ ref = ref->next) {
+ if (is_zero_sha1(ref->new_sha1) &&
+ !is_zero_sha1(ref->old_sha1) &&
+ has_sha1_file(ref->old_sha1)) {
+ char *buf = malloc(42);
args[i++] = buf;
- snprintf(buf, 50, "%s", sha1_to_hex(refs->new_sha1));
+ snprintf(buf, 42, "^%s", sha1_to_hex(ref->old_sha1));
}
- refs = refs->next;
}
args[i] = NULL;
execv_git_cmd(args);