2017-06-10 4 views
1

ファイルの実際の内容が.gitにどのように格納されているのか混乱します。GitオブジェクトSHA-1はファイルの内容またはファイル名ですか?

Version 1は、test.txtの実際のテキストコンテンツです。私がリポジトリにコミットすると(最初にコミット)、gitは.git\objects\0c\15af113a95643d7c244332b0e0b287184cd049にあるそのファイルのSHA-1を返します。

私は、テキストエディタでファイル15af113a95643d7c244332b0e0b287184cd049を開くと、それはすべてのゴミ、この

x+)JMU074f040031QÐKÏ,ÉLÏË/Je¨}ºõw[Éœ„ÇR­ ñ·Î}úyGª*±8#³¨,1%>9?¯$5¯D¯¤¢„áôÏ3%³þú>š~}Ž÷*ë²-¶ç¡êÊòR“KâKòãs+‹sô

のようなものだ。しかし、私はこのゴミは、テキストVersion 1の暗号化された形を表しているかどうかわからないか、それですSHA-1 15af113a95643d7c244332b0e0b287184cd049によって表される。

+2

https://git-scm.com/book/en/v2/Git-Internals-Git-Objects –

+0

これは私が今行っていることですが、ファイル内容の部分ではまだ分かりません。ここをクリックしてください。 – appu

+0

あなたの質問を編集して、そのリンクの「Object Storage」ヘッダーの説明の特定の側面について理解することはできますか? – jthill

答えて

2

件名に質問に対する正しい答え:

GitオブジェクトSHA-1はファイルの内容またはファイル名ですか?

は、元のファイルではなく緩いオブジェクトファイルの内容を参照していた可能性があります。元のファイルを参照していても、それはまだ正しくありません。

ルースオブジェクトは、Gitでプレーンファイルです。ファイルの名前は、オブジェクトのハッシュIDから作成されます。オブジェクトのハッシュIDは、オブジェクトの内容のハッシュを計算し、プレフィックスヘッダーがになるように構成されます。

プレフィックス付きヘッダーは、オブジェクトの種類によって異なります。blobcommittag、およびtreeの4種類があります。ヘッダーは、タイプ名からASCII(またはそれに相当するUTF-8)バイト文字列で構成されたゼロ終端のバイトストリングと、その後に続くスペースと、バイト単位のオブジェクトのサイズの10進数表現ASCII NUL(Pythonでb'\x00'、現代のPython表記を使用する場合は'\0')を使用してください。

ヘッダーの後に実際のオブジェクトの内容が来ます。だから、バイト列b'hello\n'を含むファイルに対して、ハッシュされるデータはb'blob 6\0hello\nから成る:

$ echo 'hello' | git hash-object -t blob --stdin 
ce013625030ba8dba906f756967f9e9ca394464a 
$ python3 
[...] 
>>> import hashlib 
>>> s = b'blob 6\0hello\n' 
>>> hashlib.sha1(s).hexdigest() 
'ce013625030ba8dba906f756967f9e9ca394464a' 

したがって、このファイルを格納するために使用されるファイル名はce013625030ba8dba906f756967f9e9ca394464a(由来)されます。緩いオブジェクトとしては、.git/objects/ce/013625030ba8dba906f756967f9e9ca394464aになります。

内容そのファイルのは、しかし、明らかに、level=1 -theのデフォルトは現在6で、結果はそのレベルで一致していない(とb'blob 6\0hello\n'のzlibの圧縮形式であり、それはGitリポジトリのzlibのかどうかは明らかではありません正確に)Pythonのと一致しますが、ここで働いたレベル1を使用して収縮:

$ echo 'hello' | git hash-object -w -t blob --stdin 
ce013625030ba8dba906f756967f9e9ca394464a 
$ vis .git/objects/ce/013625030ba8dba906f756967f9e9ca394464a 
x\^AK\M-J\M-IOR0c\M-HH\M-M\M-I\M-I\M-g\^B\000\^]\M-E\^D\^T$ 

(最終$は、シェルが再びプロンプトであることに注意してください。すぐに戻って

>>> import zlib 
>>> zlib.compress(s, 1) 
b'x\x01K\xca\xc9OR0c\xc8H\xcd\xc9\xc9\xe7\x02\x00\x1d\xc5\x04\x14' 
>>> import vis 
>>> print(vis.vis(zlib.compress(s, 1))) 
x\^AK\M-J\M-IOR0c\M-HH\M-M\M-I\M-I\M-g\^B\^@\^]\M-E\^D\^T 
)のpython3に

vis.pyである:

def vischr(byte): 
    "encode characters the way vis(1) does by default" 
    if byte in b' \t\n': 
     return chr(byte) 
    # control chars: \^X; del: \^? 
    if byte < 32 or byte == 127: 
     return r'\^' + chr(byte^64) 
    # printable characters, 32..126 
    if byte < 128: 
     return chr(byte) 
    # meta characters: prefix with \M^ or \M- 
    byte -= 128 
    if byte < 32 or byte == 127: 
     return r'\M^' + chr(byte^64) 
    return r'\M-' + chr(byte) 

def vis(bytestr): 
    "same as vis(1)" 
    return ''.join(vischr(c) for c in bytestr) 

visバイナリファイルの可逆が、印刷可能な符号を生成します。 cat -vの問題に対する私の1993年の答えです)。 (コミット下)Gitのリポジトリに格納されたファイルの名は、個々のtreeオブジェクトに保存されているだけとして、パス名コンポーネントを表示さ

注意。ツリーオブジェクトのハッシュIDを計算することは重要ではありません。私はgithash.pyの私の公開 "スクリプト"リポジトリでこれを行うPythonコードを持っています。

+0

少なくとも今度は、もっと簡潔でポイントです。 +1 – VonC

+0

良い解説をいただきありがとうございますが、Gitリポジトリ(コミット中)に保存されているファイルの名前は、個々のツリーオブジェクトに格納されているパス名のコンポーネントとしてしか表示されないことに注意してください。_ pls – appu

+0

コミットは'tree'オブジェクト(コミットとそのツリーオブジェクトを見る' git cat-file -p HEAD'を試してください)。ツリーオブジェクト自体はバイナリ形式で保存されていますが(githash.pyコードはリンクされています)、別の 'git cat-file -p'コマンドで印刷可能なテキストに変換できます。ツリーにオブジェクトIDが '1234567'の場合、' git cat-file -p 1234567'が表示されます。 – torek

0

Git Magicが言及:ところで

あなたが直接凝視べきではありませんので、.git /オブジェクト内のファイルはzlibので圧縮されています。 zpipe -dを介してそれらをフィルタリングし、またはタイプ(git cat-fileを使用して):

$ git cat-file -p .git/objects/0c/15af113a95643d7c244332b0e0b287184cd049 

zpipeで:

$ ./zpipe -d < .git/objects/0c/15af113a95643d7c244332b0e0b287184cd049 

注:zpipeために、私が最初にzpipe.cをコンパイルする必要がありました:

sudo apt-get install zlib1g-dev 
cd /usr/share/doc/zlib1g-dev/examples 
sudo gunzip zpipe.c.gz 
sudo gcc -o zpipe zpipe.c -lz 

次に:

あなたは、実際のコンテンツが続くタイプとコンテンツサイズで構成されるヘッダを参照してください

[email protected]:/mnt/d/git/seec$ /usr/share/doc/zlib1g-dev/examples/zpipe -d < .git/objects/0d/b6225927ef60e21138a9762c41ea0db714ca0d 
blob 2142 <full content there...> 

:よう

$ /usr/share/doc/zlib1g-dev/examples/zpipe -d < /usr/share/doc/zlib1g-dev/examples/zpipe -d < 

あなたは結果を取得します。ジェフKunkleから

見る "Understanding Git Internalsは"、ブロブ実際の内容の説明のために、8をスライド:

Jeff Kunkle

関連する問題