なぜgitはリビジョン番号ではなくハッシュを使用するのですか?


80

なぜgitはリビジョン番号よりもハッシュを好むのかといつも思っていました。リビジョン番号ははるかに明確で簡単に参照できます(私の意見では):リビジョン1200を見てもらうか、92ba93eをコミットするように誰かに言うことには違いがあります!(1つの例を挙げます)。

それでは、この設計には理由がありますか?


3
「v1.0」でコミットにタグを付け、そのタグでコミットを参照できます。参照してくださいgit-scm.com/book/en/v2/Git-Basics-Tagging
マイケル・デュラント

回答:


114

単一の単調に増加するリビジョン番号は、すべてのリビジョンが番号を追跡して割り当てることができる単一の場所に流れる集中型バージョン管理システムにのみ意味があります。リポジトリの多数のコピーが存在し、任意のワークフローで変更がそこから取得およびプッシュされるDVCSの世界に入ると、この概念はまったく適用されません。(たとえば、リビジョン番号を割り当てる場所はどこにもありません-リポジトリを分岐し、1年後に変更をプルすることにした場合、システムはリビジョン番号が競合しないことをどのように確認できますか?)


11
Bazaarの方法を見ることもできます-リビジョン番号を保持しているDVCSです。唯一の保証は、リビジョン番号がブランチ内で一意であることです。
krlmlr

3
@krlmlr- Person 1: "Hey, <P2>, what was revision 12345 for?" P2: "Revision 12345 was commited by <P3>." P3: "I don't have a revision 12345..."正しく覚えていれば、Mercurialにも同様の問題があります。一方、gitを使用している場合は、コミットごとにすべて同一の参照があります。
イズカタ

1
@Izkata:P1: "Do you have revision with the GUID gdlmsnblngoijlafd-35345-fg?"... BazaarはまだGUIDを持っています...
krlmlr

5
@Iskata Mercurialにも同様の問題はありませ。ハッシュを使用しますgit。また、入力しやすいように、ローカルのみの回転数も提供します。
ハンクゲイ

1
gitでは、ハッシュの最初の5文字は多くの場合、完全なリビジョンIDの省略形を使用するのに十分なほど一意です。
メンドータ

40

分散システムではハッシュが必要です。あなたと同僚が同じリポジトリで作業しており、両方ともローカルで変更をコミットしてからプッシュしたとします。誰がリビジョン番号1200になり、誰もリビジョン番号1201になります。どちらの当事者にも互いの知識がありません。唯一の現実的な技術的解決策は、既知の方法を使用して変更のハッシュを作成し、それに基づいてリンクすることです。

興味深いことに、HGはバージョン番号をサポートしますが、それらは明示的にローカルのみの機能です。リポジトリには1つのセットがあり、同僚のリポジトリにはプッシュとプルの方法によって異なるセットがあります。ただし、コマンドラインの使用はGitよりも少し使いやすくなります。


34

データの整合性。

私は、現在の答えに敬意を表して反対します。DVCSにはハッシュは必要ありません。Bazaarの方法を参照してください。他の種類のグローバルに一意の識別子でも同様にできます。ハッシュは、データの整合性を保証する手段です。ハッシュによって参照されるオブジェクト(コミット、ツリーなど)に含まれる情報のダイジェストを表します。ハッシュを変更せずにコンテンツを変更すること(つまり、プリイメージ攻撃または衝突攻撃)は難しいと考えられていますが、不可能ではありません。(もし本当に興味があるなら、Marc Stevensによる2011年の論文をご覧ください)。

したがって、SHAハッシュでオブジェクトを参照すると、コンテンツが改ざんされていないかどうかを確認できます。そして、それらが(ほとんど)一意であることが保証されていることを考えると、それらはリビジョン識別子としても使用できます-便利です。

詳細については、Gitブックの第9章を参照してください。


8
ハッシュは変更されたコミットに対して簡単に再計算できるため、セキュリティ対策ではありません。計算されたハッシュに対して内容を検証するために、整合性のためにのみ使用されます-GitでのSHA-1の使用に関するLinus Torvaldsからのこのコメントを参照してください。
リー

@Lee:Chuckのリポジトリがリビジョンハッシュの点でAliceとBobのリポジトリと異なる場合、Chuckのコンテンツも異なることが保証されます。一方、Chuckが、リビジョンハッシュに対して同一に見える異なるコンテンツのリポジトリを作成することは非常に困難です。
krlmlr

@リー:あなたのリンクを逃しました。それを「データ整合性」と呼びましょう...
krlmlr

正しい答えなければなりません
SuperUberDuper

8

素人の言葉で:

  • ハッシュは、ほぼ普遍的に一意であることが意図されています。それは保証が、されないが、非常に同じSHA年代が異なるコンテンツのために生成されているとは考えにくいです。特定のプロジェクトの実際的な用語では、それをユニークなものとして扱うことができます。
  • リビジョン番号では、特にリビジョン1200を参照するためにネームスペースを使用する必要があります。
  • Gitは分散型および/または集中型の両方で機能します。それでは、どのようにしてリビジョン番号を正しく一意にするのでしょうか?
  • また、リビジョン番号を使用すると、新しいリビジョンには高い番号が必要であり、分岐、マージ、リベースなどのために真実ではないという誤った推測が生じます。
  • コミットにタグを付けるオプションが常にあります。

32
一意であるとは限りませんが、信じられないほど一意である可能性が高いです。:)
dsw88

@ mustang2009cobraそれは本当です。
Tulainsコルドバ

1
ハッシュが変更されていないため、私の変更が受け入れられない可能性があります。2つの流星が私のコンピューターとリポジトリーを持つコンピューターに同じ秒に衝突し、コンピューターを破壊して関係者全員を殺す可能性がはるかに高くなります。
gnasher729


1

ハッシュは、分散VCSのユニークなソリューションではありません。ただし、分散システムを扱う場合は、イベントの部分的な順序のみを記録できます。(VCSの場合、イベントはコミットです。)それが、単調に増加するリビジョン番号を維持することが不可能な理由です。通常、このような半順序関係を記録するには、ベクトルクロック(またはベクトルタイムスタンプ)のようなものを採用します。これはBazaarで使用されるソリューションです。

しかし、なぜGitはベクトルクロックではなくハッシュを使用するのですか?根本的な原因はチェリーピックだと思います。リポジトリでチェリーピックを実行すると、コミットの部分的な順序が変わります。一部のコミットのベクトルクロックは、新しい半順序を表すために再割り当てする必要があります。ただし、分散システムでのこのような再割り当ては、一貫性のないベクトルクロックを引き起こします。それがハッシュが扱う本当の問題です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.