X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=upload-pack.c;h=83f5a35d2686401e9a70d7aafae07c88c7b6e936;hb=8b73edf498adf2895af7ff9c750283cf9325a632;hp=9edbf51dc5aac854943ad34c001b11850000e2a7;hpb=723c31fea2f1c4994de837bda9022ffa8b6de1bb;p=git.git diff --git a/upload-pack.c b/upload-pack.c index 9edbf51d..83f5a35d 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -5,7 +5,7 @@ static const char upload_pack_usage[] = "git-upload-pack "; #define MAX_HAS (16) -#define MAX_NEEDS (16) +#define MAX_NEEDS (256) static int nr_has = 0, nr_needs = 0; static unsigned char has_sha1[MAX_HAS][20]; static unsigned char needs_sha1[MAX_NEEDS][20]; @@ -30,10 +30,18 @@ static void create_pack_file(void) if (!pid) { int i; - int args = nr_has + nr_needs + 5; - char **argv = xmalloc(args * sizeof(char *)); - char *buf = xmalloc(args * 45); - char **p = argv; + int args; + char **argv; + char *buf; + char **p; + + if (MAX_NEEDS <= nr_needs) + args = nr_has + 10; + else + args = nr_has + nr_needs + 5; + argv = xmalloc(args * sizeof(char *)); + buf = xmalloc(args * 45); + p = argv; dup2(fd[1], 1); close(0); @@ -41,10 +49,14 @@ static void create_pack_file(void) close(fd[1]); *p++ = "git-rev-list"; *p++ = "--objects"; - for (i = 0; i < nr_needs; i++) { - *p++ = buf; - memcpy(buf, sha1_to_hex(needs_sha1[i]), 41); - buf += 41; + if (MAX_NEEDS <= nr_needs) + *p++ = "--all"; + else { + for (i = 0; i < nr_needs; i++) { + *p++ = buf; + memcpy(buf, sha1_to_hex(needs_sha1[i]), 41); + buf += 41; + } } for (i = 0; i < nr_has; i++) { *p++ = buf; @@ -129,18 +141,24 @@ static int receive_needs(void) needs = 0; for (;;) { + unsigned char dummy[20], *sha1_buf; len = packet_read_line(0, line, sizeof(line)); if (!len) return needs; - /* - * This is purely theoretical right now: git-fetch-pack only - * ever asks for a single HEAD - */ - if (needs >= MAX_NEEDS) - die("I'm only doing a max of %d requests", MAX_NEEDS); - if (strncmp("want ", line, 5) || get_sha1_hex(line+5, needs_sha1[needs])) - die("git-upload-pack: protocol error, expected to get sha, not '%s'", line); + sha1_buf = dummy; + if (needs == MAX_NEEDS) { + fprintf(stderr, + "warning: supporting only a max of %d requests. " + "sending everything instead.\n", + MAX_NEEDS); + } + else if (needs < MAX_NEEDS) + sha1_buf = needs_sha1[needs]; + + if (strncmp("want ", line, 5) || get_sha1_hex(line+5, sha1_buf)) + die("git-upload-pack: protocol error, " + "expected to get sha, not '%s'", line); needs++; } } @@ -170,12 +188,16 @@ int main(int argc, char **argv) if (argc != 2) usage(upload_pack_usage); dir = argv[1]; - if (chdir(dir)) - die("git-upload-pack unable to chdir to %s", dir); + + /* chdir to the directory. If that fails, try appending ".git" */ + if (chdir(dir) < 0) { + if (chdir(mkpath("%s.git", dir)) < 0) + die("git-upload-pack unable to chdir to %s", dir); + } chdir(".git"); if (access("objects", X_OK) || access("refs", X_OK)) die("git-upload-pack: %s doesn't seem to be a git archive", dir); - setenv("GIT_DIR", ".", 1); + putenv("GIT_DIR=."); upload_pack(); return 0; }