gitオブジェクトを抽出するコマンドラインツールでデフレートする方法は?

StackOverflow https://stackoverflow.com/questions/3178566

  •  02-10-2019
  •  | 
  •  

質問

DEFLATEアルゴリズムのコマンドラインラッパーを探しています。

デフレートを使用して圧縮されるファイル(git blob)があり、それを非圧縮したいと思います。 GZIPコマンドには、GZIP形式ではなく、DERLATEアルゴリズムを直接使用するオプションがないようです。

理想的には、これを行うことができる標準のUNIX/Linuxツールを探しています。

編集:これは、問題にGZIPを使用しようとするときに得られる出力です。

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

gzip: stdin: not in gzip format
役に立ちましたか?

解決

アップデート: Mark Adlerは、Git Blobsは生の層ではなく、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!

私の元の答えは、歴史的な理由で保持されています:

のヒントを理解している場合 ウィキペディアの記事 Marc Van Kempenが言及して、使用できます puff.c から Zlib 直接。

これは小さな例です:

#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 );
}

他のヒント

次のようなものには、「$ type $ length 0」ヘッダーを含む生のコンテンツを印刷します。

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

OpenSSLコマンドラインツールでこれを行うことができます。

openssl zlib -d < $IN > $OUT

残念ながら、少なくともubuntuでは zlib サブコマンドは、デフォルトのビルド構成で無効になっています(--no-zlib --no-zlib-dynamic)、したがって、コンパイルする必要があります openssl ソースから使用します。ただし、たとえば、Archでデフォルトで有効になっています。

編集:のようです zlib コマンドはアーチでもサポートされなくなりました。この答えはもう役に立たないかもしれません:(

Pythonic One-Liner:

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

このようなZlib-flateを使用できます。

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

それは私のマシンにデフォルトでそこにありますが、それはの一部です qpdf - tools for and transforming and inspecting PDF files インストールする必要がある場合。

私はポップしました echo コマンドの最後に、出力をそのように読みやすくなります。

次のコマンドを試してください。

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

外部ツールは必要ありません。

ソース: UNIXでZLIBデータを非圧縮する方法は? Unix SEで

これはRuby One-Liner(cd .git/ firstと任意のオブジェクトへのパスを識別する)です。

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

私はこれに対して良い解決策を持っていないことにうんざりしたので、私はnpmに何かを置きました:

https://github.com/jezell/zlibber

これで、コマンドを膨らませる /デフレートするためにパイプすることができます。

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!

コマンドがヘッダーを印刷しないことを除いて、「git cat -file -p [hash]」の出力とほぼ同じです(コンテンツのサイズとnullバイトのサイズに続く)。

マーク・アドラーが私たちを念頭に置いているように見え、これを行う方法の例を書きました。 http://www.zlib.net/zpipe.c

それ以上にコンパイルされます gcc -lz Zlibヘッダーがインストールされました。結果のバイナリを自分にコピーしました /usr/local/bin/zpipe Gitのものを使用している間。

gitオブジェクトはによって圧縮されます zlib それよりも gzip, 、したがって、使用しています zlib それを非圧縮するか、gitコマンド、すなわち git cat-file -p <SHA1>, 、コンテンツを印刷します。

// 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()
}

$ go build deflate.go
$ ./deflate -f .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7

見る http://en.wikipedia.org/wiki/deflate#encoder_implementations

GZIPを含む多くのソフトウェア実装をリストしているため、機能するはずです。ファイルでGZIPを実行してみましたか?フォーマットが自動的に認識されませんか?

デフレートを使用して圧縮されていることをどうやって知っていますか?ファイルを圧縮するためにどのツールを使用しましたか?

Gitのツールを使用してデータにアクセスしてみませんか?これにより、任意のgitオブジェクトを読み取ることができるはずです。

git show --pretty=raw <object SHA-1>

私はこの質問を見つけました -text の新しいバージョンのユーティリティ hadoop dfs クライアント私はちょうどインストールしました。 -text ユーティリティは次のように機能します cat, 、読み取られているファイルが圧縮されている場合を除き、プレーンテキストを透過的に減圧および出力します(したがって名前)。

すでに投稿された回答は間違いなく役立ちましたが、Hadoopサイズの量のデータを処理する際には1つの問題があります。

だから、ここに私のバリエーションがあります PerlPython その上記の回答にはその制限がありません:

Python:

hadoop fs -cat /path/to/example.deflate |
  python -c 'import zlib,sys;map(lambda b:sys.stdout.write(zlib.decompress(b)),iter(lambda:sys.stdin.read(4096),""))'

Perl:

hadoop fs -cat /path/to/example.deflate |
  perl -MCompress::Zlib -e 'print uncompress($buf) while sysread(STDIN,$buf,4096)'

の使用に注意してください -cat 代わりにサブコマンド -text. 。これは、バグを修正した後、私の回答が壊れないようにするためです。 Pythonバージョンの読みやすさについてお詫びします。

gitオブジェクトはzlibストリームです(生のデフレートではありません)。 でそれらを減圧します -dz オプション。

出来る:

apt-get install pigz
unpigz -c .git/objects/c0/fb67ab3fda7909000da003f4b2ce50a53f43e7
const zlib = require("zlib");
const adler32 = require("adler32");
const data = "hello world~!";
const chksum = adler32.sum(new Buffer(data)).toString(16);
console.log("789c",zlib.deflateRawSync(data).toString("hex"),chksum);
// or
console.log(zlib.deflateSync(data).toString("hex"));

コレクションに追加するために、こちらがデフレート/インフレ/生のデフレート/生の膨張のためのパールワンライナーを紹介します。

デフレート

perl -MIO::Compress::Deflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Compress::Deflate::deflate(\$in, \$out); print $out;'

膨らみます

perl -MIO::Uncompress::Inflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Uncompress::Inflate::inflate(\$in, \$out); print $out;'

生のデフレート

perl -MIO::Compress::RawDeflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Compress::RawDeflate::rawdeflate(\$in, \$out); print $out;'

生の膨張

perl -MIO::Uncompress::RawInflate -e 'undef $/; my ($in, $out) = (<>, undef); IO::Uncompress::RawInflate::rawinflate(\$in, \$out); print $out;'
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top