X-Git-Url: https://git.octo.it/?p=git.git;a=blobdiff_plain;f=upload-pack.c;h=47560c9527b9c17db34f10e78d7c1f0d99b746e1;hp=686445ec9b0a685e8325bb4d62abba90a6b3ad07;hb=162f41292167a800432fc6bbacfcd9f93a90b0c8;hpb=1bd8c8f00b1c7facb67c99047fe777b53f2c49ff diff --git a/upload-pack.c b/upload-pack.c index 686445ec..47560c95 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -4,6 +4,7 @@ #include "tag.h" #include "object.h" #include "commit.h" +#include "exec_cmd.h" static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=nn] "; @@ -13,6 +14,7 @@ static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=n #define MAX_HAS 256 #define MAX_NEEDS 256 static int nr_has = 0, nr_needs = 0, multi_ack = 0, nr_our_refs = 0; +static int use_thin_pack = 0; static unsigned char has_sha1[MAX_HAS][20]; static unsigned char needs_sha1[MAX_NEEDS][20]; static unsigned int timeout = 0; @@ -44,24 +46,26 @@ static void create_pack_file(void) if (!pid) { int i; int args; - char **argv; + const char **argv; char *buf; char **p; - if (create_full_pack) + if (create_full_pack) { args = 10; + use_thin_pack = 0; /* no point doing it */ + } else args = nr_has + nr_needs + 5; - argv = xmalloc(args * sizeof(char *)); + p = xmalloc(args * sizeof(char *)); + argv = (const char **) p; buf = xmalloc(args * 45); - p = argv; dup2(fd[1], 1); close(0); close(fd[0]); close(fd[1]); - *p++ = "git-rev-list"; - *p++ = "--objects"; + *p++ = "rev-list"; + *p++ = use_thin_pack ? "--objects-edge" : "--objects"; if (create_full_pack || MAX_NEEDS <= nr_needs) *p++ = "--all"; else { @@ -79,13 +83,13 @@ static void create_pack_file(void) buf += 41; } *p++ = NULL; - execvp("git-rev-list", argv); + execv_git_cmd(argv); die("git-upload-pack: unable to exec git-rev-list"); } dup2(fd[0], 0); close(fd[0]); close(fd[1]); - execlp("git-pack-objects", "git-pack-objects", "--stdout", NULL); + execl_git_cmd("pack-objects", "--stdout", NULL); die("git-upload-pack: unable to exec git-pack-objects"); } @@ -191,6 +195,8 @@ static int receive_needs(void) "expected to get sha, not '%s'", line); if (strstr(line+45, "multi_ack")) multi_ack = 1; + if (strstr(line+45, "thin-pack")) + use_thin_pack = 1; /* We have sent all our refs already, and the other end * should have chosen out of them; otherwise they are @@ -212,17 +218,24 @@ static int receive_needs(void) static int send_ref(const char *refname, const unsigned char *sha1) { - static char *capabilities = "\0multi_ack"; + static char *capabilities = "multi_ack thin-pack"; struct object *o = parse_object(sha1); - packet_write(1, "%s %s%s\n", sha1_to_hex(sha1), refname, capabilities); - capabilities = ""; + 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); + else + packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname); + capabilities = NULL; if (!(o->flags & OUR_REF)) { o->flags |= OUR_REF; nr_our_refs++; } if (o->type == tag_type) { - o = deref_tag(o); + o = deref_tag(o, refname, 0); packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname); } return 0; @@ -244,7 +257,7 @@ static int upload_pack(void) int main(int argc, char **argv) { - const char *dir; + char *dir; int i; int strict = 0; @@ -271,18 +284,9 @@ int main(int argc, char **argv) usage(upload_pack_usage); dir = argv[i]; - /* chdir to the directory. If that fails, try appending ".git" */ - if (chdir(dir) < 0) { - if (strict || chdir(mkpath("%s.git", dir)) < 0) - die("git-upload-pack unable to chdir to %s", dir); - } - if (!strict) - 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); + if (!enter_repo(dir, strict)) + die("'%s': unable to chdir or not a git archive", dir); - putenv("GIT_DIR=."); upload_pack(); return 0; }