どうやら Mercurial は各変更にグローバル変更セット ID を割り当てているようです。これが一意であることをどのように保証しますか?
2 に答える
ザックが言うように、変更セット ID はSHA-1 ハッシュ関数を使用して計算されます。これは、暗号的に安全なハッシュ関数の例です。暗号化ハッシュ関数は、任意の長さの入力文字列を受け取り、この文字列から固定長のダイジェストを生成します。SHA-1 の場合、出力長は 160 ビットに固定されており、Mercurial はデフォルトで最初の 48 ビット (12 桁の 16 進数) のみを表示します。
暗号化ハッシュ関数には、同じ出力を生成する 2 つの異なる入力を見つけるのが非常に難しいという特性があります。つまり、 のx != y
ような文字列を見つけるのは困難ですH(x) == H(y)
。これを耐衝突性といいます。
Mercurial は SHA-1 関数を使用してチェンジセット ID を計算するため、同一の入力 (同一の変更、同一のコミッター名および日付) に対して同じチェンジセット ID を取得します。ただし、異なる入力 ( x != y
) を使用すると、衝突耐性のために異なる出力 (変更セット ID) が得られます。
別の言い方をすれば、異なる入力に対して異なる変更セット ID を取得しない場合は、SHA-1 の衝突が見つかりました! これまでのところ、SHA-1 の衝突を発見した人はいないため、これは大きな発見になるでしょう。
より詳細には、SHA-1 ハッシュ関数は Mercurial で再帰的に使用されます。各チェンジセット ハッシュは、以下を連結して計算されます。
- マニフェスト ID
- ユーザー名をコミットする
- コミット日
- 影響を受けるファイル
- コミットメッセージ
- 最初の親変更セット ID
- 2 番目の親変更セット ID
そして、これらすべてに対して SHA-1 を実行します ( changelog.pyおよびrevlog.pyを参照)。ハッシュ関数は再帰的に使用されるため、チェンジセット ハッシュはチェンジセット グラフのルートまでさかのぼって履歴全体を修正します。
Hello World!
これは、同じコミット メッセージで同時に 2 つの異なるプロジェクトに行を追加した場合、同じ変更セット ID を取得しないことも意味します。履歴が異なる場合 (親変更セットが異なる場合)、2 つの新しい変更セットは異なる ID を取得します。 .
Mercurial のチェンジセット ID は、各チェンジセットの「マニフェスト」の SHA-1 ハッシュです。グローバル ID の最初の 12 桁の 16 進数のみを出力しますが、内部操作には完全な SHA-1 を使用します。それらが一意であるという実際の保証はありませんが、実用的な目的には十分ありそうにありません。