はじめに
Gitはテキストファイル用に設計されており、大規模バイナリには不向きです。大容量ファイルがリポジトリに入るとクローン時間が増加し、リポジトリサイズが膨張し、git logなどの操作が低速化します。Git LFS(Large File Storage)は、大容量ファイルをテキストのポインターファイルに置き換え、実際のファイルコンテンツをリモートサーバーに保存することでこの問題を解決します。
ポインターファイルは、リモートのLFSサーバー上のコンテンツを指す小さなテキストファイルです:
version https://git-lfs.github.com/spec/v1
oid sha256:4a7e9a5b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b
size 12345
実際の事例では、デザインチームのリポジトリがLFS移行後に12GBから140MBに削減されました。Git LFSは現在、GitHub、GitLab、Bitbucket、セルフホストソリューションでサポートされる標準的な大容量ファイル管理ツールです。
1. LFSアーキテクチャとインストール
Git LFSはsmudgeフィルタとcleanフィルタによって動作します。ブランチをチェックアウトするとsmudgeフィルタがポインターファイルを実際のコンテンツに置き換え、コミット時にはcleanフィルタが大容量ファイルをポインタに置き換えます。
# Git LFSのインストール
git lfs install
# インストール確認
git lfs version
git lfs installを実行すると、filter.lfsセクションにsmudge/cleanフィルタの設定が.gitconfigに追加されます。新しいSSHベースのプロトコルではgit-lfs-transferコマンドを使用して、HTTPSに依存しない認証付き転送を行います。
インストール方法:
- Windows:
git lfs install(Git for Windowsに同梱) - macOS:
brew install git-lfs && git lfs install - Linux:
apt install git-lfs(Debian/Ubuntu)またはyum install git-lfs(RHEL/Fedora)
2. 追跡パターンと設定
git lfs trackコマンドで特定のファイルパターンをLFSで追跡するよう設定します。このコマンドは.gitattributesファイルにエントリを追加します。チーム全体で適用するには、この.gitattributesをコミットする必要があります。
# 一般的なバイナリファイルタイプを追跡
git lfs track "*.psd"
git lfs track "*.zip"
git lfs track "*.h5"
git lfs track "*.onnx"
生成される.gitattributesのエントリ:
*.psd filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.h5 filter=lfs diff=lfs merge=lfs -text
特定のディレクトリにスコープを限定したり、否定パターンを使用することもできます:
assets/**/*.png filter=lfs diff=lfs merge=lfs -text
!assets/thumbnails/*.png
追跡中のパターンはgit lfs trackで確認でき、.gitattributesファイルを直接編集することも可能です。
3. ファイルサイズ制限と帯域幅管理
LFSのストレージと帯域幅はホスティング事業者ごとに制限があります:
| プロバイダ | 無料ストレージ | 月間無料帯域幅 |
|---|---|---|
| GitHub | 1 GB | 1 GB |
| GitLab | プランにより異なる | プランにより異なる |
| Bitbucket | 1.8 GB | 1.8 GB |
コスト削減のための戦略:
# ローカルキャッシュから古いLFSリビジョンを削除
git lfs prune
# 重複排除でストレージ効率化
git lfs dedup
# .lfsconfigでクローン時のフェッチを制限
[lfs]
fetchinclude = "assets/**"
fetchexclude = "archive/**"
lfs.<url>.access設定で認証方法を構成できます。複数ファイルの転送には、デフォルトのバッチ転送モードがシーケンシャル転送より効率的です。
4. 通常のGit追跡からの移行
既に大容量ファイルがコミットされている既存リポジトリでは、git lfs migrateを使用して歴史を書き換え、大容量ファイルをLFSポインタに置き換えます。
# 履歴を書き換える前にバックアップを取得
git lfs migrate import --include="*.psd,*.zip" --everything
移行手順:
- リポジトリをバックアップ
git lfs migrate importを適切な--includeパターンで実行git lfs ls-files --allで確認- チームと調整後、force push
- 全員がリクローン
# 移行ファイルの確認
git lfs ls-files --all
# force push(事前にチームと調整)
git push --force --all
重要:履歴の書き換えはコミットハッシュを変更し、force pushが必要で、オープン中のプルリクエストを破損させます。より影響の少ない方法として、git lfs trackのみを使用して将来のファイルだけを追跡することもできます。5GBのUnityゲームリポジトリがLFS移行後に280MBに削減された事例もあります。
5. CI/CD統合
CI/CDパイプラインでLFSを使用するには明示的な設定が必要です。
GitHub Actions:actions/checkout@v4でlfs: trueを設定するか、チェックアウト後にgit lfs pullを実行します。
- uses: actions/checkout@v4
with:
lfs: true
GitLab CI:GIT_LFS_SKIP_SMUDGE変数でLFSを無効化し、必要なジョブでのみgit lfs pullを実行します。
variables:
GIT_LFS_SKIP_SMUDGE: "1"
before_script:
- apt-get update && apt-get install -y git-lfs
- git lfs install
- git lfs pull --include="models/**"
CI最適化のポイント:
- 大容量ファイル不要のジョブではLFSプルをスキップ
--include/--excludeで必要なファイルのみフェッチ- 実行間で
.git/lfsディレクトリをキャッシュ - LFSサーバーに近いセルフホストランナーを使用して帯域幅コストを削減
6. リポジトリクリーンアップとメンテナンス
LFSリポジトリの健全性を維持するための定期的なメンテナンス:
# ローカルストレージから古いLFSリビジョンを削除
git lfs prune --recent --verify-remote
# 全追跡ファイルの一覧
git lfs ls-files --all
# 最大のファイルを特定
git lfs migrate info --everything --top=10
リモート上の孤立したLFSオブジェクトは、GitHubのStorage設定または該当プラットフォームの管理画面からクリーンアップします。ブランチ間の.gitattributes管理に注意し、LFSパターンのマージコンフリクトはLFSマージドライバが自動解決します。lfs.allowincompletepush設定で中断されたプッシュを適切に処理できます。
7. 代替手段の比較
Git LFSが常に最適とは限りません。以下の代替手段を検討してください:
| ツール | 最適な用途 | ストレージバックエンド | 複雑さ |
|---|---|---|---|
| Git LFS | デザインアセット、バイナリ | ネイティブGitホスティング | 低 |
| DVC | MLデータセット、モデルファイル | S3、GCS、SSH、SMB | 中 |
| Git Annex | 大規模メディア制作 | 任意のリモート | 高 |
| Perforce | 100GB以上のゲームアセット | 集中型サーバー | 高 |
- DVC(Data Version Control):MLワークフロー向けに設計。データセットのバージョン管理、パイプライン追跡、クラウドストレージバックエンドをサポート。単純なバイナリ管理にはLFSの方が適切です。
- Git Annex:柔軟なストレージバックエンド、部分ファイルアクセス、暗号化に対応。強力ですが、複雑さが増します。
- Perforce:100GB以上の超大規模バイナリアセット(ゲーム開発)では集中型モデルが優位です。
8. トラブルシューティングとよくある問題
| 問題 | 解決策 |
|---|---|
git-lfs not found | git-lfsをインストールしgit lfs installを実行 |
| サーバー上にオブジェクトがない | git lfs fetch --allでポインタを同期 |
| LFSマージコンフリクト | LFSマージドライバが自動解決(いずれかを採用) |
| 認証エラー | credential.helperとlfs.<url>.accessを設定 |
| 帯域幅超過 | プランアップグレードまたはリセット待機 |
まとめ
Git LFSはGitでの大容量ファイル管理の事実上の標準です。早期の追跡パターン設定、チーム調整による注意深い移行、ストレージと帯域幅の監視、選択的フェッチによるCI最適化、git lfs pruneによる定期的なクリーンアップが重要です。プロジェクトセットアップの早期にLFSガイドラインを確立することを推奨します。ML特有のワークフローにはDVCを、超大規模バイナリにはPerforceやGit Annexを検討してください。
