web-dev-qa-db-ja.com

Gitはどのようにしてユニークなコミットハッシュ、主に最初の数文字を作成しますか?

最初の4文字でも同じにすることを許可されていない、完全に一意のハッシュをGitが作成する方法に頭を悩ますのは難しいと思います。最初の4文字だけを使用して、Git Bashでコミットを呼び出すことができます。最初の文字が「超」一意であり、他の類似のハッシュと競合しないことがアルゴリズムで明確に決定されていますか、それともアルゴリズムは同じ方法でハッシュのすべての部分を生成しますか?

22
Ben

Gitは次の情報を使用してsha-1を生成します。

  • コミットのソースツリー(すべてのサブツリーとBLOBに展開されます)
  • 親コミットsha1
  • 著者情報(タイムスタンプ付き)
  • コミッター情報(正しい、これらは異なります!、タイムスタンプも含まれます)
  • コミットメッセージ

(完全な説明については、見てください ここ )。

Git しないでください最初の4文字が一意であることを保証します。 Pro Git Bookの第7章 には次のように書かれています:

Gitは、SHA-1値の短くてユニークな省略形を理解できます。 --abbrev-commitをgit logコマンドに渡すと、出力はより短い値を使用しますが、それらは一意のままです。デフォルトでは7文字を使用しますが、SHA-1を明確にするために必要な場合は長くします。

したがって、Gitは、一意性を保つために、省略形必要な限りを作成します。彼らはさらに次のように述べています:

通常、8文字から10文字は、プロジェクト内で一意になるには十分です。

例として、45万を超えるコミットと360万のオブジェクトを持つかなり大きなプロジェクトであるLinuxカーネルには、SHA-1が最初の11文字を超えてオーバーラップするオブジェクトが2つありません。

したがって、実際には、まったく同じ(aの最初のX文字)を持っているimprobabilityに依存しています。

36
Chris Maes

2017年4月:結局のところ shattered.ioエピソード (GoogleによってSHA1の衝突が発生した場合)、20バイトのフォーマットは永久に存在しないことに注意してください。

その最初のステップは、Gitコードベース全体にハードコードされている_unsigned char sha1[20]_を、将来その定義が変更される可能性がある汎用オブジェクト(SHA2 ?, Blake2 、... )

commit e86ab2c (2017年2月21日)の brian m.carlson(_bk2204_) を参照してください。

_unsigned char [20]_の残りの使用を_struct object_id_に変換します。

これは、v2.5.0-rc0の brian m.carlson(_bk2204_) によって commit 5f7817c (2015年3月13日)で開始された継続的な取り組みの例です。 、で _cache.h_

_/* The length in bytes and in hex digits of an object name (SHA-1 value). */
#define GIT_SHA1_RAWSZ 20
#define GIT_SHA1_HEXSZ (2 * GIT_SHA1_RAWSZ)

struct object_id {
    unsigned char hash[GIT_SHA1_RAWSZ];
};
_

そして、SHA1を使用しても、最初の4文字は一意性を保証するのに十分ではないことを忘れないでください。これは、「 git shaのの一般的な量特定のコードベースの変更を一意に識別するために必要と考えられますか? "。


2017年12月の更新とGit 2.16(2018年第1四半期):代替をサポートするためのこの取り組みSHAが進行中:参照" なぜGitはより最新のSHAを使用しないのですか? "。

別のハッシュを使用できるようになります。SHA1はGitの唯一のハッシュではなくなりました。

Update 2018-2019:Git 2.19+で選択されました:SHA-256
hash-function-transition 」を参照してください。

これはまだアクティブではありませんが(git 2.21がまだSHA1を使用していることを意味します)、コードは将来のSHA-256をサポートするために行われています。


Git 2.26(2020年第1四半期)では、作業が続行され、「_object_id"_」の代わりに「struct _char *sha1_」が使用されます

commit 2fecc48commit 6ac976commit b99b6bccommit 63f4a7fcommit e31c71 を参照してください、 commit 500e4f2commit f66d4ecommit a93c141commit 3f83fd5commit 0763671 (2020年2月24日)作成者 Jeff King(peff
Junio C Hamano-gitster- によってマージ commit e8e7184 、2020年3月5日)

packfile :ドロップnth_packed_object_sha1()

サインオフ:Jeff King

かつて、nth_packed_object_sha1()は、パックファイルのインデックス位置のOIDを取得するための主要な方法でした。
しかし、最近はよりタイプセーフなnth_packed_object_id()ラッパーがあり、すべての呼び出し元が変換されています。

"_sha1_"バージョン(より安全なラッパーを単一の関数に変換)を削除して、だれも新しい呼び出し元を紹介する気にならないようにします。

4
VonC