X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=builtin-archive.c;h=187491bc172571b783a0be4f4dfa3d94d58bb0fe;hb=738a1154db190c75a7454da85d85be68ad7db065;hp=c70488c53790d0339d38f5978d97fb4e7faa7fb3;hpb=37f944363d5b5fb5bcbf2d184865534739713c01;p=git.git diff --git a/builtin-archive.c b/builtin-archive.c index c70488c53..187491bc1 100644 --- a/builtin-archive.c +++ b/builtin-archive.c @@ -2,7 +2,6 @@ * Copyright (c) 2006 Franck Bui-Huu * Copyright (c) 2006 Rene Scharfe */ -#include #include "cache.h" #include "builtin.h" #include "archive.h" @@ -10,38 +9,51 @@ #include "tree-walk.h" #include "exec_cmd.h" #include "pkt-line.h" +#include "sideband.h" static const char archive_usage[] = \ -"git-archive --format= [--prefix=/] [] [path...]"; - -struct archiver archivers[] = { - { - .name = "tar", - .write_archive = write_tar_archive, - }, - { - .name = "zip", - .write_archive = write_zip_archive, - .parse_extra = parse_extra_zip_args, - }, +"git-archive --format= [--prefix=/] [--verbose] [] [path...]"; + +static struct archiver_desc +{ + const char *name; + write_archive_fn_t write_archive; + parse_extra_args_fn_t parse_extra; +} archivers[] = { + { "tar", write_tar_archive, NULL }, + { "zip", write_zip_archive, parse_extra_zip_args }, }; static int run_remote_archiver(const char *remote, int argc, const char **argv) { - char *url, buf[1024]; + char *url, buf[LARGE_PACKET_MAX]; int fd[2], i, len, rv; pid_t pid; + const char *exec = "git-upload-archive"; + int exec_at = 0; - sprintf(buf, "git-upload-archive"); + for (i = 1; i < argc; i++) { + const char *arg = argv[i]; + if (!prefixcmp(arg, "--exec=")) { + if (exec_at) + die("multiple --exec specified"); + exec = arg + 7; + exec_at = i; + break; + } + } url = xstrdup(remote); - pid = git_connect(fd, url, buf); + pid = git_connect(fd, url, exec, 0); if (pid < 0) return pid; - for (i = 1; i < argc; i++) + for (i = 1; i < argc; i++) { + if (i == exec_at) + continue; packet_write(fd[1], "argument %s\n", argv[i]); + } packet_flush(fd[1]); len = packet_read_line(fd[0], buf, sizeof(buf)); @@ -50,7 +62,7 @@ static int run_remote_archiver(const char *remote, int argc, if (buf[len-1] == '\n') buf[--len] = 0; if (strcmp(buf, "ACK")) { - if (len > 5 && !strncmp(buf, "NACK ", 5)) + if (len > 5 && !prefixcmp(buf, "NACK ")) die("git-archive: NACK %s", buf + 5); die("git-archive: protocol error"); } @@ -60,9 +72,9 @@ static int run_remote_archiver(const char *remote, int argc, die("git-archive: expected a flush"); /* Now, start reading from fd[0] and spit it out to stdout */ - rv = copy_fd(fd[0], 1); - + rv = recv_sideband("archive", fd[0], 1, 2); close(fd[0]); + close(fd[1]); rv |= finish_connect(pid); return !!rv; @@ -74,7 +86,10 @@ static int init_archiver(const char *name, struct archiver *ar) for (i = 0; i < ARRAY_SIZE(archivers); i++) { if (!strcmp(name, archivers[i].name)) { - memcpy(ar, &archivers[i], sizeof(struct archiver)); + memset(ar, 0, sizeof(*ar)); + ar->name = archivers[i].name; + ar->write_archive = archivers[i].write_archive; + ar->parse_extra = archivers[i].parse_extra; rv = 0; break; } @@ -123,7 +138,6 @@ void parse_treeish_arg(const char **argv, struct archiver_args *ar_args, if (err || !S_ISDIR(mode)) die("current working directory is untracked"); - free(tree); tree = parse_tree_indirect(tree_sha1); } ar_args->tree = tree; @@ -131,23 +145,13 @@ void parse_treeish_arg(const char **argv, struct archiver_args *ar_args, ar_args->time = archive_time; } -static const char *default_parse_extra(struct archiver *ar, - const char **argv) -{ - static char msg[64]; - - snprintf(msg, sizeof(msg) - 4, "'%s' format does not handle %s", - ar->name, *argv); - - return strcat(msg, "..."); -} - int parse_archive_args(int argc, const char **argv, struct archiver *ar) { const char *extra_argv[MAX_EXTRA_ARGS]; int extra_argc = 0; - const char *format = NULL; /* might want to default to "tar" */ + const char *format = "tar"; const char *base = ""; + int verbose = 0; int i; for (i = 1; i < argc; i++) { @@ -158,11 +162,15 @@ int parse_archive_args(int argc, const char **argv, struct archiver *ar) printf("%s\n", archivers[i].name); exit(0); } - if (!strncmp(arg, "--format=", 9)) { + if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) { + verbose = 1; + continue; + } + if (!prefixcmp(arg, "--format=")) { format = arg + 9; continue; } - if (!strncmp(arg, "--prefix=", 9)) { + if (!prefixcmp(arg, "--prefix=")) { base = arg + 9; continue; } @@ -182,22 +190,22 @@ int parse_archive_args(int argc, const char **argv, struct archiver *ar) /* We need at least one parameter -- tree-ish */ if (argc - 1 < i) usage(archive_usage); - if (!format) - die("You must specify an archive format"); if (init_archiver(format, ar) < 0) die("Unknown archive format '%s'", format); if (extra_argc) { if (!ar->parse_extra) - die("%s", default_parse_extra(ar, extra_argv)); + die("'%s' format does not handle %s", + ar->name, extra_argv[0]); ar->args.extra = ar->parse_extra(extra_argc, extra_argv); } + ar->args.verbose = verbose; ar->args.base = base; return i; } -static const char *remote_request(int *ac, const char **av) +static const char *extract_remote_arg(int *ac, const char **av) { int ix, iy, cnt = *ac; int no_more_options = 0; @@ -208,7 +216,7 @@ static const char *remote_request(int *ac, const char **av) if (!strcmp(arg, "--")) no_more_options = 1; if (!no_more_options) { - if (!strncmp(arg, "--remote=", 9)) { + if (!prefixcmp(arg, "--remote=")) { if (remote) die("Multiple --remote specified"); remote = arg + 9; @@ -234,10 +242,12 @@ int cmd_archive(int argc, const char **argv, const char *prefix) int tree_idx; const char *remote = NULL; - remote = remote_request(&argc, argv); + remote = extract_remote_arg(&argc, argv); if (remote) return run_remote_archiver(remote, argc, argv); + setvbuf(stderr, NULL, _IOLBF, BUFSIZ); + memset(&ar, 0, sizeof(ar)); tree_idx = parse_archive_args(argc, argv, &ar); if (prefix == NULL)