Einführung
Garbage Collection (gc) hält Ihr Repository kompakt und schnell. Git führt sie automatisch aus, wenn bestimmte Schwellen überschritten sind. Sie können sie auch manuell aufrufen.
Was gc tut
- Packt lose Objekte in Pack-Dateien.
- Re-deltifiziert auf Anfrage.
- Entfernt unerreichbare Objekte, älter als das Prune-Expire-Fenster.
- Lässt Reflog-Einträge nach ihrem TTL ablaufen.
- Schreibt optional die commit-graph-Datei.
git gc
git gc --auto
git gc --aggressive
git gc --prune=now
git count-objects -v
Auto-gc-Schwellen
git config gc.auto 6700 # Schwellenwert für lose Objekte
git config gc.autoPackLimit 50 # Schwelle für Anzahl Packs
git config gc.autoDetach true # im Hintergrund laufen lassen
Auto-gc feuert nach Operationen, die neue Objekte erzeugen, wie commit und fetch. Mit autoDetach läuft es im Hintergrund und Git kehrt sofort zurück.
Reflog-Ablauf
git config gc.reflogExpire 90.days
git config gc.reflogExpireUnreachable 30.days
git reflog expire --expire=90.days --all
Erreichbare Einträge bleiben standardmäßig 90 Tage, unerreichbare 30. Branches und Tags, die Sie löschen, hinterlassen Reflog-Spuren, die innerhalb dieses Fensters überleben.
Prune-Fenster
git config gc.pruneExpire 2.weeks.ago
Unerreichbare Objekte, älter als dies, kommen während gc zur Löschung in Frage. --prune=now löscht sofort; nützlich, aber gefährlich, da es Sicherheitsmargen entfernt.
Aggressiv vs. normal
git gc # Routine: neue Objekte packen, alte prunen
git gc --aggressive # Deltas von Grund auf neu aufbauen
Aggressives gc ist selten lohnend; es ist CPU-intensiv und der Gewinn ist üblicherweise gering. Normales gc ist für die meisten Repositories ausreichend.
Maintenance
Modernes Git (2.29+) hat ein maintenance-Subsystem, das gc konsolidiert und verbessert:
git maintenance start
git maintenance run --task gc
git maintenance run --task commit-graph
git maintenance run --task incremental-repack
git maintenance start registriert einen Hintergrund-Job (cron, launchd oder systemd-Timer), der das Repository periodisch optimiert.
Gesperrte Operationen
Wenn gc unterbrochen wird, sehen Sie möglicherweise eine veraltete Lock-Datei:
ls .git/gc.pid
rm .git/gc.pid # nur nach Bestätigung, dass kein gc läuft
Was gc nie löscht
Mehrere Objektklassen sind von gc ausgenommen, bis ihre Referenz abläuft:
- Objekte, die von einer Ref unter
refs/aus erreichbar sind. - Objekte, die aus dem Reflog einer Ref erreichbar sind (bis zum Reflog-Ablauf).
- Objekte unter
refs/stash(die Stash-Liste). - Objekte, die durch
git replace-Mappings festgehalten werden. - Objekte, die aus HEAD und Index der Worktrees erreichbar sind.
git fsck --unreachable --no-reflogs
git reflog expire --expire-unreachable=now --all
git gc --prune=now
Diese letzte Sequenz ist das Standard-"Wirklich unerreichbare Historie löschen"-Rezept; greifen Sie vorsichtig danach.
Häufige Fehler
git gc --prune=now direkt nach einer destruktiven Operation ausführen und das Reflog-Sicherheitsnetz beseitigen. Warten Sie immer das Standardfenster ab, es sei denn, Sie brauchen wirklich den Platz. Auto-gc auf einem schnellen Repository deaktivieren und Millionen lose Objekte ansammeln. --aggressive regelmäßig laufen lassen unter der Annahme "mehr ist besser"; es verbrennt nur CPU. Schließlich: gc gleichzeitig mit git push auf einem Server laufen lassen; modernes Git handhabt Nebenläufigkeit sicher, aber benutzerdefinierte Skripte, die um .git/objects kämpfen, können korrumpieren. Verwenden Sie git maintenance statt selbstgemachter Cron-Jobs.