54

これによると:

これは、よく知られているほとんどの SCM システムとは大きく異なることに注意してください。Subversion、CVS、Perforce、Mercurial などはすべてデルタ ストレージ システムを使用しており、あるコミットと次のコミットの間の差分を保存します。Git はこれを行いません。コミットするたびに、プロジェクト内のすべてのファイルがこのツリー構造でどのように見えるかのスナップショットを保存します。これは、Git を使用する際に理解しておくべき非常に重要な概念です。

それでも走るgit show $SHA1ofCommitObjectと…

commit 4405aa474fff8247607d0bf599e054173da84113
Author: Joe Smoe <joe.smoe@example.com>
Date:   Tue May 1 08:48:21 2012 -0500

    First commit

diff --git a/index.html b/index.html
new file mode 100644
index 0000000..de8b69b
--- /dev/null
+++ b/index.html
@@ -0,0 +1 @@
+<h1>Hello World!</h1>
diff --git a/interests/chess.html b/interests/chess.html
new file mode 100644
index 0000000..e5be7dd
--- /dev/null
+++ b/interests/chess.html
@@ -0,0 +1 @@
+Did you see on Slashdot that King's Gambit accepted is solved! <a href="http://game

...以前のコミットとのコミットの差分を出力します。git が差分を blob オブジェクトに保存しないことは知っていますが、コミット オブジェクトに差分を保存しますか? またはgit show、差分を動的に計算していますか?

4

2 に答える 2

87

このステートメントが意味することは、他のほとんどのバージョン管理システムでは、現在のコミットを再作成できるようにするために過去の参照ポイントが必要だということです。

たとえば、過去のある時点で、差分ベースの VCS (バージョン管理システム) は完全なスナップショットを保存していました。

x = snapshot
+ = diff
History:
x-----+-----+-----+-----(+) Where we are now

したがって、このようなシナリオでは、(現在) の状態を再作成するには、チェックアウト (x) してから、現在に至るまで各 (+) の差分を適用する必要があります。デルタを永久に保存するのは非常に非効率的であることに注意してください。そのため、デルタ ベースの VCS は完全なスナップショットを頻繁に保存します。Subversion の場合は次のようになります

さて、gitは違います。Git は完全なブロブへの参照を保存します。これは、git を使用すると、その時点でコードベースを再作成するのに 1 つのコミットだけで十分であることを意味します。Git は、スナップショットを作成するために過去のリビジョンから情報を検索する必要はありません。

その場合、git が使用するデルタ圧縮はどこから来るのでしょうか?

まあ、それは圧縮の概念に他なりません。わずかな量しか変更されていない場合、同じ情報を 2 回保存しても意味がありません。したがって、何が変更されたかを表しますが、それへの参照を保存して、実際には参照のツリーであるそれが属するコミットを、過去のコミットを見なくても再作成できるようにします。ただし、Git はコミットのたびにこれを行うのではなく、ガベージ コレクションの実行時にこれを行います。そのため、git がそのガベージ コレクションを実行していない場合、インデックス内のオブジェクトが非常に類似した内容であることがわかります。

ただし、Git がガベージ コレクションを実行すると (またはgit gc手動で呼び出すと)、重複がクリーンアップされ、読み取り専用のパック ファイルが作成されます。ガベージ コレクションを手動で実行することについて心配する必要はありません。

于 2014-07-30T04:16:50.107 に答える
55

いいえ、git のコミット オブジェクトには差分が含まれていません。代わりに、各コミット オブジェクトにはツリーのハッシュが含まれており、そのコミットでソース ツリーのコンテンツを再帰的かつ完全に定義します。ブロブ オブジェクト、ツリー オブジェクト、コミット オブジェクトについては、git コミュニティ ブックにわかりやすい説明があります。

git のツールによって表示されるすべての差分は、ファイルの完全なコンテンツからオンデマンドで計算されます。

于 2012-05-01T14:10:04.780 に答える