Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] git-archive error, gzip -cn : command not found #2077

Merged
merged 2 commits into from
Feb 20, 2019
Merged

[FIX] git-archive error, gzip -cn : command not found #2077

merged 2 commits into from
Feb 20, 2019

Conversation

r1walz
Copy link

@r1walz r1walz commented Feb 15, 2019

git-archive uses gzip -cn to compress tar files but for this to work, gzip needs to be present on the host system, which sometimes is not the case.

In our implementation, we are trying to add minimal code that will mimic gzip compression, so as to get rid of this gzip dependency

Closes: #1970

Copy link
Member

@dscho dscho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great first version of that PR. I offered a couple of suggestions how to improve it, hopefully you agree with all of them...

archive-tar.c Outdated
if (gzip) {
if (gzwrite(gzip, block, BLOCKSIZE) != BLOCKSIZE) error("gzwrite failed");
if (gzwrite(gzip, block, (unsigned) BLOCKSIZE) != BLOCKSIZE) error("gzwrite failed");
} else write_or_die(1, block, BLOCKSIZE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please squash these two fixups into the previous commit, which introduces the bugs fixed here.

archive-tar.c Outdated
@@ -454,26 +455,36 @@ static int write_tar_filter_archive(const struct archiver *ar,
if (args->compression_level >= 0)
strbuf_addf(&cmd, " -%d", args->compression_level);

snprintf(outmode, sizeof(outmode), "%s%d", "wb", args->compression_level);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

snprintf() will no longer be allowed in Git for Windows' code base, as soon as v2.21.0 comes out. It is not even necessary here: you can write

char outmode[4] = "wb\0";
if (args->compression_level >= 0 && args->compression_level <= 9)
    outmode[2] = '0' + args->compression_level;

BTW please move the declaration of outmode to the if (!strcmp("gzip -cn", ar->data)) block, as that is the right scope for that variable.

archive-tar.c Outdated
die_errno(_("unable to redirect descriptor"));
close(filter.in);
if (finish_command(&filter) != 0)
die(_("'%s' filter reported error"), argv[0]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think that this is correct. At this point, the filter cannot have received any input, so if we think it should exit here, then it definitely won't have written the data we want.

Instead, we need to leave the finish_command() statement where it is (if indented one level because it will be in the conditional else block of the if (gzip)).

archive-tar.c Outdated
die(_("'%s' filter reported error"), argv[0]);
if (gzip) {
if (gzclose(gzip) != Z_OK) error("failed gzclose");
} else close(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The finish_command() still needs to be here, albeit in the else block now.

archive-tar.c Outdated

strbuf_release(&cmd);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? I do not quite understand why we no longer release cmd here. Could you explain? (Or in the alternative, revert this change?)

archive-tar.c Outdated
@@ -38,11 +37,18 @@ static int write_tar_filter_archive(const struct archiver *ar,
#define USTAR_MAX_MTIME 077777777777ULL
#endif

/* writes out the whole block */
static void write_block(const char * block) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might make sense to call it write_block_or_die() and use die() instead of error() in case gzwrite() fails. That would make the gzip code more consistent with the !gzip one.

archive-tar.c Outdated
/* writes out the whole block */
static void write_block(const char * block) {
if (gzip) {
if (gzwrite(gzip, block, BLOCKSIZE) != BLOCKSIZE) error("gzwrite failed");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Git's source code, we never have conditional statements on the same line as the if keyword. Please always put the conditional statements into their own line, whether with or without curlies is up to you, but it needs to be an own line.

archive-tar.c Outdated
@@ -14,9 +14,8 @@

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second paragraph of the commit message talks about "our implementation", but it actually wants to talk about the next commit (because there is no "our implementation" before the next commit yet...).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except for the line "replace write_or_die() calls with write_block_or_die()", this commit message would now fit better onto the second commit than onto this one...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better commit message for this here commit might be:

archive: replace write_or_die() calls with write_block_or_die()

In the next commit, we will change the gzip compression so
that we no longer spawn `gzip` but let zlib perform the
compression in the same process.

In preparation for this, we consolidate all the block writes into a
single function.

archive-tar.c Show resolved Hide resolved
archive-tar.c Outdated
static int tar_umask = 002;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you leave the whitespace of unrelated code untouched, please? 😃

archive-tar.c Show resolved Hide resolved
archive-tar.c Outdated
@@ -14,9 +14,8 @@

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better commit message for this here commit might be:

archive: replace write_or_die() calls with write_block_or_die()

In the next commit, we will change the gzip compression so
that we no longer spawn `gzip` but let zlib perform the
compression in the same process.

In preparation for this, we consolidate all the block writes into a
single function.

archive-tar.c Outdated
die_errno(_("unable to redirect descriptor"));
close(filter.in);
if (!strcmp("gzip -cn", ar->data)) {
char outmode[4] = "wb6\0";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not "wb\0\0"? The previous code did not default to compression level 6, after all, but let zlib decided...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better "wb\0", actually, as that automatically NUL terminates, i.e. it is already 4 bytes long.

archive-tar.c Outdated
die(_("'%s' filter reported error"), argv[0]);
if (gzip) {
if (gzclose(gzip) != Z_OK)
die(_("failed gzclose"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe "gzclose failed"?

@dscho
Copy link
Member

dscho commented Feb 19, 2019

This is now very close! Just a little cleanup of the commit messages (they seem to have been mixed up, the current first commit message would look better on the second commit, and I offered a suggestion how the first commit message might look like), and a few touchups of the patches, and we're done!

MinGit for Windows comes without `gzip` bundled inside,
git-archive uses `gzip -cn` to compress tar files but
for this to work, gzip needs to be present on the host
system, which sometimes is not the case

In the next commit, we will change the gzip compression
so that we no longer spawn `gzip` but let zlib perform
the compression in the same process

In preparation for this, we consolidate all the block
writes into a single function

Closes: #1970
Signed-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com>
As we already link to `zlib` library, we can perform the
compression without even requiring gzip on the host
machine

We modify write_tar_filter_archive() function in archive-tar.c
to handle the compression when `gzip -cn` is requested

Signed-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com>
@dscho dscho merged commit ed2b22a into git-for-windows:master Feb 20, 2019
@dscho dscho added this to the v2.20.1(2) milestone Feb 20, 2019
dscho added a commit to dscho/git that referenced this pull request Feb 20, 2019
[FIX] git-archive error, gzip -cn : command not found
dscho added a commit to git-for-windows/build-extra that referenced this pull request Feb 20, 2019
`git archive` [no longer requires `gzip` to generate `.tgz`
archives](git-for-windows/git#2077) (this
means in particular that it works in MinGit).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@r1walz r1walz deleted the gzip-cmd-404 branch February 20, 2019 21:23
dscho added a commit to dscho/git that referenced this pull request Feb 21, 2019
We accepted a Pull Request into `master`, but the main development
happens on the topic branch `rebase-to-v2.21.0` right now, in
preparation for the final v2.21.0 in a couple of days.

So after we forward-ported the changes in a6567c7 (Merge pull
request git-for-windows#2077 from r1walz/gzip-cmd-404, 2019-02-20), it is now time to
pull in the commit history of origin/master in a fake merge (i.e. with
`-s ours`), to make `master` fast-forward to `rebase-to-v2.21.0` again.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
git-for-windows-ci pushed a commit that referenced this pull request Feb 22, 2019
[FIX] git-archive error, gzip -cn : command not found
git-for-windows-ci pushed a commit that referenced this pull request Feb 22, 2019
[FIX] git-archive error, gzip -cn : command not found
git-for-windows-ci pushed a commit that referenced this pull request Feb 23, 2019
[FIX] git-archive error, gzip -cn : command not found
git-for-windows-ci pushed a commit that referenced this pull request Feb 23, 2019
[FIX] git-archive error, gzip -cn : command not found
r1walz added a commit to r1walz/git-patches that referenced this pull request Jul 2, 2019
r1walz added a commit to r1walz/git-patches that referenced this pull request Aug 20, 2019
r1walz added a commit to r1walz/git-patches that referenced this pull request Aug 20, 2019
r1walz added a commit to r1walz/git-patches that referenced this pull request Aug 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants