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 <johannes.schindelin@gmx.de>
This commit is contained in:
Johannes Schindelin
2019-02-21 11:06:57 +01:00
committed by Derrick Stolee

View File

@@ -17,6 +17,8 @@ static unsigned long offset;
static int tar_umask = 002;
static gzFile gzip;
static int write_tar_filter_archive(const struct archiver *ar,
struct archiver_args *args);
@@ -38,11 +40,21 @@ static int write_tar_filter_archive(const struct archiver *ar,
#define USTAR_MAX_MTIME 077777777777ULL
#endif
/* writes out the whole block, or dies if fails */
static void write_block_or_die(const char *block) {
if (gzip) {
if (gzwrite(gzip, block, (unsigned) BLOCKSIZE) != BLOCKSIZE)
die(_("gzwrite failed"));
} else {
write_or_die(1, block, BLOCKSIZE);
}
}
/* writes out the whole block, but only if it is full */
static void write_if_needed(void)
{
if (offset == BLOCKSIZE) {
write_or_die(1, block, BLOCKSIZE);
write_block_or_die(block);
offset = 0;
}
}
@@ -66,7 +78,7 @@ static void do_write_blocked(const void *data, unsigned long size)
write_if_needed();
}
while (size >= BLOCKSIZE) {
write_or_die(1, buf, BLOCKSIZE);
write_block_or_die(buf);
size -= BLOCKSIZE;
buf += BLOCKSIZE;
}
@@ -101,10 +113,10 @@ static void write_trailer(void)
{
int tail = BLOCKSIZE - offset;
memset(block + offset, 0, tail);
write_or_die(1, block, BLOCKSIZE);
write_block_or_die(block);
if (tail < 2 * RECORDSIZE) {
memset(block, 0, offset);
write_or_die(1, block, BLOCKSIZE);
write_block_or_die(block);
}
}
@@ -461,18 +473,34 @@ static int write_tar_filter_archive(const struct archiver *ar,
filter.use_shell = 1;
filter.in = -1;
if (start_command(&filter) < 0)
die_errno(_("unable to start '%s' filter"), argv[0]);
close(1);
if (dup2(filter.in, 1) < 0)
die_errno(_("unable to redirect descriptor"));
close(filter.in);
if (!strcmp("gzip -cn", ar->data)) {
char outmode[4] = "wb\0";
if (args->compression_level >= 0 && args->compression_level <= 9)
outmode[2] = '0' + args->compression_level;
gzip = gzdopen(fileno(stdout), outmode);
if (!gzip)
die(_("Could not gzdopen stdout"));
} else {
if (start_command(&filter) < 0)
die_errno(_("unable to start '%s' filter"), argv[0]);
close(1);
if (dup2(filter.in, 1) < 0)
die_errno(_("unable to redirect descriptor"));
close(filter.in);
}
r = write_tar_archive(ar, args);
close(1);
if (finish_command(&filter) != 0)
die(_("'%s' filter reported error"), argv[0]);
if (gzip) {
if (gzclose(gzip) != Z_OK)
die(_("gzclose failed"));
} else {
close(1);
if (finish_command(&filter) != 0)
die(_("'%s' filter reported error"), argv[0]);
}
strbuf_release(&cmd);
return r;