如何使用命令行工具进行 DEFLATE 以提取 git 对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3178566/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 08:40:27  来源:igfitidea点击:

How to DEFLATE with a command line tool to extract a git object?

gitblobdeflate

提问by Felix Geisend?rfer

I'm looking for a command line wrapper for the DEFLATE algorithm.

我正在寻找 DEFLATE 算法的命令行包装器。

I have a file (git blob) that is compressed using DEFLATE, and I want to uncompress it. The gzip command does not seem to have an option to directly use the DEFLATE algorithm, rather than the gzip format.

我有一个使用 DEFLATE 压缩的文件 (git blob),我想解压缩它。gzip 命令似乎没有直接使用 DEFLATE 算法的选项,而不是 gzip 格式。

Ideally I'm looking for a standard Unix/Linux tool that can do this.

理想情况下,我正在寻找可以执行此操作的标准 Unix/Linux 工具。

edit: This is the output I get when trying to use gzip for my problem:

编辑:这是我尝试使用 gzip 解决我的问题时得到的输出:

$ cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip

gzip: stdin: not in gzip format

采纳答案by mkluwe

UPDATE:Mark Adler noted that git blobs are not raw DEFLATE streams, but zlib streams. These can be unpacked by the pigztool, which comes pre-packaged in several Linux distributions:

更新:Mark Adler 指出 git blob 不是原始的 DEFLATE 流,而是 zlib 流。这些可以通过该pigz工具解压缩,该工具预打包在多个 Linux 发行版中:

$ cat foo.txt 
file foo.txt!

$ git ls-files -s foo.txt
100644 7a79fc625cac65001fb127f468847ab93b5f8b19 0   foo.txt

$ pigz -d < .git/objects/7a/79fc625cac65001fb127f468847ab93b5f8b19 
blob 14file foo.txt!

My original answer, kept for historical reasons:

我的原始答案,因历史原因而保留:

If I understand the hint in the Wikipedia articlementioned by Marc van Kempen, you can use puff.cfrom zlibdirectly.

如果我理解了Marc van Kempen 提到的维基百科文章中的提示,您可以直接puff.czlib使用。

This is a small example:

这是一个小例子:

#include <assert.h>
#include <string.h>
#include "puff.h"

int main( int argc, char **argv ) {
    unsigned char dest[ 5 ];
    unsigned long destlen = 4;
    const unsigned char *source = "\x4B\x2C\x4E\x49\x03\x00";
    unsigned long sourcelen = 6;    
    assert( puff( dest, &destlen, source, &sourcelen ) == 0 );
    dest[ 4 ] = '
perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)' \
     < .git/objects/27/de0a1dd5a89a94990618632967a1c86a82d577
'; assert( strcmp( dest, "asdf" ) == 0 ); }

回答by araqnid

Something like the following will print the raw content, including the "$type $length\0" header:

类似以下内容将打印原始内容,包括“$type $length\0”标题:

openssl zlib -d < $IN > $OUT

回答by Hyman O'Connor

You can do this with the OpenSSL command line tool:

您可以使用 OpenSSL 命令行工具执行此操作:

$> python -c "import zlib,sys;print \
           repr(zlib.decompress(sys.stdin.read()))" < $IN

Unfortunately, at least on Ubuntu, the zlibsubcommand is disabled in the default build configuration (--no-zlib--no-zlib-dynamic), so you would need to compile opensslfrom source to use it. But it is enabled by default on Arch, for example.

不幸的是,至少在 Ubuntu 上,zlib子命令在默认构建配置 ( --no-zlib--no-zlib-dynamic) 中被禁用,因此您需要openssl从源代码编译才能使用它。但是,例如,它在 Arch 上默认启用。

Edit: Seems like the zlibcommand is no longer supported on Arch either. This answer might not be useful anymore :(

编辑:似乎zlibArch 也不再支持该命令。这个答案可能不再有用:(

回答by akira

pythonic one-liner:

pythonic单线:

cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 \
    | zlib-flate -uncompress; echo

回答by seumasmac

You can use zlib-flate, like this:

您可以使用 zlib-flate,如下所示:

printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" | cat - .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip

It's there by default on my machine, but it's part of qpdf - tools for and transforming and inspecting PDF filesif you need to install it.

它在我的机器上默认存在,但qpdf - tools for and transforming and inspecting PDF files如果您需要安装它,它就是其中的一部分。

I've popped an echoon the end of the command, as it's easier to read the output that way.

echo在命令的末尾弹出了一个,因为这样更容易阅读输出。

回答by kenorb

Try the following command:

尝试以下命令:

ruby -rzlib -e 'print Zlib::Inflate.new.inflate(STDIN.read)' < ./74/c757240ec596063af8cd273ebd9f67073e1208

No external tools are needed.

不需要外部工具。

Source: How to uncompress zlib data in UNIX?at unix SE

来源:如何在 UNIX 中解压缩 zlib 数据?在 unix SE

回答by tuxdna

Here is a Ruby one-liner ( cd .git/ first and identify path to any object ):

这是一个 Ruby 单行( cd .git/ 首先并确定任何对象的路径):

$ git show
commit 0972d7651ff85bedf464fba868c2ef434543916a
# all the junk in my commit...
$ python
>>> import zlib
>>> file = open(".git/objects/09/72d7651ff85bedf464fba868c2ef434543916a")
>>> data = file.read()
>>> print data
# binary garbage
>>> unzipped_data = zlib.decompress(data)
>>> print unzipped_data
# all the junk in my commit!

回答by Jesse Ezell

I got tired of not having a good solution for this, so I put something on NPM:

我厌倦了没有一个好的解决方案,所以我在 NPM 上放了一些东西:

https://github.com/jezell/zlibber

https://github.com/jezell/zlibber

Now can just pipe to inflate / deflate command.

现在可以通过管道来充气/放气命令。

回答by Hyman O'Connor

Here's a example of breaking open a commit object in Python:

这是在 Python 中打开提交对象的示例:

##代码##

What you will see there is almost identical to the output of 'git cat-file -p [hash]', except that command doesn't print the header ('commit' followed by the size of the content and a null byte).

您将看到的内容几乎与 'git cat-file -p [hash]' 的输出相同,只是该命令不打印标题('commit' 后跟内容的大小和空字节)。

回答by Tim Caswell

Looks like Mark Adler has us in mind and wrote an example of just how to do this with: http://www.zlib.net/zpipe.c

看起来 Mark Adler 已经想到了我们,并写了一个例子来说明如何做到这一点:http: //www.zlib.net/zpipe.c

It compiles with nothing more than gcc -lzand the zlib headers installed. I copied the resulting binary to my /usr/local/bin/zpipewhile working with git stuff.

它只编译gcc -lz并安装了 zlib 头文件。我/usr/local/bin/zpipe在使用 git 东西时将生成的二进制文件复制到我的。