Skip to content

Commit aec0c1b

Browse files
Carlos Manuel Duclos Vergaragitster
authored andcommitted
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>
1 parent 734cd57 commit aec0c1b

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

Documentation/git-archive.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ SYNOPSIS
1010
--------
1111
[verse]
1212
'git archive' --format=<fmt> [--list] [--prefix=<prefix>/] [<extra>]
13+
[--output=<file>]
1314
[--remote=<repo> [--exec=<git-upload-archive>]] <tree-ish>
1415
[path...]
1516

@@ -47,6 +48,9 @@ OPTIONS
4748
--prefix=<prefix>/::
4849
Prepend <prefix>/ to each filename in the archive.
4950

51+
--output=<file>::
52+
Write the archive to <file> instead of stdout.
53+
5054
<extra>::
5155
This can be any options that the archiver backend understand.
5256
See next section.

archive.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,19 @@ static void parse_treeish_arg(const char **argv,
239239
ar_args->time = archive_time;
240240
}
241241

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+
242255
#define OPT__COMPR(s, v, h, p) \
243256
{ OPTION_SET_INT, (s), NULL, (v), NULL, (h), \
244257
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, (p) }
@@ -253,6 +266,7 @@ static int parse_archive_args(int argc, const char **argv,
253266
const char *base = NULL;
254267
const char *remote = NULL;
255268
const char *exec = NULL;
269+
const char *output = NULL;
256270
int compression_level = -1;
257271
int verbose = 0;
258272
int i;
@@ -262,6 +276,8 @@ static int parse_archive_args(int argc, const char **argv,
262276
OPT_STRING(0, "format", &format, "fmt", "archive format"),
263277
OPT_STRING(0, "prefix", &base, "prefix",
264278
"prepend prefix to each pathname in the archive"),
279+
OPT_STRING(0, "output", &output, "file",
280+
"write the archive to this file"),
265281
OPT__VERBOSE(&verbose),
266282
OPT__COMPR('0', &compression_level, "store only", 0),
267283
OPT__COMPR('1', &compression_level, "compress faster", 1),
@@ -294,6 +310,9 @@ static int parse_archive_args(int argc, const char **argv,
294310
if (!base)
295311
base = "";
296312

313+
if (output)
314+
create_output_file(output);
315+
297316
if (list) {
298317
for (i = 0; i < ARRAY_SIZE(archivers); i++)
299318
printf("%s\n", archivers[i].name);

t/t5000-tar-tree.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ test_expect_success \
8686
'git archive vs. the same in a bare repo' \
8787
'test_cmp b.tar b3.tar'
8888

89+
test_expect_success 'git archive with --output' \
90+
'git archive --output=b4.tar HEAD &&
91+
test_cmp b.tar b4.tar'
92+
8993
test_expect_success \
9094
'validate file modification time' \
9195
'mkdir extract &&
@@ -172,6 +176,10 @@ test_expect_success \
172176
'git archive --format=zip vs. the same in a bare repo' \
173177
'test_cmp d.zip d1.zip'
174178

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+
175183
$UNZIP -v >/dev/null 2>&1
176184
if [ $? -eq 127 ]; then
177185
echo "Skipping ZIP tests, because unzip was not found"

0 commit comments

Comments
 (0)