1

最初に、roseという名前のファイルを含むリポジトリを初期化します

$: echo sweet > rose
$: git init
$: git add .
$: find .git/objects/ -type f
.git/objects/aa/823728ea7d592acc69b36875a482cdf3fd5c8d
$: git commit -m "rose"
$: find .git/objects/ -type f -printf "%h%f %s\n"
.git/objects/05b217bb859794d08bb9e4f7f04cbda4b207fbe9 49
.git/objects/aa823728ea7d592acc69b36875a482cdf3fd5c8d 21
.git/objects/665d02ccbacdde1c0f2eecde01fbf47144ddd492 124

次に、BLOBをShaして、ツリーオブジェクトのIDを生成する方法を確認します。

echo -e "tree 21\0100644 rose\0aa823728ea7d592acc69b36875a482cdf3fd5c8d"|sha1sum

それが印刷するものは05b217bb859794d08bb9e4f7f04cbda4b207fbe9
どこに間違っていますか?

4

3 に答える 3

3

echo-n(省略改行)フラグを指定しない限り、デフォルトで改行を挿入します。

また、blob IDはASCII形式ではなく、バイナリ値として保存されます。これにより、オブジェクトサイズは32(21ではなく)になります。

次のコマンドは、正しい出力を提供します。

echo -en 'tree 32\x00100644 rose\x00\xaa\x82\x37\x28\xea\x7d\x59\x2a\xcc\x69\xb3\x68\x75\xa4\x82\xcd\xf3\xfd\x5c\x8d' | sha1sum
于 2012-12-20T17:00:19.027 に答える
3

ツリー内のオブジェクトIDは、その形式では保存されません。見てください:

git cat-file tree 05b217bb859794d08bb9e4f7f04cbda4b207fbe9 | od -c

むしろ、ツリーデータはのシーケンスです<mode> SP <filename> NUL <hash>。ここで、<mode>は文字列形式モードであり、<hash>は20オクテットのSHA1です。

于 2012-12-20T17:14:33.257 に答える
2

ツリーオブジェクトの形式は次のとおりです。

tree SIZE\0ENTRIES

SIZEは木のサイズです。
ENTRIES各要素がツリーによって参照されるオブジェクトを表すシーケンスです。
各オブジェクトエントリは次のようにフォーマットされます。

MODE NAME\0BSHA

MODEは:

  • 通常のファイルの場合は100644、
  • 実行可能ファイルの場合は100755、
  • シンボリックリンクの場合は120000、
  • ツリーオブジェクトの場合は040000。

NAMEディレクトリまたはファイル名です。
BSHAオブジェクトIDのバイナリ表現です。

OPによる例に関して、上位ツリー(マスターブランチ)への参照を取得しましょう。

$ git write-tree
05b217bb859794d08bb9e4f7f04cbda4b207fbe9

このツリーっぽいものを使用しますが、以下はすべてのツリーに当てはまります。
最初の6文字(05b217)で十分です。

人間が読める形式のツリーコンテンツは、次のように提供されます。

$ git ls-tree 05b217
100644 blob aa823728ea7d592acc69b36875a482cdf3fd5c8d    rose

に置き換えることができgit ls-treeますgit cat-file -p

バイナリ形式は、次の形式にています。

$ git cat-file tree 05b217
100644 rose ▒▒7(▒}Y*▒i▒hu▒▒▒▒▒\▒%

実際のコンテンツには、最初の文字列も含まれていますtree [content size]\0。これを取得するには、2/38ハッシュ形式を使用して
、フォルダー内にツリーを格納しているファイルを解凍します。.git

$ openssl zlib -d -in .git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9
tree 32 100644 rose ▒▒7(▒}Y*▒i▒hu▒▒▒▒▒\▒%

ツリーに保存され、を介して利用できるオブジェクトを考えるls-treeと、awkスクリプトで保存された(実際の)コンテンツを生成する可能性があります。

$ git ls-tree 05b217 | awk -b 'function bsha(asha)\
{patsplit(asha, x, /../); h=""; for(j in x) h=h sprintf("%c", strtonum("0x" x[j])); return(h)}\
{t=t sprintf("%d %s\0%s", $1, $4, bsha($3))} END {printf("tree %s\0%s", length(t), t)}'
tree 32 100644 rose ▒▒7(▒}Y*▒i▒hu▒▒▒▒▒\▒%

出力をよりよく理解するために、エスケープシーケンスを使用してそのバージョンを作成します。

$ git ls-tree 05b217 | awk -b 'function bsha(asha)\
{patsplit(asha, x, /../); h=""; for(j in x) h=h sprintf("%s", "\\x" x[j]); return(h)}\
{t=t sprintf("%d %s\0%s", $1, $4, bsha($3))} END {printf("tree %s\0%s", length(t), t)}'
tree 92 100644 rose \xaa\x82\x37\x28\xea\x7d\x59\x2a\xcc\x69\xb3\x68\x75\xa4\x82\xcd\xf3\xfd\x5c\x8d%     

この出力を。からの前の出力と比較しますgit ls-tree 05b217

ここで、 さまざまな方法を使用してツリーハッシュを生成します。

ツリーのファイル保存バージョンの使用:

$ openssl zlib -d -in .git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9 | shasum
05b217bb859794d08bb9e4f7f04cbda4b207fbe9 *-

私のawk生成コンテンツの使用:

$ git ls-tree 05b217 | awk -b 'function bsha(asha)\
{patsplit(asha, x, /../); h=""; for(j in x) h=h sprintf("%c", strtonum("0x" x[j])); return(h)}\
{t=t sprintf("%d %s\0%s", $1, $4, bsha($3))} END {printf("tree %s\0%s", length(t), t)}' | shasum
05b217bb859794d08bb9e4f7f04cbda4b207fbe9 *-

そして最後にgit mktreeコマンド:

# git ls-tree 05b217 | git mktree    
05b217bb859794d08bb9e4f7f04cbda4b207fbe9    

得られるハッシュは常に同じです。

于 2016-05-08T00:25:02.617 に答える