皆さん、こんにちは!
開発中に、気合を入れて作ったデータセットや高画質な動画、今回僕がハマったような3D点群データ(.las
や.bin
)を「よし、GitHubにプッシュするぞ!」と思ったら、こんな冷たいエラーメッセージに遭遇した経験はありませんか?
😭 パターン1:そもそもプッシュできない
remote: fatal: pack exceeds maximum allowed size (2.00 GiB)
error: remote unpack failed: index-pack failed
😭 パターン2:100MB超えで怒られる
remote: error: GH001: Large files detected. You may want to try Git Large File Storage...
File your_big_file.data is 1.6 GB; this exceeds GitHub's file size limit of 100.00 MB
! [remote rejected] main -> main (pre-receive hook declined)
「うわーっ!どうしよう…」「データ分割する?いや、それは面倒くさい…」
分かります、その気持ち。でも大丈夫!そんな僕らのスーパーヒーロー、Git LFS (Large File Storage) がいれば、この問題はスマートに解決できます。
今回は、僕が実際にハマったエラーとその解決策を、ブログ記事として分かりやすくまとめてみました!
Git LFSは、一言でいうと**「大きなファイルを専門に扱うGitの拡張機能」**です。
本来、Gitはソースコードのようなテキストファイルの差分を管理するのが得意で、動画やデータセットのような大きなバイナリファイルは苦手です。リポジトリがどんどん重くなって、クローンするだけで一苦労…なんてことになりがちです。
Git LFSは、そんな大きなファイルをリポジトリ内では「ポインタ」と呼ばれる軽い参照情報だけを管理し、実際のファイル本体は別の専用ストレージに保存してくれます。これでリポジトリは軽量なまま、大きなファイルも扱えるようになる、という優れものです。
まずは基本から。Git LFSをインストールして、大きなファイルを追跡対象に指定します。
1. Git LFSをインストール (PCに一度だけ)
brew install git-lfs
git lfs install
を実行するだけ!2. リポジトリでLFSを有効化 (プロジェクトごとに一回)
Bash
# LFSを初期化
git lfs install
3. 大きなファイルの種類をLFSに教える
僕の場合は.lasファイルが原因だったので、こう宣言しました。
Bash
git lfs track "*.las"
これで.gitattributes
という設定ファイルが作られ、「.las
ファイルはLFSで管理してね」というルールが追加されます。
4. 通常通りコミット&プッシュ!
Bash
git add .gitattributes
git add path/to/your_big_file.las
git commit -m "Add large file with LFS"
git push origin main
よし、これで完璧!…と思いきや。
僕の場合、.las
ファイルだけでなく、関連して生成されたoctree.bin
というファイルも巨大でした。そして、それをGit LFSを設定する前にコミットしてしまっていたのです。
その結果、冒頭のパターン2のエラーが…!
GH001: Large files detected
そう、git lfs track
は未来のファイルにしか効きません。すでにGitの歴史(コミット履歴)に刻まれてしまった大きなファイルには効果がないのです。「時すでに遅し」状態ですね。
なんてこった!でも、ここからが本番です。
git lfs migrate
Gitには、過去の歴史を書き換えて「なかったこと」にする強力なコマンドがあります。これを使って、すでにコミット済みの巨大ファイルをLFS管理下に移行させましょう!
1. 新たな巨大ファイル(.bin)も追跡対象に
まずは、.binファイルもLFSで管理するようルールを追加します。
Bash
git lfs track "*.bin"
git add .gitattributes
git commit -m "Track .bin files with LFS"
2. タイムマシン、起動!
git lfs migrateコマンドで、歴史上のすべての.lasと.binファイルをLFSに移行します。
Bash
git lfs migrate import --include="*.las,*.bin" --everything
--include
:対象のファイルを指定します。カンマ区切りで複数指定できます。--everything
:すべてのブランチとタグの歴史を書き換えます。このコマンドが完了すると、あなたのリポジトリの歴史は「最初からLFSを使っていた綺麗な歴史」に書き換えられます。
3. 書き換えた歴史をGitHubに反映! (最重要注意点あり)
歴史を書き換えたので、普通のpushはできません。リモートの歴史を強制的に上書きする必要があります。
Bash
git push --force origin main
⚠️ 超重要:git push –force の注意点 ⚠️
このコマンドは、リモートリポジトリ(GitHub上)の歴史をローカルの歴史で強制的に上書きします。
- 個人プロジェクトの場合: 問題ありません。安心して実行してください。
- チームで開発している場合: 絶対に独断で実行しないでください! 他のメンバーの変更が消えてしまう可能性があります。実行する前に必ずチーム全員に連絡し、作業内容を退避してもらうなど、調整が必要です。
僕はこのコマンドで、ついにプッシュを成功させることができました!やったー!🎉
git lfs install git lfs track "*.filetype" git add .gitattributes
# (必要なら追跡ファイルを追加) # git lfs track "*.another_filetype" # git add .gitattributes # git commit ... # 履歴を書き換え git lfs migrate import --include="*.filetype,*.another_filetype" --everything # 強制プッシュ git push --force origin main
GitHubで大きなファイルを扱うのは少しコツがいりますが、Git LFSの使い方さえ覚えればもう怖くありません。同じエラーで困っている誰かの助けになれば嬉しいです!
それでは、Happy Coding! ✨