git-archive: add --output=<file> to send output to a file
When archiving a repository there is no way to specify a file as output. This patch adds a new option "--output" that redirects the output to a file instead of stdout. Signed-off-by: Carlos Manuel Duclos Vergara <carlos.duclos@nokia.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Carlos Manuel Duclos Vergara committed
Feb 16, 2009 at 18:20 UTC
aec0c1bbfb2d42659bb710bd79f8228ac59e1b0c
3 files changed
+31
Documentation/git-archive.txt
+4
@@ -10,6 +10,7 @@ SYNOPSIS
10
--------
11
[verse]
12
'git archive' --format=<fmt> [--list] [--prefix=<prefix>/] [<extra>]
13
+ [--output=<file>]
14
[--remote=<repo> [--exec=<git-upload-archive>]] <tree-ish>
15
[path...]
16
@@ -47,6 +48,9 @@ OPTIONS
48
--prefix=<prefix>/::
49
Prepend <prefix>/ to each filename in the archive.
50
51
+--output=<file>::
52
+ Write the archive to <file> instead of stdout.
53
+
54
<extra>::
55
This can be any options that the archiver backend understand.
56
See next section.
archive.c
+19
@@ -239,6 +239,19 @@ static void parse_treeish_arg(const char **argv,
239
ar_args->time = archive_time;
240
}
241
242
+static void create_output_file(const char *output_file)
243
+{
244
+ int output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
245
+ if (output_fd < 0)
246
+ die("could not create archive file: %s ", output_file);
247
+ if (output_fd != 1) {
248
+ if (dup2(output_fd, 1) < 0)
249
+ die("could not redirect output");
250
+ else
251
+ close(output_fd);
252
+ }
253
+}
254
+
255
#define OPT__COMPR(s, v, h, p) \
256
{ OPTION_SET_INT, (s), NULL, (v), NULL, (h), \
257
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, (p) }
@@ -253,6 +266,7 @@ static int parse_archive_args(int argc, const char **argv,
266
const char *base = NULL;
267
const char *remote = NULL;
268
const char *exec = NULL;
269
+ const char *output = NULL;
270
int compression_level = -1;
271
int verbose = 0;
272
int i;
@@ -262,6 +276,8 @@ static int parse_archive_args(int argc, const char **argv,
276
OPT_STRING(0, "format", &format, "fmt", "archive format"),
277
OPT_STRING(0, "prefix", &base, "prefix",
278
"prepend prefix to each pathname in the archive"),
279
+ OPT_STRING(0, "output", &output, "file",
280
+ "write the archive to this file"),
281
OPT__VERBOSE(&verbose),
282
OPT__COMPR('0', &compression_level, "store only", 0),
283
OPT__COMPR('1', &compression_level, "compress faster", 1),
@@ -294,6 +310,9 @@ static int parse_archive_args(int argc, const char **argv,
310
if (!base)
311
base = "";
312
313
+ if (output)
314
+ create_output_file(output);
315
+
316
if (list) {
317
for (i = 0; i < ARRAY_SIZE(archivers); i++)
318
printf("%s\n", archivers[i].name);
t/t5000-tar-tree.sh
+8
@@ -86,6 +86,10 @@ test_expect_success \
86
'git archive vs. the same in a bare repo' \
87
'test_cmp b.tar b3.tar'
88
89
+test_expect_success 'git archive with --output' \
90
+ 'git archive --output=b4.tar HEAD &&
91
+ test_cmp b.tar b4.tar'
92
+
93
test_expect_success \
94
'validate file modification time' \
95
'mkdir extract &&
@@ -172,6 +176,10 @@ test_expect_success \
176
'git archive --format=zip vs. the same in a bare repo' \
177
'test_cmp d.zip d1.zip'
178
179
+test_expect_success 'git archive --format=zip with --output' \
180
+ 'git archive --format=zip --output=d2.zip HEAD &&
181
+ test_cmp d.zip d2.zip'
182
+
183
$UNZIP -v >/dev/null 2>&1
184
if [ $? -eq 127 ]; then
185
echo "Skipping ZIP tests, because unzip was not found"