【テクニカル・上級編】Gitリポジトリの断捨離:git-pruneとreflogを活用した「孤立オブジェクト」の完全駆除術 – バージョン管理・CI/CD活用バイブル

魂の断捨離:Gitリポジトリを「極限まで軽量化」する孤立オブジェクト駆除の深淵

リポジトリが肥大化し、`git fetch` が重くなり、CI/CDのクローン時間が分単位で伸びる――。それは、お前のリポジトリが「デジタルゴミ屋敷」と化している証拠だ。

Gitは本質的に「追記型」のデータ構造であり、一度コミットしたデータは、たとえ削除したように見えても、`.git` ディレクトリの深淵に残り続ける。これこそが、数年運用されたリポジトリが突如として数GBに膨れ上がる真因だ。

今日は、Gitの内部構造を掌握し、`reflog` と `prune` を操ってリポジトリを「新品同様」の軽快さに戻す、外科手術レベルの最適化術を伝授する。

—

1. なぜ「削除」しても消えないのか:Gitの墓場構造

Gitは、オブジェクト(Blob, Tree, Commit)を一度書き込むと、決してそれを即座に消去しない。`git branch -d` や `git reset –hard` を実行しても、それらは単に「どこからも参照されなくなったオブジェクト(Dangling Objects)」になるだけだ。

これらは `reflog` という名の「履歴の安全網」に守られている。`reflog` は作業のやり直しには最強の武器だが、長期間放置すれば、過去の残骸がリポジトリを物理的に蝕む。

2. 駆除の作法:安全かつ確実に「物理消去」する手順

単にコマンドを叩くだけでは不十分だ。以下の手順は、リポジトリの整合性を保ちつつ、不要な脂肪だけを削ぎ落とすプロトコルである。

Step 1: 孤立オブジェクトの特定

まずは、どれだけのゴミが埋まっているかを可視化する。

どこからも参照されていない、物理的に無駄なオブジェクトを列挙
git fsck –lost-found –no-reflog

Step 2: reflogの「期限切れ」を強制する

Gitはデフォルトで、過去90日間の操作を `reflog` に保持する。これを今すぐ破棄する。

全てのreflogを即座に期限切れにし、削除対象にする
git reflog expire –all –expire=now

Step 3: ゴミ掃除の実行

ここで初めて `prune` を行う。`gc`(Garbage Collection)を呼び出すのが最も効率的だ。

孤立したオブジェクトを物理削除し、パックファイルを再構成する
git gc –prune=now –aggressive

※ `–aggressive` は強力だが時間がかかる。リポジトリが数GBを超える場合は、これをCIの夜間バッチ等で実行するのが定石だ。

—

3. 自動化ハック:CIパイプラインへの「セルフ・クリーニング」実装

CIのたびに実行するのは非効率だが、週に一度の「リポジトリ・メンテナンス」を自動化するのはDevOpsの嗜みである。以下は、GitHub Actionsの `workflow_dispatch` で実行可能な、最適化スクリプトのテンプレートだ。

!/bin/bash
.github/scripts/repo-maintenance.sh

set -e

1. 肥大化の兆候を検知
SIZE_BEFORE=$(du -sh .git | cut -f1)

2. 徹底的なガベージコレクション
–aggressive を伴う再パックにより、デルタ圧縮を最適化する
git gc –prune=now –aggressive –prune=now

3. ログ出力(最適化の成果を可視化)
SIZE_AFTER=$(du -sh .git | cut -f1)
echo “::notice::Repo optimization complete: $SIZE_BEFORE -> $SIZE_AFTER”

—

4. エキスパートの知見:低レイヤからの最適化アドバイス

パックファイル(Packfile)の魔力

Gitの性能低下の多くは、`objects/pack/` 内部の断片化にある。`git gc` はこれらを一つにまとめ、圧縮率を極限まで高める。もしリポジトリが極端に大きい場合、以下の設定を試してほしい。

デルタ圧縮のメモリ制限を緩和(メモリ潤沢なビルドサーバ向け)
git config –global pack.windowMemory 1g
git config –global pack.packSizeLimit 2g

なぜ「 shallow clone」で逃げてはいけないのか

CIで `git clone –depth 1` を使うのは、一時的な解決策に過ぎない。真の熟練者は、リポジトリそのものを健全に保ち、完全な履歴を持ちながらも高速に動作させることを目指す。`prune` を正しく適用すれば、完全なクローンであっても、肥大化したリポジトリより高速に処理できる。

—

結び:エンジニアとしての美学

リポジトリは、チームの思考のログである。しかし、不要な残骸を放置することは、思考のノイズを蓄積することと同義だ。

`reflog` を理解し、`prune` を制御下に置くことは、単なる容量の節約ではない。Gitという強力なツールを、自身の支配下に置くための通過儀礼である。

今すぐお前のリポジトリの `.git` サイズを確認してみろ。それが数年分の「無駄」の総量だ。さあ、今夜はコードを書く前に、リポジトリの魂を浄化することから始めよう。

タイトルとURLをコピーしました