Skip to content

Commit bf775f5

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 8eff8ca + eb948f7 commit bf775f5

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

@@ -446,18 +458,34 @@ static int write_tar_filter_archive(const struct archiver *ar,
446458
filter.use_shell = 1;
447459
filter.in = -1;
448460

449-
if (start_command(&filter) < 0)
450-
die_errno(_("unable to start '%s' filter"), argv[0]);
451-
close(1);
452-
if (dup2(filter.in, 1) < 0)
453-
die_errno(_("unable to redirect descriptor"));
454-
close(filter.in);
461+
if (!strcmp("gzip -cn", ar->data)) {
462+
char outmode[4] = "wb\0";
463+
464+
if (args->compression_level >= 0 && args->compression_level <= 9)
465+
outmode[2] = '0' + args->compression_level;
466+
467+
gzip = gzdopen(fileno(stdout), outmode);
468+
if (!gzip)
469+
die(_("Could not gzdopen stdout"));
470+
} else {
471+
if (start_command(&filter) < 0)
472+
die_errno(_("unable to start '%s' filter"), argv[0]);
473+
close(1);
474+
if (dup2(filter.in, 1) < 0)
475+
die_errno(_("unable to redirect descriptor"));
476+
close(filter.in);
477+
}
455478

456479
r = write_tar_archive(ar, args);
457480

458-
close(1);
459-
if (finish_command(&filter) != 0)
460-
die(_("'%s' filter reported error"), argv[0]);
481+
if (gzip) {
482+
if (gzclose(gzip) != Z_OK)
483+
die(_("gzclose failed"));
484+
} else {
485+
close(1);
486+
if (finish_command(&filter) != 0)
487+
die(_("'%s' filter reported error"), argv[0]);
488+
}
461489

462490
strbuf_release(&cmd);
463491
return r;

0 commit comments

Comments
 (0)