本文へ移動
Monaural Sound

開発関連

Gitブランチ削除後の容量解放

Gitのローカルリポジトリで継続的に作業していると、消し忘れたマージ済みのブランチや、作業途中で保留中の作業ブランチ等が増えて、作業PCの容量を圧迫することがある。そんな時 git branch -D で不要なブランチを削除してクリーンアップするのが一般的だと思う。しかし、このコマンドでブランチを消しただけでは、PCのディスク容量はすぐには解放されない。 Git は安全のために削除されたブランチが参照していたコミットやオブジェクトを「孤立したデータ(Unreachable Object)」として内部に一時保持している。そのため、物理的な容量をすぐに確保するには不要になったキャッシュをクリア(ガベージコレクション)することが必要になる。

容量を開放する手順

  1. (必要であれば)Gitリポジトリの全体サイズを計測する:
du -sh .git
  1. 不要なブランチを削除する:
git branch -D <BRANCH_A> <BRANCH_B> <...>
  1. 削除済みブランチの古い参照履歴(reflog)を消去する:
git reflog expire --expire=now --all
  1. 孤立したオブジェクトを完全に削除してデータベースを最適化する:
git gc --prune=now
  1. Gitリポジトリの全体サイズを再確認する:
du -sh .git

※ Windowsの PowerShell を利用する場合、リポジトリのサイズ計測コマンドを下記のようにする:

Get-ChildItem -Recurse .git | Measure-Object -Property Length -Sum

注意:誤って消したコミットの復元ができなくなる

git reflog expire と git gc --prune=now を実行すると、削除したブランチに含まれていたコミットは完全に削除される。そのため、誤って消したコミットなどのローカルリポジトリにだけ履歴が残っているコミットを復元することができなくなる。

注意:Stash した退避データについて

git stash で退避したデータは、Git 内部で refs/stash という専用参照で保護されているため、ガベージコレクション(git gc)を実行しても削除対象にならない。そのため、git stash list で表示される退避データはそのまま残る。しかし、git stash drop や git stash pop で破棄したものは完全に削除される。stash のログ(参照履歴)に残っていれば、コミットハッシュを探して復元できる場合もあるが、git reflog expire と git gc --prune=now 実行後はその参照履歴ごと抹消されるので破棄済み stash からの復旧はできなくなる。

注意:大容量ファイル(画像や動画など)を過去にコミットしていた場合

この場合、単にブランチを消すだけではなく、現在の作業ブランチのコミット履歴自体から大容量ファイル(サイズの大きい画像や動画ファイル等)を完全に削除しないとリポジトリ容量が解放されない。その場合は git-filter-repo などのツールを使ってコミット履歴自体を書き換える必要がある。 ただし、これはコミットハッシュがすべて再計算され、チームで共有しているリポジトリの場合は他の開発者のローカル環境との整合性が崩れてしまう。影響範囲が大きくリスクも高いので、リポジトリ全体のバックアップ後にチームメンバーと共有してから作業する必要がある。 そもそも Git 管理ファイルに大容量ファイル等を含めるなっていうことである。

  • Git
  • Tips

関連記事

Ka2(カツ)

ゲームと、アメコミと、アニメと、歴史が好きなフリーランスのフルスタック系ITエンジニア。
仕事は気に入ったものだけを「最小限」に、趣味のオープンソース開発と小説書くのを「最大限」に、
好きなこと『だけ』して生きていく。