[実話] GitHubの「ファイルサイズ制限」エラーとの長い戦い ~BFGでも解決できない履歴をfilter-branchで切り捨てる~

August 10, 2025 開発ノート Github

Development Image

GitHubのファイルサイズ制限エラーとの戦いを記録する:BFGが失敗したとき、filter-branchが履歴を切り裂く

2025年8月10日

こんにちは!Webアプリケーションを開発していると、予期せぬGitエラーに遭遇することがあります。今回は、GitHubのファイルサイズ制限エラーとの格闘を記録したブログ記事をまとめました。

始まり:GitHubのファイルサイズ制限を超える悪夢

ある日、Next.jsプロジェクトに変更をプッシュしようとしたところ、見慣れないエラーメッセージが表示されました。

remote: error: File <プロジェクト名>/node_modules/... is 129.50 MB; this exceeds GitHub's file size limit of 100.00 MB remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com. ! [remote rejected] master -> master (pre-receive hook declined) error: failed to push some refs to 'https://github.com/<ユーザー名>/<リポジトリ名>'

原因は単純明快でした。Next.jsプロジェクトディレクトリに.gitignoreファイルを追加し忘れており、巨大なnode_modulesフォルダ全体をコミットしてしまっていたのです。

「なんだ、簡単じゃないか!」と思い、すぐに.gitignoreファイルを追加し、キャッシュをクリアする標準コマンドを実行しました。

.gitignoreに/node_modulesを追加

キャッシュを削除して再コミット

git rm -r --cached . git add . git commit -m "fix: add .gitignore"

しかし、再度プッシュしても同じエラーが発生しました。「大きなファイルコミット」がGitの履歴に記録されると、そう簡単には消えません。

ラウンド2:推奨ツール「BFG」が機能しない…?

履歴の改訂という旅に出ることを決意し、Gitが公式に推奨するBFG Repo-Cleanerという専用ツールを使用することにしました。

  1. Javaを準備し、BFGをダウンロードします。
  2. 安全のためにミラークローンを作成します。 git clone --mirror https://github.com/<ユーザー名>/<リポジトリ名>.git
  3. BFGを実行します!

しかし、ここからが本当の戦いの始まりです。

試行1:フォルダ名で削除 → 失敗!

$ java -jar ../bfg-x.x.x.jar --delete-folders node_modules

BFG aborting: No refs to update - no dirty commits found??

試行2:最新のコミットを保護しない → 失敗!

$ java -jar ../bfg-x.x.x.jar --delete-folders node_modules --no-blob-protection

BFG aborting: No refs to update - no dirty commits found??

試行3:ファイルサイズで削除 → 失敗!

$ java -jar ../bfg-x.x.x.jar --strip-blobs-bigger-than 100M

Warning: No large blobs matching criteria found in packfiles

試行4:git gcでデータベースを最適化して再試行 → 失敗!

$ git gc $ java -jar ../bfg-x.x.x.jar --strip-blobs-bigger-than 100M

Warning: No large blobs matching criteria found in packfiles

試行5:ファイル名を直接指定 → 失敗!

$ java -jar ../bfg-x.x.x.jar -D <大きなファイル名>

BFG aborting: No refs to update - no dirty commits found??

何を試しても、BFGは大きなファイルを見つけることができず、プロセスを中断しました。おそらくサブディレクトリにあったためか、リポジトリが特殊な状態だったためか…理由は不明ですが、BFGの使用を諦めるしかありませんでした。

最終決戦:禁断のGit filter-branch

残された選択肢は一つだけでした。Gitに組み込まれた究極の武器、git filter-branchです。このコマンドは非常に強力ですが、リポジトリを破壊するリスクも伴います。

[最も重要] 実行する前に、必ずプロジェクトフォルダ全体をバックアップしてください!

最悪の事態に備え、以下のコマンドを実行しました。

  1. 履歴の書き換え

これはリポジトリの全履歴をスキャンし、指定されたフォルダ(この場合は<プロジェクト名>/node_modules)を削除します。リポジトリのサイズによっては、完了までにかなりの時間がかかる場合があります。

git filter-branch --force --index-filter 'git rm -r --cached --ignore-unmatch <project_name>/node_modules' --prune-empty --tag-name-filter cat -- --all

  1. リポジトリのクリーンアップ

filter-branchによって残されたバックアップデータを完全に削除し、リポジトリを最適化します。

バックアップ参照を削除(Windows PowerShellでエラーが発生したため、フォルダを直接削除)

PowerShellの場合:

Remove-Item -Recurse -Force .git\refs\original

Linux/macOS/Git Bashの場合:

rm -rf .git/refs/original/

参照ログと不要なデータを削除

git reflog expire --expire=now --all git gc --prune=now

  1. 強制プッシュ

ローカルのリビジョン履歴が正しいと仮定して、GitHubに強制プッシュします。

git push origin --force --all git push origin --force --tags

このプッシュが成功したとき、長い戦いの終わりを告げるプログレスバーが表示されました。

まとめ

この記事が、同じエラーで苦しんでいる誰かの助けになることを願っています。

← Previous Entry: 次期開発計画Next Entry: Mochikana (iOS, Androidアプリ) は日本語初心者にとって非常に役立ちます。
← Back to Blog List