Da Anonimo (non verificato) , 29 Aprile 2026

Introduzione

Il garbage collection (gc) mantiene il tuo repository compatto e veloce. Git lo esegue automaticamente quando certe soglie vengono superate. Puoi anche invocarlo manualmente.

Cosa fa gc

  1. Impacchetta gli oggetti loose in pack file.
  2. Re-deltifica se richiesto.
  3. Rimuove oggetti irraggiungibili più vecchi della finestra prune-expire.
  4. Fa scadere le entry reflog oltre il loro TTL.
  5. Opzionalmente scrive il file commit-graph.
git gc
git gc --auto
git gc --aggressive
git gc --prune=now
git count-objects -v

Soglie auto-gc

git config gc.auto 6700                 # soglia oggetti loose
git config gc.autoPackLimit 50          # soglia numero di pack
git config gc.autoDetach true           # esegui in background

L'auto-gc scatta dopo operazioni che creano nuovi oggetti, come commit e fetch. Con autoDetach, gira in background e Git ritorna immediatamente.

Scadenza del reflog

git config gc.reflogExpire 90.days
git config gc.reflogExpireUnreachable 30.days
git reflog expire --expire=90.days --all

Le entry raggiungibili durano 90 giorni, quelle irraggiungibili 30 di default. I branch e tag che cancelli lasciano tracce nel reflog che sopravvivono entro quella finestra.

Finestra di prune

git config gc.pruneExpire 2.weeks.ago

Gli oggetti irraggiungibili più vecchi di questo sono candidati alla cancellazione durante gc. --prune=now cancella immediatamente; utile ma pericoloso poiché rimuove i margini di sicurezza.

Aggressivo vs normale

git gc                       # routine: impacchetta nuovi oggetti, pota i vecchi
git gc --aggressive          # ricostruisce i delta da zero

Il gc aggressivo raramente vale la pena; è pesante in CPU e il guadagno è di solito piccolo. Il gc normale è sufficiente per la maggior parte dei repo.

Manutenzione

Git moderno (2.29+) ha un sottosistema maintenance che consolida e migliora gc:

git maintenance start
git maintenance run --task gc
git maintenance run --task commit-graph
git maintenance run --task incremental-repack

git maintenance start registra un job in background (cron, launchd o timer systemd) che ottimizza periodicamente il repo.

Operazioni bloccate

Se gc viene interrotto, potresti vedere un file di lock stantio:

ls .git/gc.pid
rm .git/gc.pid    # solo dopo aver confermato che nessun gc è in esecuzione

Cosa gc non cancella mai

Diverse classi di oggetti sono esenti da gc finché il loro riferimento non scade:

  • Oggetti raggiungibili da qualsiasi ref sotto refs/.
  • Oggetti raggiungibili dal reflog di qualsiasi ref (fino alla scadenza del reflog).
  • Oggetti sotto refs/stash (la lista stash).
  • Oggetti fissati da mapping git replace.
  • Oggetti raggiungibili dal HEAD e index dei worktree.
git fsck --unreachable --no-reflogs
git reflog expire --expire-unreachable=now --all
git gc --prune=now

Quell'ultima sequenza è la ricetta standard "cancella davvero la storia irraggiungibile"; ricorrici con cura.

Errori comuni

Eseguire git gc --prune=now subito dopo un'operazione distruttiva, eliminando la rete di sicurezza del reflog. Aspetta sempre la finestra di default a meno che tu non abbia davvero bisogno dello spazio. Disabilitare auto-gc su un repo a movimento veloce, accumulando milioni di oggetti loose. Eseguire --aggressive programmato sotto l'assunzione che "di più è meglio"; brucia solo CPU. Infine, eseguire gc concorrentemente con git push su un server; Git moderno gestisce la concorrenza in sicurezza, ma script personalizzati che combattono su .git/objects possono corrompere. Usa git maintenance piuttosto che cron job fatti in casa.