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

Fel*_*fer 75 git blob deflate

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

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

理想情况下,我正在寻找可以做到这一点的标准Unix/Linux工具.

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

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

gzip: stdin: not in gzip format
Run Code Online (Sandbox Code Playgroud)

ara*_*nid 50

类似下面的内容将打印原始内容,包括"$ type $ length\0"标题:

perl -MCompress::Zlib -e 'undef $/; print uncompress(<>)' \
     < .git/objects/27/de0a1dd5a89a94990618632967a1c86a82d577
Run Code Online (Sandbox Code Playgroud)


Jac*_*nor 45

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

openssl zlib -d < $IN > $OUT
Run Code Online (Sandbox Code Playgroud)

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

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

  • 请注意,如果使用默认选项(包括`--no-)配置openssl的构建,则`zlib`子命令(以及`enc`子命令的`-z`选项)*不可用*zlib`和`--no-zlib-dynamic`.所以这个答案只有在你的openssl编译时从其中一个配置选项中删除了`no-`前缀时才有效.你可以通过在`openssl version -f`的输出中查找`-DZLIB`来判断 (12认同)
  • 不适用于带有 `LibreSSL 2.2.7` 的 Mac。我收到 `openssl:Error: 'zlib' is an invalid command.` (2认同)

aki*_*ira 39

pythonic单线程:

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


seu*_*mac 26

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

cat .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 \
    | zlib-flate -uncompress; echo
Run Code Online (Sandbox Code Playgroud)

它默认存在于我的机器上,但它是qpdf - tools for and transforming and inspecting PDF files你需要安装它的一部分.

echo在命令的末尾弹出一个,因为它更容易以这种方式读取输出.

  • 不需要cat:zlib-flate -uncompress <.git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 (2认同)

ken*_*orb 19

请尝试以下命令:

printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" | cat - .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7 | gunzip
Run Code Online (Sandbox Code Playgroud)

无需外部工具.

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

  • 只需添加一个gzip文件头.好:) (2认同)

tux*_*dna 14

这是一个Ruby一行代码(cd .git/first并识别任何对象的路径):

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


mkl*_*uwe 13

更新: 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!
Run Code Online (Sandbox Code Playgroud)

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

如果我的理解中提示Wikipedia文章由马克面包车Kempen的提到的,你可以使用puff.czlib的直接.

这是一个小例子:

#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 ] = '\0';
    assert( strcmp( dest, "asdf" ) == 0 );
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,我看着那个.但我肯定更喜欢一种常用的工具. (4认同)
  • 这是行不通的。git blob 是 zlib 流,而不是原始放气。此解决方案适用于原始放气。puff 不处理 zlib 头和尾。如果你想要一个实用程序,你可以使用[pigz](http://zlib.net/pigz),它会用`-dz`选项解压zlib格式,并用`-z`生成zlib格式. (4认同)

小智 11

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

https://github.com/jezell/zlibber

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


小智 9

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

$ 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!
Run Code Online (Sandbox Code Playgroud)

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

  • 根据操作系统的不同,您可能需要为`open`添加"rb"开关,如:`file = open(".git/objects/09/72d7651ff85bedf464fba868c2ef434543916a","rb")` (4认同)
  • +1用于解释标题的格式. (3认同)

小智 7

看起来马克·阿德勒(Mark Adler)想到了我们,并写了一个如何使用以下内容的示例:http://www.zlib.net/zpipe.c

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


Con*_*Guo 6

git对象是压缩zlib而不是gzip,因此要么使用zlib它来解压缩,要么使用git命令,即git cat-file -p <SHA1>打印内容.

  • 正如[Jack指出上面](http://stackoverflow.com/a/6539072/470844),`git cat-file -p <SHA1>`的输出是*不是*zlib解压缩的完整内容`的.git /对象/ <SHA1>`.如果您正在尝试实现Git提交哈希计算器,那么差异是关键... (3认同)

小智 5

// save this as deflate.go

package main

import (
    "compress/zlib"
    "io"
    "os"
    "flag"
)

var infile = flag.String("f", "", "infile")

func main() {
    flag.Parse()
    file, _ := os.Open(*infile)

    r, err := zlib.NewReader(file)
    if err != nil {
        panic(err)
    }
    io.Copy(os.Stdout, r)

    r.Close()
}
Run Code Online (Sandbox Code Playgroud)
$ go build deflate.go
$ ./deflate -f .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7
Run Code Online (Sandbox Code Playgroud)