The future of large files in Git is Git

Tyler Cipriani

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は、どちらも次のことを実現します。

  1. 小さなチェックアウト ― クローン時に取得するのは、大容量ファイルのすべてのコピーではなく、最新のコピーです。
  2. 高速なクローン ― 大容量ファイルのダウンロードを避けるため、クローンが速くなります。
  3. すぐに作業を始められる ― 浅いクローンとは違い、プロジェクトの履歴全体を取得できるので、すぐに作業に取りかかれます。

部分クローンとは?

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 diffgit blamegit 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リモートです。

輝かしく、きらきらした未来では、ラージオブジェクト・プロミサーは次のように動作します。

  1. 大容量ファイルをGitホストへプッシュします。
  2. Gitホストがバックグラウンドで、その大容量ファイルをラージオブジェクト・プロミサーへオフロードします。
  3. クローン時に、Gitホストがプロミサーの存在をGitクライアントに伝えます。
  4. クライアントはGitホストからクローンし、大容量ファイルをプロミサーのリモートから自動的に取得します。

しかし、その輝かしく、きらきらした未来はまだ先です。

Gitのラージオブジェクト・プロミサーは、まだ開発途上です。ラージオブジェクト・プロミサーの一部が、2025年3月にGitへマージされました。しかし、やるべきことはまだあり答えの出ていない疑問も残っています

そのため現時点では、巨大なファイルについてはGit LFSを使わざるを得ません。しかし、ラージオブジェクト・プロミサーが広く採用されるようになれば、GitHubでも100MBを超えるファイルをプッシュできるようになるかもしれません。

Gitにおける大容量ファイルの未来は、Gitだ。

Gitプロジェクトは、あなたが大容量ファイルについて考えなくて済むよう、真剣に取り組んでいます。

今はまだ、Git LFSを使わざるを得ません。

しかし近いうちに、Gitにおける大容量ファイルの唯一の障害は、「MP3ライブラリをGitにしまっておくのはまずい」という、うろ覚えで不吉な予感だけになるでしょう。


Refactoring Englishによる編集


  1. その後、ほかのGitフォージも独自のLFSサーバーを作りました。現在では、複数のGitフォージへプッシュしたり、LFS転送エージェントを使ったりできますが、その分、コントリビューターにとってのセットアップは難しくなります。ロックインを解除するために余計な手間をかけない限り、ほぼ完全に縛られたままです。↩︎

  2. ファイルサイズの上限:GitHubは100MBGitLab.comも100MB↩︎

原文は Tyler Cipriani により に公開されました。

この記事は「gpt-5.6-terra」を使用して翻訳されました。