Skip to content

Commit 671df31

Browse files
dschoGit for Windows Build Agent
authored andcommitted
Merge branch 'dont-spawn-gzip-in-archive'
This topic branch avoids spawning `gzip` when asking `git archive` to create `.tar.gz` files. Signed-off-by: Johannes Schindelin <[email protected]>
2 parents 2f1c689 + 4b4907e commit 671df31

File tree

1 file changed

+41
-13
lines changed

1 file changed

+41
-13
lines changed

archive-tar.c

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ static unsigned long offset;
1717

1818
static int tar_umask = 002;
1919

20+
static gzFile gzip;
21+
2022
static int write_tar_filter_archive(const struct archiver *ar,
2123
struct archiver_args *args);
2224

@@ -38,11 +40,21 @@ static int write_tar_filter_archive(const struct archiver *ar,
3840
#define USTAR_MAX_MTIME 077777777777ULL
3941
#endif
4042

43+
/* writes out the whole block, or dies if fails */
44+
static void write_block_or_die(const char *block) {
45+
if (gzip) {
46+
if (gzwrite(gzip, block, (unsigned) BLOCKSIZE) != BLOCKSIZE)
47+
die(_("gzwrite failed"));
48+
} else {
49+
write_or_die(1, block, BLOCKSIZE);
50+
}
51+
}
52+
4153
/* writes out the whole block, but only if it is full */
4254
static void write_if_needed(void)
4355
{
4456
if (offset == BLOCKSIZE) {
45-
write_or_die(1, block, BLOCKSIZE);
57+
write_block_or_die(block);
4658
offset = 0;
4759
}
4860
}
@@ -66,7 +78,7 @@ static void do_write_blocked(const void *data, unsigned long size)
6678
write_if_needed();
6779
}
6880
while (size >= BLOCKSIZE) {
69-
write_or_die(1, buf, BLOCKSIZE);
81+
write_block_or_die(buf);
7082
size -= BLOCKSIZE;
7183
buf += BLOCKSIZE;
7284
}
@@ -101,10 +113,10 @@ static void write_trailer(void)
101113
{
102114
int tail = BLOCKSIZE - offset;
103115
memset(block + offset, 0, tail);
104-
write_or_die(1, block, BLOCKSIZE);
116+
write_block_or_die(block);
105117
if (tail < 2 * RECORDSIZE) {
106118
memset(block, 0, offset);
107-
write_or_die(1, block, BLOCKSIZE);
119+
write_block_or_die(block);
108120
}
109121
}
110122

@@ -461,18 +473,34 @@ static int write_tar_filter_archive(const struct archiver *ar,
461473
filter.use_shell = 1;
462474
filter.in = -1;
463475

464-
if (start_command(&filter) < 0)
465-
die_errno(_("unable to start '%s' filter"), argv[0]);
466-
close(1);
467-
if (dup2(filter.in, 1) < 0)
468-
die_errno(_("unable to redirect descriptor"));
469-
close(filter.in);
476+
if (!strcmp("gzip -cn", ar->data)) {
477+
char outmode[4] = "wb\0";
478+
479+
if (args->compression_level >= 0 && args->compression_level <= 9)
480+
outmode[2] = '0' + args->compression_level;
481+
482+
gzip = gzdopen(fileno(stdout), outmode);
483+
if (!gzip)
484+
die(_("Could not gzdopen stdout"));
485+
} else {
486+
if (start_command(&filter) < 0)
487+
die_errno(_("unable to start '%s' filter"), argv[0]);
488+
close(1);
489+
if (dup2(filter.in, 1) < 0)
490+
die_errno(_("unable to redirect descriptor"));
491+
close(filter.in);
492+
}
470493

471494
r = write_tar_archive(ar, args);
472495

473-
close(1);
474-
if (finish_command(&filter) != 0)
475-
die(_("'%s' filter reported error"), argv[0]);
496+
if (gzip) {
497+
if (gzclose(gzip) != Z_OK)
498+
die(_("gzclose failed"));
499+
} else {
500+
close(1);
501+
if (finish_command(&filter) != 0)
502+
die(_("'%s' filter reported error"), argv[0]);
503+
}
476504

477505
strbuf_release(&cmd);
478506
return r;

0 commit comments

Comments
 (0)