Git:圧縮とリポジトリのサイズ

Git便利ですね。Gitではオブジェクト(ファイルなど)をzlibで圧縮して保持します。それだけではなく、差分を計算したり、複数のオブジェクトを packすることで、単純にすべての履歴を記録するよりも効率的にリポジトリを保持することができます。

duだとファイルサイズではなくてブロックサイズになるので上記コマンドを使います。Landscape – エンジニアのメモを参考にしました。

まずはgit initしただけの状態で。

13.6KiBです。ここからどうなっていくかを見て行きましょう。まずはテキストファイルから。

Gitはファイルをテキストファイルとして認識してくれました。巨大なテキストファイル(24.8MiB)を追加したにもかかわらず、リポジトリのサイズは162KiBに収まっています。これは繰り返し文字列でありzlibによる圧縮が良好に効いていることによります。

ファイルの一部(10000行目のみ)改変してみましょう。

Gitは一行のみの変化であることをきちんと認識してくれました。しかし、リポジトリのサイズは310KiBとなっています。先ほどのリポジトリのサイズが162KiBなのでほとんど倍です。圧縮されて効率的なのは確かですが、ちょっと期待していた動作と違います。1行だけの変更なので、もう少し小さなサイズになることを期待していました。

Gitは、コンテンツの変更の際も単純にリポジトリに新しいオブジェクトとして追加します。これは高速に動作しますが、ディスク容量の観点からは非効率です。差分を探して、不必要なオブジェクトを削除するにはgit gcコマンドを使います。

リポジトリのサイズは78KiBと十分に小さくなりました。一つ目のファイルを追加した際のサイズより小さくなっています。

git gcコマンドは上記のように手動で実行することもできますが、必要と考えられるときやリモートリポジトリへのpushを行う時には自動で実行されます。

それではバイナリファイルの実験に入りましょう。リポジトリを初期化して開始します。

Gitはファイルをバイナリ(binfile)として認識してくれました。binfileは9.5MiBと大きなファイルですが、繰り返しが多いのでzlibによる圧縮が効率的に行えそうです。リポジトリのファイルは66KiBと期待通り小さなものになりました。

一部を改変するとどうなるでしょうか。

binfileに16バイトのわずかな変更を加えました。git gcを行うとリポジトリのサイズは35KiBとなりました。バイナリファイルでも差分による圧縮とzlib圧縮を行なって効率的にリポジトリにファイルが格納されることがわかりました。

コメントを残す