git gc --auto を clone‑reset に組み込み、キャッシュのパック増大を抑制

basecamp/kamal

Kamal のビルドキャッシュは kamal-clones ディレクトリを再利用することで高速化していますが、リポジトリのガーベジコレクションが行われず .git/objects/pack/ が無制限に肥大化していました。本 PR はその肥大化を防ぐため、クローンリセット工程の最後に git gc --auto --quiet を自動実行する変更です。

背景

Kamal はデプロイごとに同一サービスのビルドキャッシュを fetch + reset --hard + clean -fdx で再利用しています。このフローはビルド時間を大幅に短縮しますが、git gc が呼び出されない点が抜け落ちていました。その結果、git fetch が毎回新しいオブジェクトを .git/objects/pack/ に追加し、長期間使用されたキャッシュで数百メガバイト、場合によっては数ギガバイトまでサイズが増大します。実際に開発環境で SSD が 100% に達した事例が報告されており、クライアント側のディスク容量枯渇リスクが顕在化しています。

この問題は別 Issue #1794 のリモート BuildKit ボリューム肥大と同種の「キャッシュの寿命管理がない」ケースですが、今回はローカルキャッシュに焦点を当てた最小限の修正となります。

技術的な変更

clone_reset_steps 配列に git gc --auto --quiet を追加入しただけのシンプルな実装です。既存のステップは変更せず、サブモジュール更新の直後に新しいステップを追加する形を取っています。この追加により、Git が内部で設定された gc.auto(デフォルト 6700)や gc.autoPackLimit(デフォルト 50)を基準に自動でリパックを行い、パックファイルの無制限蓄積を防止します。

@@ -9,7 +9,8 @@ def clone_reset_steps
       git(:fetch, :origin, path: escaped_build_directory),
       git(:reset, "--hard", Kamal::Git.revision, path: escaped_build_directory),
       git(:clean, "-fdx", path: escaped_build_directory),
-      git(:submodule, :update, "--init", path: escaped_build_directory)
+      git(:submodule, :update, "--init", path: escaped_build_directory),
+      git(:gc, "--auto", "--quiet", path: escaped_build_directory)
     ]
   end

さらに、テスト clone reset runs git gc --auto to bound pack growth が追加され、clone_reset_steps が期待通り gc --auto --quiet を含むことを自動的に検証しています。これにより、将来的なリグレッションが防がれ、変更の意図が永続的に保証されます。

設計判断

既存の配列に要素を追加するだけという非侵襲的なアプローチが選ばれました。git gc はデフォルトで何もしないケースが多く、--auto--quiet の組み合わせは出力の副作用も最小化します。そのため、従来のデプロイフローの速度や挙動に影響を与えず、キャッシュサイズを自然に抑制できる設計となっています。また、新しい設定キーやオプションを導入しないことで、後方互換性が完全に保たれ、既存のデプロイパイプラインを改修する必要がありません。

この判断は、Kamal が提供する「設定なしで即戦力になる」理念に合致し、ユーザーが追加作業を行わずにディスク使用量の上限を確保できる点で価値があります。

まとめ

本 PR は git gc --auto --quiet をクローンリセット工程に組み込むだけの小さな変更で、キャッシュのパックファイル蓄積を自然に制御し、ディスク容量枯渇という実運用リスクを解消します。既存フローへの侵入は最小限に抑えられ、テストにより動作保証が追加されたため、今後のリリースでも安全に利用できるでしょう。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
374287e8

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文、背景、技術的な変更、設計判断(任意)、まとめの全要素が揃っており、総論→各論→結論の構成が明確です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

コードブロックは正しい diff シンタックスで記述され、PRリンクは #1866 の形式で正しくハイパーリンク化されています。ファイル名付きハイライトは不要なので問題なしです。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

エンジニア向けの専門的な内容で、初心者向けの過剰な説明はありません。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションは総論パラグラフで要旨を示し、続く段落で具体例・コードを示し、最後に結論的まとめがあります。段落はトピックセンテンスで始まり、長さも適切で空行で区切られています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事中の diff コードブロックは提供された PR の diff と完全に一致しており、ファイル名や行番号の相違はありません。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

`git gc --auto --quiet`、`clone_reset_steps`、`gc.auto` などの用語は PR と一致し、誤用はありません。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

キャッシュ肥大の原因や `git gc --auto` の効果についての説明は PR の記述と合致しています。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事の主張はすべて PR のタイトル、説明、Diff で裏付けられており、推測や外部知識の付加はありません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

デフォルト設定値 6700、50 などの数値は PR と一致しています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトルは PR タイトルの意味を正確に日本語化しており、内容と一致しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

LTS やリリース日程等の外部情報は含まれていません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

時間表現の歪曲はなく、PR の記述と整合しています。