5
#include "cache.h"
6
#include "builtin.h"
7
#include "archive.h"
8
+#include "parse-options.h"
9
#include "pkt-line.h"
10
#include "sideband.h"
11
11
-static int run_remote_archiver(const char *remote, int argc,
12
- const char **argv)
12
+static void create_output_file(const char *output_file)
13
+{
14
+ int output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
15
+ if (output_fd < 0)
16
+ die("could not create archive file: %s ", output_file);
17
+ if (output_fd != 1) {
18
+ if (dup2(output_fd, 1) < 0)
19
+ die("could not redirect output");
20
+ else
21
+ close(output_fd);
22
+ }
23
+}
24
+
25
+static int run_remote_archiver(int argc, const char **argv,
26
+ const char *remote, const char *exec)
27
{
28
char *url, buf[LARGE_PACKET_MAX];
29
int fd[2], i, len, rv;
30
struct child_process *conn;
17
- const char *exec = "git-upload-archive";
18
- int exec_at = 0, exec_value_at = 0;
19
-
20
- for (i = 1; i < argc; i++) {
21
- const char *arg = argv[i];
22
- if (!prefixcmp(arg, "--exec=")) {
23
- if (exec_at)
24
- die("multiple --exec specified");
25
- exec = arg + 7;
26
- exec_at = i;
27
- } else if (!strcmp(arg, "--exec")) {
28
- if (exec_at)
29
- die("multiple --exec specified");
30
- if (i + 1 >= argc)
31
- die("option --exec requires a value");
32
- exec = argv[i + 1];
33
- exec_at = i;
34
- exec_value_at = ++i;
35
- }
36
- }
31
32
url = xstrdup(remote);
33
conn = git_connect(fd, url, exec, 0);
34
41
- for (i = 1; i < argc; i++) {
42
- if (i == exec_at || i == exec_value_at)
43
- continue;
35
+ for (i = 1; i < argc; i++)
36
packet_write(fd[1], "argument %s\n", argv[i]);
45
- }
37
packet_flush(fd[1]);
38
39
len = packet_read_line(fd[0], buf, sizeof(buf));
60
return !!rv;
61
}
62
72
-static const char *extract_remote_arg(int *ac, const char **av)
73
-{
74
- int ix, iy, cnt = *ac;
75
- int no_more_options = 0;
76
- const char *remote = NULL;
77
-
78
- for (ix = iy = 1; ix < cnt; ix++) {
79
- const char *arg = av[ix];
80
- if (!strcmp(arg, "--"))
81
- no_more_options = 1;
82
- if (!no_more_options) {
83
- if (!prefixcmp(arg, "--remote=")) {
84
- if (remote)
85
- die("Multiple --remote specified");
86
- remote = arg + 9;
87
- continue;
88
- } else if (!strcmp(arg, "--remote")) {
89
- if (remote)
90
- die("Multiple --remote specified");
91
- if (++ix >= cnt)
92
- die("option --remote requires a value");
93
- remote = av[ix];
94
- continue;
95
- }
96
- if (arg[0] != '-')
97
- no_more_options = 1;
98
- }
99
- if (ix != iy)
100
- av[iy] = arg;
101
- iy++;
102
- }
103
- if (remote) {
104
- av[--cnt] = NULL;
105
- *ac = cnt;
106
- }
107
- return remote;
108
-}
63
+#define PARSE_OPT_KEEP_ALL ( PARSE_OPT_KEEP_DASHDASH | \
64
+ PARSE_OPT_KEEP_ARGV0 | \
65
+ PARSE_OPT_KEEP_UNKNOWN | \
66
+ PARSE_OPT_NO_INTERNAL_HELP )
67
68
int cmd_archive(int argc, const char **argv, const char *prefix)
69
{
70
+ const char *exec = "git-upload-archive";
71
+ const char *output = NULL;
72
const char *remote = NULL;
73
+ struct option local_opts[] = {
74
+ OPT_STRING(0, "output", &output, "file",
75
+ "write the archive to this file"),
76
+ OPT_STRING(0, "remote", &remote, "repo",
77
+ "retrieve the archive from remote repository <repo>"),
78
+ OPT_STRING(0, "exec", &exec, "cmd",
79
+ "path to the remote git-upload-archive command"),
80
+ OPT_END()
81
+ };
82
+
83
+ argc = parse_options(argc, argv, local_opts, NULL, PARSE_OPT_KEEP_ALL);
84
+
85
+ if (output)
86
+ create_output_file(output);
87
114
- remote = extract_remote_arg(&argc, argv);
88
if (remote)
116
- return run_remote_archiver(remote, argc, argv);
89
+ return run_remote_archiver(argc, argv, remote, exec);
90
91
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
92