大きなファイルを Git で扱おうとすると
容量、処理速度、通信時間などの面で問題が発生します。
例えば、大きなファイルのほんの一部を変更して再度コミットしたとしても、
作成されるリビジョンのデータは差分ではなくスナップショットであるために
リポジトリーの容量は大きく増加します。
実際に行った実験の結果を見てみましょう。
テキストファイルで実験
サイズが 1 GB のテキストファイルを用意しました。
内容は以下のように、”0123456789″ という文字列を何行も繰り返しています。
これをローカルリポジトリーにコミットし、
その前後のローカルリポジトリーのサイズを調べます。
コミット前のリポジトリーのサイズは 18.8 KB でした。
その後、1 GB のテキストファイルをコミットして、
再度リポジトリーのサイズを確認すると、5.22 MB まで増加しました。
元のテキストファイルは 1 GB ですが、 Git が圧縮を行ってくれるようです。
その影響なのか、コミットには数十秒の時間がかかりました。
続いて、テキストファイルの内容を 1 文字だけ変更します。
これをコミットして再度リポジトリーのサイズを調べると、
サイズは 10.4 MB まで増加していました。
半角数字の容量は 1 byte ですが、
変更は 1 byte でもリポジトリーのサイズは 5 MB 増加しました。
メディアファイルで実験
今度はメディアファイルで実験してみましょう。
Wikipedia に NASA が撮影した地球の PNG 画像ファイルがあります。
File:Blue Marble 2002.png – Wikimedia Commons
これを画像編集アプリケーションの GIMP で開き、
以下の設定で PNG 画像ファイルとしてエクスポートし直します。
エクスポートは 2 回行い、1 回目はそのまま、
2 回目のエクスポートは画像の右下の 1 ピクセルのみ色を変えて行います。
ファイルサイズはどちらも 529 MB になりました。
ファイルの中身を比較すると、ほとんど同じ内容になっています。
この 2 枚の PNG 画像ファイルを
同じファイル名 “Blue_Marble_2002.png” として
同一のローカルリポジトリーにコミットして
コミット前後のローカルリポジトリーのサイズを確認します。
コミット前のリポジトリーのサイズはやはり 18.8 KB でした。
その後、1 枚目の PNG 画像ファイルをコミットして、
再度リポジトリーのサイズを確認すると、526 MB まで増加しました。
Web で使われる形式のメディアファイルは既に圧縮されているため
Git リポジトリーへの保存時に大きくファイルサイズが削減されることはありません。
さらに 2 枚目の画像をコミットして再度リポジトリーのサイズを調べると、
サイズは 1.02 GB まで増加していました。
画像ファイル 1 pixel の更新であっても
リポジトリーの容量は更新したファイルのサイズ分増加しました。
GitHub の制限
GitHub へは 100 MB 以上のファイルをプッシュすると拒否されます。
また、 50 MB 以上のファイルをプッシュすると警告が表示されます。
大きなファイルを Git でバージョン管理する方法はないの?
GitHub の 「release」 機能を使う
Git のリポジトリーには大きなファイルを含めず、
GitHub の 「release」 機能を使って GitHub 上で特定のリビジョンに
大きなファイルを関連付けて登録する方法です。
GitHub 上でリポジトリーとファイルを関連付けられる一方で、
関連付けたファイルは Git 以外の方法で操作することになります。
Git Large File Storage 拡張 (Git LFS) を使う
Git のリポジトリーに大きなファイルへの参照のみを含め、
大きなファイルの本体自体は別のストレージに保管する方法です。
公式サイトの Git LFS の仕組みを表す図を見ると
どのように機能するか理解しやすいでしょう。
ストレージはリポジトリーとは別途選択できますが、
初期状態ではクローンしたリポジトリーと同じ URL になります。
そして、 GitHub は Git LFS をサポートしており、
ストレージの容量と月間の帯域 (通信量) に 1 GB の上限はありますが、
無料で利用できます。
(追加の容量と帯域は、料金を支払うことで追加することができます。)