X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=builtin-archive.c;h=6dabdee2019d15d7deadfc094d0c1e5f101d09ca;hb=e70866f53a8d31cde6cfff6396ba0d1f64029afb;hp=651d1bf6d916b40c38be8e0c9000a277fb667349;hpb=ec06bff5e6f76b46c22a3b2c97452568f088fa3c;p=git.git diff --git a/builtin-archive.c b/builtin-archive.c index 651d1bf6d..6dabdee20 100644 --- a/builtin-archive.c +++ b/builtin-archive.c @@ -10,31 +10,50 @@ #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...]"; +"git-archive --format= [--prefix=/] [--verbose] [] [path...]"; struct archiver archivers[] = { - { .name = "tar", .write_archive = write_tar_archive }, - { .name = "zip", .write_archive = write_zip_archive }, + { + .name = "tar", + .write_archive = write_tar_archive, + }, + { + .name = "zip", + .write_archive = write_zip_archive, + .parse_extra = parse_extra_zip_args, + }, }; -static int run_remote_archiver(struct archiver *ar, int argc, +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 (!strncmp("--exec=", arg, 7)) { + if (exec_at) + die("multiple --exec specified"); + exec = arg + 7; + exec_at = i; + break; + } + } - url = xstrdup(ar->remote); - pid = git_connect(fd, url, buf); + url = xstrdup(remote); + pid = git_connect(fd, url, exec); if (pid < 0) return pid; for (i = 1; i < argc; i++) { - if (!strncmp(argv[i], "--remote=", 9)) + if (i == exec_at) continue; packet_write(fd[1], "argument %s\n", argv[i]); } @@ -56,8 +75,7 @@ static int run_remote_archiver(struct archiver *ar, 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, buf, sizeof(buf)); close(fd[0]); rv |= finish_connect(pid); @@ -127,32 +145,25 @@ 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 *remote = NULL; const char *base = ""; - int list = 0; + int verbose = 0; int i; for (i = 1; i < argc; i++) { const char *arg = argv[i]; if (!strcmp(arg, "--list") || !strcmp(arg, "-l")) { - list = 1; + for (i = 0; i < ARRAY_SIZE(archivers); i++) + printf("%s\n", archivers[i].name); + exit(0); + } + if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) { + verbose = 1; continue; } if (!strncmp(arg, "--format=", 9)) { @@ -163,10 +174,6 @@ int parse_archive_args(int argc, const char **argv, struct archiver *ar) base = arg + 9; continue; } - if (!strncmp(arg, "--remote=", 9)) { - remote = arg + 9; - continue; - } if (!strcmp(arg, "--")) { i++; break; @@ -180,44 +187,71 @@ int parse_archive_args(int argc, const char **argv, struct archiver *ar) break; } - if (list) { - if (!remote) { - for (i = 0; i < ARRAY_SIZE(archivers); i++) - printf("%s\n", archivers[i].name); - exit(0); - } - die("--list and --remote are mutually exclusive"); - } - - if (argc - i < 1) + /* 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 && !remote) { - if (!ar->parse_extra) { - die("%s", default_parse_extra(ar, extra_argv)); - } + if (extra_argc) { + if (!ar->parse_extra) + die("'%s' format does not handle %s", + ar->name, extra_argv[0]); ar->args.extra = ar->parse_extra(extra_argc, extra_argv); } - ar->remote = remote; + ar->args.verbose = verbose; ar->args.base = base; return i; } +static const char *extract_remote_arg(int *ac, const char **av) +{ + int ix, iy, cnt = *ac; + int no_more_options = 0; + const char *remote = NULL; + + for (ix = iy = 1; ix < cnt; ix++) { + const char *arg = av[ix]; + if (!strcmp(arg, "--")) + no_more_options = 1; + if (!no_more_options) { + if (!strncmp(arg, "--remote=", 9)) { + if (remote) + die("Multiple --remote specified"); + remote = arg + 9; + continue; + } + if (arg[0] != '-') + no_more_options = 1; + } + if (ix != iy) + av[iy] = arg; + iy++; + } + if (remote) { + av[--cnt] = NULL; + *ac = cnt; + } + return remote; +} + int cmd_archive(int argc, const char **argv, const char *prefix) { struct archiver ar; int tree_idx; + const char *remote = NULL; - tree_idx = parse_archive_args(argc, argv, &ar); + remote = extract_remote_arg(&argc, argv); + if (remote) + return run_remote_archiver(remote, argc, argv); - if (ar.remote) - return run_remote_archiver(&ar, argc, argv); + setlinebuf(stderr); + memset(&ar, 0, sizeof(ar)); + tree_idx = parse_archive_args(argc, argv, &ar); if (prefix == NULL) prefix = setup_git_directory();