2016-02-16 22 views
7

私はgitがrefのハッシュを計算する方法を理解しようとしています。gitハッシュはどのように計算されますか?

$ git ls-remote https://github.com/git/git 

.... 
29932f3915935d773dc8d52c292cadd81c81071d refs/tags/v2.4.2 
9eabf5b536662000f79978c4d1b6e4eff5c8d785 refs/tags/v2.4.2^{} 
.... 

リポジトリをローカルでクローンします。我々はそれをハッシュすることができるようSHA

$ git cat-file -p 9eabf5b536662000f79978c4d1b6e4eff5c8d785 

tree 655a20f99af32926cbf6d8fab092506ddd70e49c 
parent df08eb357dd7f432c3dcbe0ef4b3212a38b4aeff 
author Junio C Hamano <[email protected]> 1432673399 -0700 
committer Junio C Hamano <[email protected]> 1432673399 -0700 

Git 2.4.2 

Signed-off-by: Junio C Hamano <[email protected]> 

コピーし、解凍内容によってrefs/tags/v2.4.2^{} REFを確認してください。gitの年代を使用して

git cat-file -p 9eabf5b536662000f79978c4d1b6e4eff5c8d785 > fi 

レッツ・SHA-1コンテンツ(私の知る限りのgitのは、それがハッシングだ圧縮されていないバージョンを使用しています)独自のハッシュコマンド

git hash-object fi 
3cf741bbdbcdeed65e5371912742e854a035e665 

なぜ出力が[9e]abf5b536662000f79978c4d1b6e4eff5c8d785ではないのですか?私は最初の2文字(9e)が16進数であることを理解しています。 fiの内容をハッシュすると、私はgit ref abf5b536662000f79978c4d1b6e4eff5c8d785を得ることができますか?

+0

(1) 'git hash-object'は他のオブジェクトタイプではなくファイルを追加しています。明らかに、ハッシュされたコンテンツには何らかの形で型が追加されます。そして、私は9eが長さではないと考えています。sha1アルゴリズムが返すように、行全体がハッシュです。 – max630

答えて

2

"How is git commit sha1 formed" で説明したように、式は:の場合

(printf "<type> %s\0" $(git cat-file <type> <ref> | wc -c); git cat-file <type> <ref>)|sha1sum 

である 9eabf5b536662000f79978c4d1b6e4eff5c8d785を(コミットv2.4.2^{}、ツリーを参照している):

(printf "commit %s\0" $(git cat-file commit 9eabf5b536662000f79978c4d1b6e4eff5c8d785 | wc -c); git cat-file commit 9eabf5b536662000f79978c4d1b6e4eff5c8d785)|sha1sum 

9eabf5b536662000f79978c4d1b6e4eff5c8d785となります。

ようになる:

(printf "commit %s\0" $(git cat-file commit v2.4.2{} | wc -c); git cat-file commit v2.4.2{})|sha1sum 

(静止9eabf5b536662000f79978c4d1b6e4eff5c8d785)

同様に、タグv2.4.2のSHA1を計算するであろう:

29932f3915935d773dc8d52c292cadd81c81071dを与える
(printf "tag %s\0" $(git cat-file tag v2.4.2 | wc -c); git cat-file tag v2.4.2)|sha1sum 

+0

は私がなぜわからないが、私は、異なるデータ$ '(printfの "ツリー%sの\ 0" $(gitの猫-ファイルツリー9eabf5b536662000f79978c4d1b6e4eff5c8d785 |トイレ-c); gitの猫のファイルツリー9eabf5b536662000f79978c4d1b6e4eff5c8d785)|取得SHA1SUM 655a20f99af32926cbf6d8fab092506ddd70e49cを' –

+0

コミットとツリーを混在させました:同じタイプを使用してください – VonC

+0

私はそれを更新しました...(ツリーを使用)。 –

4

ここに少し混乱があります。 Gitは、さまざまな種類のオブジェクトを使用します:blob、tree、およびcommit。 次のコマンドを実行します。

git cat-file -t <hash> 

はあなたに与えられたハッシュのためのオブジェクトのタイプを指示します。 あなたの例では、ハッシュ9eabf5b536662000f79978c4d1b6e4eff5c8d785はコミットオブジェクトに対応しています。今

、あなたがこれを実行し、自分自身を考え出したとして:

git cat-file -p 9eabf5b536662000f79978c4d1b6e4eff5c8d785 

は、(この例では、コミット)その種類に応じて、あなたにオブジェクトのコンテンツを提供します。

しかし、この:

git hash-object fi 

...コンテンツ(あなたの例では)前のコマンドの出力であるブロブのハッシュを計算し、それは(世界hello」のような何か他のものかもしれません! ")。ここで試してみてください:

echo "blob 277\0$(cat fi)" | shasum 

出力は前のコマンドと同じです。これは基本的にGitがブロブをハッシュする方法です。したがって、fiをハッシュすると、blobオブジェクトが生成されます。しかし、私たちが見たように、9eabf5b536662000f79978c4d1b6e4eff5c8d785はコミットであり、ブロブではありません。したがって、同じハッシュを取得するためには、それをそのままハッシュすることはできません。

コミットのハッシュは、それをユニークにする他の情報(コミッター、作成者、日付など)に基づいています。だから、あなたが元で使用されるものとまったく同じ値を使用して記事に指定されているすべてのデータを提供することで、同じハッシュを得ることができ

The anatomy of a git commit

:以下の記事は、ハッシュがで作られてまさにAコミットを示していますコミット。

これは、同様に有用であるかもしれない:

Git from the bottom up

関連する問題