Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2006 Franck Bui-Huu |
| 3 | * Copyright (c) 2006 Rene Scharfe |
| 4 | */ |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 5 | #include "cache.h" |
| 6 | #include "builtin.h" |
| 7 | #include "archive.h" |
| 8 | #include "commit.h" |
| 9 | #include "tree-walk.h" |
| 10 | #include "exec_cmd.h" |
| 11 | #include "pkt-line.h" |
Junio C Hamano | 23d6d11 | 2006-09-10 03:33:34 -0700 | [diff] [blame] | 12 | #include "sideband.h" |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 13 | #include "attr.h" |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 14 | |
| 15 | static const char archive_usage[] = \ |
Junio C Hamano | e0ffb24 | 2006-09-09 22:42:02 -0700 | [diff] [blame] | 16 | "git-archive --format=<fmt> [--prefix=<prefix>/] [--verbose] [<extra>] <tree-ish> [path...]"; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 17 | |
Shawn O. Pearce | 6c2f207 | 2006-11-05 00:37:23 -0500 | [diff] [blame] | 18 | static struct archiver_desc |
| 19 | { |
| 20 | const char *name; |
| 21 | write_archive_fn_t write_archive; |
| 22 | parse_extra_args_fn_t parse_extra; |
| 23 | } archivers[] = { |
| 24 | { "tar", write_tar_archive, NULL }, |
| 25 | { "zip", write_zip_archive, parse_extra_zip_args }, |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 26 | }; |
| 27 | |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 28 | static int run_remote_archiver(const char *remote, int argc, |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 29 | const char **argv) |
| 30 | { |
Junio C Hamano | 23d6d11 | 2006-09-10 03:33:34 -0700 | [diff] [blame] | 31 | char *url, buf[LARGE_PACKET_MAX]; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 32 | int fd[2], i, len, rv; |
Johannes Sixt | 98158e9 | 2007-10-19 21:47:53 +0200 | [diff] [blame] | 33 | struct child_process *conn; |
Junio C Hamano | fe5ab76 | 2006-09-10 04:02:57 -0700 | [diff] [blame] | 34 | const char *exec = "git-upload-archive"; |
| 35 | int exec_at = 0; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 36 | |
Junio C Hamano | fe5ab76 | 2006-09-10 04:02:57 -0700 | [diff] [blame] | 37 | for (i = 1; i < argc; i++) { |
| 38 | const char *arg = argv[i]; |
Junio C Hamano | 599065a | 2007-02-20 01:54:00 -0800 | [diff] [blame] | 39 | if (!prefixcmp(arg, "--exec=")) { |
Junio C Hamano | fe5ab76 | 2006-09-10 04:02:57 -0700 | [diff] [blame] | 40 | if (exec_at) |
| 41 | die("multiple --exec specified"); |
| 42 | exec = arg + 7; |
| 43 | exec_at = i; |
| 44 | break; |
| 45 | } |
| 46 | } |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 47 | |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 48 | url = xstrdup(remote); |
Johannes Sixt | 98158e9 | 2007-10-19 21:47:53 +0200 | [diff] [blame] | 49 | conn = git_connect(fd, url, exec, 0); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 50 | |
Junio C Hamano | fe5ab76 | 2006-09-10 04:02:57 -0700 | [diff] [blame] | 51 | for (i = 1; i < argc; i++) { |
| 52 | if (i == exec_at) |
| 53 | continue; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 54 | packet_write(fd[1], "argument %s\n", argv[i]); |
Junio C Hamano | fe5ab76 | 2006-09-10 04:02:57 -0700 | [diff] [blame] | 55 | } |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 56 | packet_flush(fd[1]); |
| 57 | |
| 58 | len = packet_read_line(fd[0], buf, sizeof(buf)); |
| 59 | if (!len) |
| 60 | die("git-archive: expected ACK/NAK, got EOF"); |
| 61 | if (buf[len-1] == '\n') |
| 62 | buf[--len] = 0; |
| 63 | if (strcmp(buf, "ACK")) { |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 64 | if (len > 5 && !prefixcmp(buf, "NACK ")) |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 65 | die("git-archive: NACK %s", buf + 5); |
| 66 | die("git-archive: protocol error"); |
| 67 | } |
| 68 | |
| 69 | len = packet_read_line(fd[0], buf, sizeof(buf)); |
| 70 | if (len) |
| 71 | die("git-archive: expected a flush"); |
| 72 | |
| 73 | /* Now, start reading from fd[0] and spit it out to stdout */ |
Nicolas Pitre | 9ac13ec | 2006-10-11 11:49:15 -0400 | [diff] [blame] | 74 | rv = recv_sideband("archive", fd[0], 1, 2); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 75 | close(fd[0]); |
Junio C Hamano | ec587fd | 2007-01-21 17:10:51 -0800 | [diff] [blame] | 76 | close(fd[1]); |
Johannes Sixt | 98158e9 | 2007-10-19 21:47:53 +0200 | [diff] [blame] | 77 | rv |= finish_connect(conn); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 78 | |
| 79 | return !!rv; |
| 80 | } |
| 81 | |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 82 | static void format_subst(const struct commit *commit, |
| 83 | const char *src, size_t len, |
| 84 | struct strbuf *buf) |
René Scharfe | df4a394 | 2007-09-07 00:34:06 +0200 | [diff] [blame] | 85 | { |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 86 | char *to_free = NULL; |
Pierre Habouzit | 674d172 | 2007-09-10 12:35:06 +0200 | [diff] [blame] | 87 | struct strbuf fmt; |
| 88 | |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 89 | if (src == buf->buf) |
Pierre Habouzit | b315c5c | 2007-09-27 12:58:23 +0200 | [diff] [blame] | 90 | to_free = strbuf_detach(buf, NULL); |
Pierre Habouzit | 674d172 | 2007-09-10 12:35:06 +0200 | [diff] [blame] | 91 | strbuf_init(&fmt, 0); |
René Scharfe | df4a394 | 2007-09-07 00:34:06 +0200 | [diff] [blame] | 92 | for (;;) { |
| 93 | const char *b, *c; |
René Scharfe | df4a394 | 2007-09-07 00:34:06 +0200 | [diff] [blame] | 94 | |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 95 | b = memmem(src, len, "$Format:", 8); |
| 96 | if (!b || src + len < b + 9) |
René Scharfe | df4a394 | 2007-09-07 00:34:06 +0200 | [diff] [blame] | 97 | break; |
| 98 | c = memchr(b + 8, '$', len - 8); |
| 99 | if (!c) |
| 100 | break; |
| 101 | |
Pierre Habouzit | 674d172 | 2007-09-10 12:35:06 +0200 | [diff] [blame] | 102 | strbuf_reset(&fmt); |
| 103 | strbuf_add(&fmt, b + 8, c - b - 8); |
René Scharfe | df4a394 | 2007-09-07 00:34:06 +0200 | [diff] [blame] | 104 | |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 105 | strbuf_add(buf, src, b - src); |
| 106 | format_commit_message(commit, fmt.buf, buf); |
| 107 | len -= c + 1 - src; |
| 108 | src = c + 1; |
René Scharfe | df4a394 | 2007-09-07 00:34:06 +0200 | [diff] [blame] | 109 | } |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 110 | strbuf_add(buf, src, len); |
Pierre Habouzit | 674d172 | 2007-09-10 12:35:06 +0200 | [diff] [blame] | 111 | strbuf_release(&fmt); |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 112 | free(to_free); |
René Scharfe | df4a394 | 2007-09-07 00:34:06 +0200 | [diff] [blame] | 113 | } |
| 114 | |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 115 | static int convert_to_archive(const char *path, |
| 116 | const void *src, size_t len, |
| 117 | struct strbuf *buf, |
| 118 | const struct commit *commit) |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 119 | { |
René Scharfe | 38c9c9b | 2007-09-06 18:51:11 +0200 | [diff] [blame] | 120 | static struct git_attr *attr_export_subst; |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 121 | struct git_attr_check check[1]; |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 122 | |
| 123 | if (!commit) |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 124 | return 0; |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 125 | |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 126 | if (!attr_export_subst) |
| 127 | attr_export_subst = git_attr("export-subst", 12); |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 128 | |
René Scharfe | 38c9c9b | 2007-09-06 18:51:11 +0200 | [diff] [blame] | 129 | check[0].attr = attr_export_subst; |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 130 | if (git_checkattr(path, ARRAY_SIZE(check), check)) |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 131 | return 0; |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 132 | if (!ATTR_TRUE(check[0].value)) |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 133 | return 0; |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 134 | |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 135 | format_subst(commit, src, len, buf); |
| 136 | return 1; |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 137 | } |
| 138 | |
| 139 | void *sha1_file_to_archive(const char *path, const unsigned char *sha1, |
| 140 | unsigned int mode, enum object_type *type, |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 141 | unsigned long *sizep, |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 142 | const struct commit *commit) |
| 143 | { |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 144 | void *buffer; |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 145 | |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 146 | buffer = read_sha1_file(sha1, type, sizep); |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 147 | if (buffer && S_ISREG(mode)) { |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 148 | struct strbuf buf; |
René Scharfe | c32f749 | 2007-10-21 11:23:49 +0200 | [diff] [blame] | 149 | size_t size = 0; |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 150 | |
Pierre Habouzit | 5ecd293 | 2007-09-16 15:51:04 +0200 | [diff] [blame] | 151 | strbuf_init(&buf, 0); |
| 152 | strbuf_attach(&buf, buffer, *sizep, *sizep + 1); |
| 153 | convert_to_working_tree(path, buf.buf, buf.len, &buf); |
| 154 | convert_to_archive(path, buf.buf, buf.len, &buf, commit); |
René Scharfe | c32f749 | 2007-10-21 11:23:49 +0200 | [diff] [blame] | 155 | buffer = strbuf_detach(&buf, &size); |
| 156 | *sizep = size; |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 157 | } |
| 158 | |
| 159 | return buffer; |
| 160 | } |
| 161 | |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 162 | static int init_archiver(const char *name, struct archiver *ar) |
| 163 | { |
| 164 | int rv = -1, i; |
| 165 | |
| 166 | for (i = 0; i < ARRAY_SIZE(archivers); i++) { |
| 167 | if (!strcmp(name, archivers[i].name)) { |
Shawn O. Pearce | 6c2f207 | 2006-11-05 00:37:23 -0500 | [diff] [blame] | 168 | memset(ar, 0, sizeof(*ar)); |
| 169 | ar->name = archivers[i].name; |
| 170 | ar->write_archive = archivers[i].write_archive; |
| 171 | ar->parse_extra = archivers[i].parse_extra; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 172 | rv = 0; |
| 173 | break; |
| 174 | } |
| 175 | } |
| 176 | return rv; |
| 177 | } |
| 178 | |
| 179 | void parse_pathspec_arg(const char **pathspec, struct archiver_args *ar_args) |
| 180 | { |
| 181 | ar_args->pathspec = get_pathspec(ar_args->base, pathspec); |
| 182 | } |
| 183 | |
| 184 | void parse_treeish_arg(const char **argv, struct archiver_args *ar_args, |
| 185 | const char *prefix) |
| 186 | { |
| 187 | const char *name = argv[0]; |
| 188 | const unsigned char *commit_sha1; |
| 189 | time_t archive_time; |
| 190 | struct tree *tree; |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 191 | const struct commit *commit; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 192 | unsigned char sha1[20]; |
| 193 | |
| 194 | if (get_sha1(name, sha1)) |
| 195 | die("Not a valid object name"); |
| 196 | |
| 197 | commit = lookup_commit_reference_gently(sha1, 1); |
| 198 | if (commit) { |
| 199 | commit_sha1 = commit->object.sha1; |
| 200 | archive_time = commit->date; |
| 201 | } else { |
| 202 | commit_sha1 = NULL; |
| 203 | archive_time = time(NULL); |
| 204 | } |
| 205 | |
| 206 | tree = parse_tree_indirect(sha1); |
| 207 | if (tree == NULL) |
| 208 | die("not a tree object"); |
| 209 | |
| 210 | if (prefix) { |
| 211 | unsigned char tree_sha1[20]; |
| 212 | unsigned int mode; |
| 213 | int err; |
| 214 | |
| 215 | err = get_tree_entry(tree->object.sha1, prefix, |
| 216 | tree_sha1, &mode); |
| 217 | if (err || !S_ISDIR(mode)) |
| 218 | die("current working directory is untracked"); |
| 219 | |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 220 | tree = parse_tree_indirect(tree_sha1); |
| 221 | } |
| 222 | ar_args->tree = tree; |
| 223 | ar_args->commit_sha1 = commit_sha1; |
René Scharfe | 8460b2f | 2007-09-03 20:07:01 +0200 | [diff] [blame] | 224 | ar_args->commit = commit; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 225 | ar_args->time = archive_time; |
| 226 | } |
| 227 | |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 228 | int parse_archive_args(int argc, const char **argv, struct archiver *ar) |
| 229 | { |
| 230 | const char *extra_argv[MAX_EXTRA_ARGS]; |
| 231 | int extra_argc = 0; |
René Scharfe | 8ff21b1 | 2007-04-09 17:12:53 +0200 | [diff] [blame] | 232 | const char *format = "tar"; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 233 | const char *base = ""; |
Junio C Hamano | e0ffb24 | 2006-09-09 22:42:02 -0700 | [diff] [blame] | 234 | int verbose = 0; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 235 | int i; |
| 236 | |
| 237 | for (i = 1; i < argc; i++) { |
| 238 | const char *arg = argv[i]; |
| 239 | |
| 240 | if (!strcmp(arg, "--list") || !strcmp(arg, "-l")) { |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 241 | for (i = 0; i < ARRAY_SIZE(archivers); i++) |
| 242 | printf("%s\n", archivers[i].name); |
| 243 | exit(0); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 244 | } |
Junio C Hamano | e0ffb24 | 2006-09-09 22:42:02 -0700 | [diff] [blame] | 245 | if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) { |
| 246 | verbose = 1; |
| 247 | continue; |
| 248 | } |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 249 | if (!prefixcmp(arg, "--format=")) { |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 250 | format = arg + 9; |
| 251 | continue; |
| 252 | } |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 253 | if (!prefixcmp(arg, "--prefix=")) { |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 254 | base = arg + 9; |
| 255 | continue; |
| 256 | } |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 257 | if (!strcmp(arg, "--")) { |
| 258 | i++; |
| 259 | break; |
| 260 | } |
| 261 | if (arg[0] == '-') { |
| 262 | if (extra_argc > MAX_EXTRA_ARGS - 1) |
| 263 | die("Too many extra options"); |
| 264 | extra_argv[extra_argc++] = arg; |
| 265 | continue; |
| 266 | } |
| 267 | break; |
| 268 | } |
| 269 | |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 270 | /* We need at least one parameter -- tree-ish */ |
| 271 | if (argc - 1 < i) |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 272 | usage(archive_usage); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 273 | if (init_archiver(format, ar) < 0) |
| 274 | die("Unknown archive format '%s'", format); |
| 275 | |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 276 | if (extra_argc) { |
| 277 | if (!ar->parse_extra) |
Rene Scharfe | 2232c0c | 2006-09-13 22:55:04 +0200 | [diff] [blame] | 278 | die("'%s' format does not handle %s", |
| 279 | ar->name, extra_argv[0]); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 280 | ar->args.extra = ar->parse_extra(extra_argc, extra_argv); |
| 281 | } |
Junio C Hamano | e0ffb24 | 2006-09-09 22:42:02 -0700 | [diff] [blame] | 282 | ar->args.verbose = verbose; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 283 | ar->args.base = base; |
| 284 | |
| 285 | return i; |
| 286 | } |
| 287 | |
Junio C Hamano | d751864 | 2006-09-12 22:42:31 -0700 | [diff] [blame] | 288 | static const char *extract_remote_arg(int *ac, const char **av) |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 289 | { |
| 290 | int ix, iy, cnt = *ac; |
| 291 | int no_more_options = 0; |
| 292 | const char *remote = NULL; |
| 293 | |
| 294 | for (ix = iy = 1; ix < cnt; ix++) { |
| 295 | const char *arg = av[ix]; |
| 296 | if (!strcmp(arg, "--")) |
| 297 | no_more_options = 1; |
| 298 | if (!no_more_options) { |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 299 | if (!prefixcmp(arg, "--remote=")) { |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 300 | if (remote) |
| 301 | die("Multiple --remote specified"); |
| 302 | remote = arg + 9; |
| 303 | continue; |
| 304 | } |
| 305 | if (arg[0] != '-') |
| 306 | no_more_options = 1; |
| 307 | } |
| 308 | if (ix != iy) |
| 309 | av[iy] = arg; |
| 310 | iy++; |
| 311 | } |
| 312 | if (remote) { |
| 313 | av[--cnt] = NULL; |
| 314 | *ac = cnt; |
| 315 | } |
| 316 | return remote; |
| 317 | } |
| 318 | |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 319 | int cmd_archive(int argc, const char **argv, const char *prefix) |
| 320 | { |
| 321 | struct archiver ar; |
| 322 | int tree_idx; |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 323 | const char *remote = NULL; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 324 | |
Junio C Hamano | d751864 | 2006-09-12 22:42:31 -0700 | [diff] [blame] | 325 | remote = extract_remote_arg(&argc, argv); |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 326 | if (remote) |
| 327 | return run_remote_archiver(remote, argc, argv); |
| 328 | |
Michal Rokos | aa90986 | 2006-11-21 23:19:28 +0100 | [diff] [blame] | 329 | setvbuf(stderr, NULL, _IOLBF, BUFSIZ); |
Junio C Hamano | 8142f60 | 2006-09-10 04:16:39 -0700 | [diff] [blame] | 330 | |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 331 | memset(&ar, 0, sizeof(ar)); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 332 | tree_idx = parse_archive_args(argc, argv, &ar); |
René Scharfe | 265d528 | 2007-04-05 22:55:43 +0200 | [diff] [blame] | 333 | if (prefix == NULL) |
| 334 | prefix = setup_git_directory(); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 335 | |
| 336 | argv += tree_idx; |
| 337 | parse_treeish_arg(argv, &ar.args, prefix); |
| 338 | parse_pathspec_arg(argv + 1, &ar.args); |
| 339 | |
| 340 | return ar.write_archive(&ar.args); |
| 341 | } |