git gc

Czyści i kompresuje bazę obiektów, optymalizując repozytorium.

git gc (od garbage collection) to wewnętrzny sprzątacz Gita. Po wielu commitach, merge’ach i amendach repozytorium puchnie od luźnych obiektów (loose objects) i porozrzucanych paczek. git gc upakowuje te obiekty w skompresowane pliki pack, usuwa nieosiągalne śmieci, czyści zbędne refy i reflogi, a przy okazji przepakowuje istniejące paczki. Efekt: mniejszy katalog .git i szybsze operacje. Git zwykle odpala to automatycznie w tle (git gc --auto) po niektórych komendach, więc ręcznie sięgasz po nie głównie wtedy, gdy repo wyraźnie spuchło albo chcesz wymusić porządki.

Składnia i najważniejsze opcje

Podstawowa składnia: git gc [--aggressive] [--prune=]

  • --aggressive — przelicza delty od zera (repack z -f). Mniejsze repo kosztem dużo dłuższego czasu i CPU. Nie na co dzień.
  • --prune= — usuwa luźne obiekty starsze niż podana data. Domyślnie 2.weeks.ago (sterowane przez gc.pruneExpire). --prune=now kasuje wszystko nieosiągalne natychmiast.
  • --no-prune — w ogóle nie usuwa luźnych obiektów, tylko pakuje.
  • --auto — sprawdza, czy sprzątanie jest w ogóle potrzebne (próg to ok. 6700 luźnych obiektów); jeśli nie, kończy bez pracy. To wariant, który Git woła sam.
  • --quiet — wycisza pasek postępu i komunikaty.
  • --keep-largest-pack — zostawia największą istniejącą paczkę nietkniętą, a przepakowuje tylko resztę. Szybsze na dużych repo.
  • --force — uruchamia gc nawet, gdy inny proces gc wygląda na aktywny (plik gc.pid).

Przykłady użycia

  • git gc — standardowe porządki: pakuje luźne obiekty, czyści refy, usuwa śmieci starsze niż 2 tygodnie.
  • git gc --auto — sprząta tylko jeśli przekroczono progi. Bezpieczne do wrzucenia w skrypt czy hooka.
  • git gc --aggressive --prune=now — maksymalna kompresja plus natychmiastowe usunięcie wszystkiego nieosiągalnego. Dla repo, które naprawdę spuchło — i gdy nie potrzebujesz odzyskiwać porzuconych commitów.
  • git gc --prune=now — szybkie czyszczenie bez przebudowy delt, np. zaraz po git filter-repo czy usunięciu dużego pliku z historii.
  • git count-objects -vH — nie jest częścią gc, ale pokaż sobie rozmiar repo przed i po, żeby zobaczyć, co dało sprzątanie.

Częste błędy i pułapki

–aggressive to nie magia. Jest wolne i przy zwykłym repo rzadko daje wymierny zysk — Git i tak dobrze pakuje na bieżąco. Odpalaj świadomie, nie z przyzwyczajenia.

–prune=now bywa nieodwracalne. Kasuje obiekty nieosiągalne z żadnego refa. Jeśli „zgubiłeś” commit po resecie, najpierw szukaj go w git reflog — po agresywnym prune może już nie dać się go odzyskać.

Komunikat „gc is already running”. Zwykle to padły wcześniejszy proces i osierocony gc.pid. Upewnij się, że żadne gc faktycznie nie chodzi, dopiero potem rozważ --force.

Zachowanie jest spójne między systemami (Linux, macOS, Windows) — to ta sama komenda Gita, więc różnic między dystrybucjami tu nie uświadczysz; co najwyżej domyślne progi zależą od wersji Gita.

Powiązane komendy: git repack, git prune, git fsck, git count-objects, git reflog, git maintenance.