Gitにおける大容量ファイルの未来は、Gitだ
Gitに天敵がいるとすれば、それは大容量ファイルです。
大容量ファイルはGitのストレージを膨張させ、git cloneを遅くし、Gitフォージに大混乱をもたらします。
2015年、GitHubはGit LFSをリリースしました。大容量ファイルの問題を回避するためのGit拡張です。しかし、Git LFSは新たな複雑さとストレージコストを生みました。
その一方で、Gitプロジェクトはひそかに大容量ファイルに取り組んできました。Git LFSはまだ消えていませんが、最新のGitリリースは、ついにLFSが不要になる未来への道筋を示しています。
今日できること:Git LFSをGitの部分クローンに置き換える
Git LFSは、大容量ファイルをリポジトリの外に保存することで動作します。
LFS経由でプロジェクトをクローンすると、リポジトリの履歴と小さなファイルは取得しますが、大容量ファイルはスキップします。その代わり、Git LFSは作業コピーに必要な大容量ファイルだけをダウンロードします。
2017年、GitプロジェクトはGit LFSと同じメリットを提供する部分クローンを導入しました。
部分クローンを使うと、クローンやフェッチの際に[大容量のバイナリアセット]をあらかじめダウンロードせずに済むため、ダウンロード時間とディスク使用量を削減できます。
―「Partial Clone Design Notes」、git-scm.com
Gitの部分クローンとLFSは、どちらも次のことを実現します。
- 小さなチェックアウト ― クローン時に取得するのは、大容量ファイルのすべてのコピーではなく、最新のコピーです。
- 高速なクローン ― 大容量ファイルのダウンロードを避けるため、クローンが速くなります。
- すぐに作業を始められる ― 浅いクローンとは違い、プロジェクトの履歴全体を取得できるので、すぐに作業に取りかかれます。
部分クローンとは?
Gitの部分クローンとは、--filterを付けたクローンです。
たとえば、100KBを超えるファイルをダウンロードしないようにするには、次のようにします。
git clone --filter='blobs:size=100k' <repo>その後、Gitはチェックアウトに必要になった100KB超のファイルを遅延ダウンロードします。
デフォルトでは、25MBの厄介なPNGファイルを何度も更新したリポジトリをgit cloneすると、クローンは遅くなり、チェックアウトは途方もなく大きくなります。
$ time git clone https://github.com/thcipriani/noise-over-git
Cloning into '/tmp/noise-over-git'...
...
Receiving objects: 100% (153/153), 1.19 GiB
real 3m49.052sたった1つの25MBファイルをチェックアウトするのに、ほぼ4分です!
$ du --max-depth=0 --human-readable noise-over-git/.
1.3G noise-over-git/.
$ ^ 🤬しかも、その25MBのファイル1つの50個のリビジョンが、1.3GBもの容量を消費します。
しかし、部分クローンならこうした問題を回避できます。
$ git config --global alias.pclone 'clone --filter=blob:limit=100k'
$ time git pclone https://github.com/thcipriani/noise-over-git
Cloning into '/tmp/noise-over-git'...
...
Receiving objects: 100% (1/1), 24.03 MiB
real 0m6.132s
$ du --max-depth=0 --human-readable noise-over-git/.
49M noise-over-git/.
$ ^ 😻 (git lfsのチェックアウトと同じサイズ)このフィルターによって、クローンは97%高速化しました(3分49秒 → 6秒)。チェックアウトのサイズも96%削減されました(1.3GB → 49MB)!
ただし、いくつか注意点は残っています。
フィルターで除外したデータを必要とするコマンドを実行すると、Gitはそれを取得するためにサーバーへ取りに行く必要があります。そのため、git diff、git blame、git checkoutなどのコマンドを実行するには、Gitホストへの通信が発生します。
しかし、大容量ファイルについては、これはGit LFSと同じ動作です。
それに、PNGに対して最後にgit blameを実行したのがいつだったかなんて、もう思い出せません 🙃。
なぜそこまでするのか? Git LFSの何が問題なのか?
Git LFSは、Gitが抱える大容量ファイルの問題をユーザーに押しつけます。
しかも、その問題は深刻です。
- 🖕 ベンダーロックインが強い ― GitHubがGit LFSを開発した当時、ほかの大容量ファイルシステムであるGit Fat、Git Annex、Git Mediaは、サーバー側の実装を特定していませんでした。しかしGitHubは、ユーザーを自社独自のサーバー実装に縛りつけ、利用料を課しました。1
- 💸 高コスト ― GitHubが勝ったのは、ユーザーがリポジトリを無料でホスティングできたからです。しかしGit LFSは有料製品として始まりました。現在は無料枠もありますが、料金設定はGitHubの気分次第です。現在、GitHubで50GBのリポジトリを保存すると、ストレージ料金は年間40ドルかかります。一方、AmazonのS3標準ストレージで50GBを保存する場合は、年間13ドルです。
- 😰 元に戻しにくい ― いったんGit LFSへ移行すると、履歴を書き換えずに元へ戻すことはできません。
- 🌀 セットアップの負担が続く ― すべてのコラボレーターがGit LFSをインストールする必要があります。Git LFSをインストールしていないコラボレーターには、期待していた大容量ファイルの代わりに、メタデータが詰め込まれたわかりにくいテキストファイルが渡されます。
未来:Gitのラージオブジェクト・プロミサー
大容量ファイルは、Gitフォージにとっても問題を引き起こします。
GitHubとGitLabがファイルサイズに上限を設けている2のは、大きなファイルほどホスティングにお金がかかるからです。Git LFSは、大容量ファイルをCDNへオフロードすることで、サーバー側のコストを抑えています。
しかし、Gitプロジェクトには新しい解決策があります。
今年の初め、Gitに新機能がマージされました。ラージオブジェクト・プロミサーです。ラージオブジェクト・プロミサーは、ユーザーに面倒をかけずに、LFSと同じサーバー側のメリットを提供することを目指しています。
この取り組みは、特にサーバー側の改善を、そして特にバイナリ形式ですでに圧縮されている大きなblobの扱いを改善することを目指しています。
この取り組みは、Git LFSに代わる選択肢を提供することを目指しています。
―「Large Object Promisors」、git-scm.com
ラージオブジェクト・プロミサーとは?
ラージオブジェクト・プロミサーは、大容量ファイルだけを格納する特別なGitリモートです。
輝かしく、きらきらした未来では、ラージオブジェクト・プロミサーは次のように動作します。
- 大容量ファイルをGitホストへプッシュします。
- Gitホストがバックグラウンドで、その大容量ファイルをラージオブジェクト・プロミサーへオフロードします。
- クローン時に、Gitホストがプロミサーの存在をGitクライアントに伝えます。
- クライアントはGitホストからクローンし、大容量ファイルをプロミサーのリモートから自動的に取得します。
しかし、その輝かしく、きらきらした未来はまだ先です。
Gitのラージオブジェクト・プロミサーは、まだ開発途上です。ラージオブジェクト・プロミサーの一部が、2025年3月にGitへマージされました。しかし、やるべきことはまだあり、答えの出ていない疑問も残っています。
そのため現時点では、巨大なファイルについてはGit LFSを使わざるを得ません。しかし、ラージオブジェクト・プロミサーが広く採用されるようになれば、GitHubでも100MBを超えるファイルをプッシュできるようになるかもしれません。
Gitにおける大容量ファイルの未来は、Gitだ。
Gitプロジェクトは、あなたが大容量ファイルについて考えなくて済むよう、真剣に取り組んでいます。
今はまだ、Git LFSを使わざるを得ません。
しかし近いうちに、Gitにおける大容量ファイルの唯一の障害は、「MP3ライブラリをGitにしまっておくのはまずい」という、うろ覚えで不吉な予感だけになるでしょう。
Refactoring Englishによる編集
その後、ほかのGitフォージも独自のLFSサーバーを作りました。現在では、複数のGitフォージへプッシュしたり、LFS転送エージェントを使ったりできますが、その分、コントリビューターにとってのセットアップは難しくなります。ロックインを解除するために余計な手間をかけない限り、ほぼ完全に縛られたままです。↩︎
ファイルサイズの上限:GitHubは100MB、GitLab.comも100MB↩︎
記事をランダムに読む