X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=fetch-pack.c;h=aa6f42ae1b45c896395fc146990db22cb61e2f60;hb=070879ca93a7d358086f4c8aff4553493dcb9210;hp=3df991100bdd51f4527703d1ce1d016b611f0d5a;hpb=e634aec752642dcf86c3fc82025e43381d6768c2;p=git.git diff --git a/fetch-pack.c b/fetch-pack.c index 3df99110..aa6f42ae 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -3,13 +3,12 @@ #include "pkt-line.h" #include "commit.h" #include "tag.h" -#include -#include +static int keep_pack; static int quiet; static int verbose; static const char fetch_pack_usage[] = -"git-fetch-pack [-q] [-v] [--exec=upload-pack] [host:]directory ..."; +"git-fetch-pack [-q] [-v] [-k] [--exec=upload-pack] [host:]directory ..."; static const char *exec = "git-upload-pack"; #define COMPLETE (1U << 0) @@ -38,9 +37,9 @@ static void rev_list_push(struct commit *commit, int mark) static int rev_list_insert_ref(const char *path, const unsigned char *sha1) { - struct object *o = deref_tag(parse_object(sha1)); + struct object *o = deref_tag(parse_object(sha1), path, 0); - if (o->type == commit_type) + if (o && o->type == commit_type) rev_list_push((struct commit *)o, SEEN); return 0; @@ -263,9 +262,6 @@ static void filter_refs(struct ref **refs, int nr_match, char **match) { struct ref *prev, *current, *next; - if (!nr_match) - return; - for (prev = NULL, current = *refs; current; current = next) { next = current->next; if ((!memcmp(current->name, "refs/", 5) && @@ -317,7 +313,8 @@ static int everything_local(struct ref **refs, int nr_match, char **match) * Don't mark them common yet; the server has to be told so first. */ for (ref = *refs; ref; ref = ref->next) { - struct object *o = deref_tag(lookup_object(ref->old_sha1)); + struct object *o = deref_tag(lookup_object(ref->old_sha1), + NULL, 0); if (!o || o->type != commit_type || !(o->flags & COMPLETE)) continue; @@ -362,7 +359,6 @@ static int fetch_pack(int fd[2], int nr_match, char **match) struct ref *ref; unsigned char sha1[20]; int status; - pid_t pid; get_remote_heads(fd[0], &ref, 0, NULL, 0); if (server_supports("multi_ack")) { @@ -380,40 +376,22 @@ static int fetch_pack(int fd[2], int nr_match, char **match) } if (find_common(fd, sha1, ref) < 0) fprintf(stderr, "warning: no common commits\n"); - pid = fork(); - if (pid < 0) - die("git-fetch-pack: unable to fork off git-unpack-objects"); - if (!pid) { - dup2(fd[0], 0); - close(fd[0]); - close(fd[1]); - execlp("git-unpack-objects", "git-unpack-objects", - quiet ? "-q" : NULL, NULL); - die("git-unpack-objects exec failed"); - } - close(fd[0]); - close(fd[1]); - while (waitpid(pid, &status, 0) < 0) { - if (errno != EINTR) - die("waiting for git-unpack-objects: %s", strerror(errno)); - } - if (WIFEXITED(status)) { - int code = WEXITSTATUS(status); - if (code) - die("git-unpack-objects died with error code %d", code); -all_done: - while (ref) { - printf("%s %s\n", - sha1_to_hex(ref->old_sha1), ref->name); - ref = ref->next; - } - return 0; - } - if (WIFSIGNALED(status)) { - int sig = WTERMSIG(status); - die("git-unpack-objects died of signal %d", sig); + + if (keep_pack) + status = receive_keep_pack(fd, "git-fetch-pack", quiet); + else + status = receive_unpack_pack(fd, "git-fetch-pack", quiet); + + if (status) + die("git-fetch-pack: fetch failed."); + + all_done: + while (ref) { + printf("%s %s\n", + sha1_to_hex(ref->old_sha1), ref->name); + ref = ref->next; } - die("Sherlock Holmes! git-unpack-objects died of unnatural causes %d!", status); + return 0; } int main(int argc, char **argv) @@ -423,6 +401,8 @@ int main(int argc, char **argv) int fd[2]; pid_t pid; + setup_git_directory(); + nr_heads = 0; heads = NULL; for (i = 1; i < argc; i++) { @@ -433,10 +413,14 @@ int main(int argc, char **argv) exec = arg + 7; continue; } - if (!strcmp("-q", arg)) { + if (!strcmp("--quiet", arg) || !strcmp("-q", arg)) { quiet = 1; continue; } + if (!strcmp("--keep", arg) || !strcmp("-k", arg)) { + keep_pack = 1; + continue; + } if (!strcmp("-v", arg)) { verbose = 1; continue; @@ -457,5 +441,19 @@ int main(int argc, char **argv) close(fd[0]); close(fd[1]); finish_connect(pid); + + if (!ret && nr_heads) { + /* If the heads to pull were given, we should have + * consumed all of them by matching the remote. + * Otherwise, 'git-fetch remote no-such-ref' would + * silently succeed without issuing an error. + */ + for (i = 0; i < nr_heads; i++) + if (heads[i] && heads[i][0]) { + error("no such remote ref %s", heads[i]); + ret = 1; + } + } + return ret; }