2

J. Loeliger と M. McCullough による "Version Control with Git" を読んでいて、git の内部構造とパックされたファイルについて、それぞれ次の説明を見つけました。

「Git の内部データベースは、ファイルがあるリビジョンから次のリビジョンに移動するときに、すべてのファイルのすべてのバージョンを効率的に保存します。ファイルの違いではありません。Git はファイルの完全なコンテンツのハッシュをそのファイルの名前として使用するため、完全なコピーごとに操作する必要があります。ファイルのコンテンツの一部のみ、またはそのファイルの 2 つのリビジョン間の違いに基づいて、その作業またはオブジェクト ストア エントリを基にすることはできません。」

「パックされたファイルを作成するために、Git は最初にコンテンツが非常に類似しているファイルを見つけ、そのうちの 1 つの完全なコンテンツを保存します。次に、類似したファイル間の差分または差分を計算し、差分だけを保存します。」

Git はブロブのデルタ (デルタはブロブ自体) を格納するため、最初の段落が間違っているように思えます。では、なぜ著者はそのように説明することにしたのでしょうか? または、誰かがこれらの 2 つの段落の間のギャップを埋めることができますか? 完全なスナップショットがなくても、Git はパックされたファイルでうまくいくように思えます。ここに git-scm.comの例があります。

4

1 に答える 1

2

2 つの段落は、システムの異なる層について述べています。

Git はオブジェクト データベースに基づいており、オブジェクトはコミット、ツリー、ブロブ、およびタグのみです。これらはユーザーが操作できるオブジェクトであり、変更自体を表すものはありません。パッチと差分はすべてオンデマンドで生成されます。

Gitデルタ エンコーディングを使用してオブジェクトをストレージ用にまとめますが、これは基本的にストレージ システムとワイヤ プロトコルの実装の詳細であり、Git の動作の基本モデルの一部ではありません。Git がストレージのデルタ エンコーディングを行わずに動作することも (これがまさに最初の方法です)、または別の実装が互換性のないエンコーディングを使用してオブジェクトを保存することも完全に可能です。特に、デルタが保存される方法は、多くの場合、差分などの一部として実際に表示される変更とは似ていません。たとえば、デルタはオブジェクトのバイトシーケンスのみに基づいており、行にはまったく基づいていません。これらのデルタはすべて抽象化されており、それらを見るには何らかのハッキングを行う必要があります。

したがって、著者が言おうとしていたのは、Git の基本的な操作モードはすべて完全なファイルに基づいており、そのような操作git log -pは実際には保存されているものを単に表示するのではなく、その場で差分を計算するということです。彼らは、ディスク上のストレージにはデルタの格納が含まれる可能性があることを正直に指摘していますが、これらは低レベルの概念です。

パック ファイルの規則には、1 つのパック ファイルが自己完結型でなければならないことが含まれます。つまり、オブジェクトがデルタとしてパック ファイルに格納される場合、ベース オブジェクトもパック ファイルに格納される必要があります。限界まで、デルタを連鎖させることができます。ただし、パック ファイルの外に出なくても、パック ファイルからいつでもオブジェクトを取得できます。Git がパックからのオブジェクトを内部的に必要とする場合、それを生成するためにデルタが適用されますが、通常、デルタ化された表現ではまったく動作しません。(私の知る限り、唯一の例外は、オブジェクトを別のパックに入れるときです。そこでは、デルタをそのままコピーできます)

于 2013-06-14T23:34:01.437 に答える