こんにちは!日々の開発、本当にお疲れ様です。
新しいツールや技術に触れるときって、ワクワクしますよね。でも、ふと気づくと「あれ、なんだか最近リポジトリの動作が重いぞ……?」なんて壁にぶつかったりしていませんか?
今回は、バージョン管理やCI/CDの世界で避けて通れない、「GitHubリポジトリの肥大化と巨大バイナリ問題」についてお話しします。
「Git LFS(Large File Storage)を導入すれば安心!」と思ってはいませんか? 実は、それだけでは根本的な解決にならないケースが多々あるんです。ストレージコストの圧迫、クローン時間の増大、そしてチームメンバー全員のフラストレーション……。
大丈夫、安心してください。今回は、Git LFSの限界を突破し、リポジトリを常に軽快に保つための「現場のプロの知見」を、初心者の方にも分かりやすく優しく解説していきます。これをマスターすれば、毎日の作業が劇的に楽になりますよ!
—
1. そもそも「Git LFS」とは何か?(その役割と限界)
まずは基礎からいきましょう。
Gitは本来、ソースコードのような「テキストファイル」の差分管理を得意としています。しかし、画像、動画、コンパイル済みのバイナリ、3Dモデルなどの巨大なファイルをGitでそのまま管理しようとすると、ファイルが更新されるたびにリポジトリのサイズが膨れ上がり、数ギガバイトの「モンスターリポジトリ」が誕生してしまいます。
そこで登場するのが Git LFS です。
Git LFSの仕組み
Git LFSは、巨大な実ファイルを専用のストレージサーバー(GitHub上のLFSストレージなど)に保存し、Gitリポジトリ内には「ポインタ(参照情報)」というごく小さなテキストファイルだけを置く仕組みです。
[あなたの手元] ──(巨大ファイルの実体)──> [Git LFSサーバー]
│
└──(数バイトのポインタ)──> [.git リポジトリ] ──> [GitHub]
Git LFSの「見落としがちな限界」
「じゃあ、LFSを入れれば万解決だね!」と言いたいところですが、ここに大きな落とし穴があります。
1. ストレージと転送量の「お財布パンク」問題
GitHubの無料枠や標準プランには、LFSのストレージ容量と月ごとのデータ転送量(帯域幅)に制限があります。これをオーバーすると、追加購入(Data Pack)が必要になり、気づけば毎月のコストが跳ね上がります。
2. 「過去の履歴」に眠るバイナリは消えない
Git LFSを導入する前にコミットしてしまったバイナリは、そのままGitの履歴(.git内部)に残ります。LFSを導入しても、過去の歴史からファイルが消えたわけではないため、リポジトリのサイズ自体は小さくならないのです。
—
2. 基礎セットアップ:Git LFSを正しく導入する
まずは、基本のGit LFSのセットアップをおさらいしておきましょう。新しくプロジェクトを始める際の手順です。
手順1: インストールと有効化
お使いのPCにGit LFSをインストールします(MacならHomebrewが簡単です)。
Git LFSのインストール(Macの場合)
brew install git-lfs
システム全体でLFSを初期化する(最初の一回だけ)
git lfs install
手順2: 追跡対象の指定
プロジェクトのルートディレクトリで、LFSで管理したい拡張子を指定します。
例:PSDファイルやZIPファイルをLFSの管理下に置く
git lfs track “.psd”
git lfs track “.zip”
このコマンドを実行すると、プロジェクトのルートに `.gitattributes` という隠しファイルが生成されます。中身を覗いてみましょう。
.gitattributes の中身(例)
.psd filter=lfs diff=lfs merge=lfs -text
.zip filter=lfs diff=lfs merge=lfs -text
この設定ファイルを必ずコミットしてチームメンバーと共有するのが、スムーズな協業の第一歩です。
—
3. HelloWorld的・動作確認:LFSが正しく動いているかテストする
では、実際にLFSが機能しているか、簡単なテスト(HelloWorld的確認)をしてみましょう。
1. テスト用ファイルの作成
わざと少し大きめのダミーファイル(テキストでも何でも構いません)を作ります。
# 適当なバイナリ風ファイルを作成
echo “Hello Git LFS” > sample.zip
2. ステージングとコミット
git add sample.zip
git commit -m “Add LFS test zip”
3. LFSで管理されているか確認
以下のコマンドを叩いてみてください。
git lfs ls-files
期待される出力:
a1b2c3d4e5 sample.zip
このようにハッシュ値が表示されれば大成功です!GitHubにプッシュした後、GitHub上のWeb画面でファイルを開いてみてください。「Stored with Git LFS」という表示があれば、完璧にセットアップできています。
—
4. 現場の裏技:LFSだけでは消えない「過去の亡霊」を葬る (`git filter-repo`)
さて、ここからが本題です。「すでにリポジトリが数ギガバイトになってしまっている」「LFSを入れたのにリポジトリが軽いどころか重い」という場合の処方箋です。
過去のコミット履歴に含まれている巨大ファイルを根こそぎ綺麗サッパリ削除し、リポジトリを軽量化するには `git filter-repo` という強力なツールを使用します(かつての `git filter-branch` は遅すぎて非推奨になりました)。
> ⚠️ 注意: この操作はリポジトリの歴史を書き換えます。チームメンバー全員に影響が出るため、実施前には必ずバックアップを取り、全員の作業が止まるタイミングで慎重に行ってください。
手順:巨大ファイルを歴史から完全に消し去る
1. git-filter-repoのインストール
brew install git-filter-repo # Macの場合
2. リポジトリのクローン(※必ず新しいクローンで行うこと)
git clone <あなたのリポジトリURL> my-project-clean
cd my-project-clean
3. 特定の巨大ファイルや拡張子を履歴から完全に削除
例えば、過去に混入してしまった `heavy_data.zip` というファイルを痕跡すら残さず消去する場合:
git filter-repo –path heavy_data.zip –invert-path
これで、過去の全コミットからこのファイルが存在しなかったことになります。
4. GitHubへ強制プッシュ
git remote add origin <あなたのリポジトリURL>
git push origin –force –all
git push origin –force –tags
これで、GitHub上のリポジトリ容量は劇的に小さくなり、クローン速度も爆速に戻ります!
—
5. それでも防げないなら:「サブモジュール」の活用と運用監視
歴史を綺麗にしてもなお、ゲームアセットや膨大なドキュメントなどでリポジトリが肥大化する場合は、「Gitサブモジュール(Submodule)」の出番です。
ソースコード本体と、頻繁に変更されない巨大なアセット群を別のリポジトリに分離し、メインのリポジトリからは「特定のバージョン(コミットハッシュ)」だけを参照するようにします。これにより、普段のプログラミング作業時には重いアセットをダウンロードせずに済むため、開発体験が劇的に向上します。
ストレージクォータの運用監視フロー
一度綺麗にしても、放っておくと開発者はまた巨大ファイルを普通にコミットしてしまいます。これを防ぐための「現場の自動化ルール」を作りましょう。
1. GitHub Actionsによるリポジトリサイズチェック
CI/CDパイプライン(GitHub Actions)を組み込み、PR(プルリクエスト)作成時にリポジトリ全体のサイズや、追加されたファイルのサイズを自動チェックし、一定以上(例:50MB以上)であれば警告またはマージをブロックする仕組みを導入します。
2. 定期的なアラート通知
GitHubのWebhooksやサードパーティツールを使い、LFSのストレージ使用量が契約容量の80%に達した段階でSlackなどに通知が飛ぶようにしておきます。月末に突然「LFSの帯域制限でビルドが止まった!」という青ざめる事態を防げます。
—
まとめ
いかがでしたでしょうか?
- Git LFS は素晴らしい機能ですが、過去の履歴までは消してくれません。
- 肥大化したリポジトリには `git filter-repo` で歴史を美しくリファクタリングする。
- どうしても分けないといけない巨大データは サブモジュール で切り離す。
- 自動化と監視で、再びモンスター化させない仕組みを作る。
このアプローチを知っていれば、どんなにアセットが多いプロジェクトを担当しても、あなたのGitHubリポジトリは常に健康で軽快な状態を保てます。
日々のバージョン管理が快適になれば、コードを書く純粋な楽しさをもっと味わえるはずです。ぜひ、あなたのプロジェクトでも試してみてくださいね!