git gc para coding agents: housekeeping, no borrar el working tree
Resumen
git gc comprime y tira objetos inalcanzables del clone local. --auto. Cero --aggressive. Cero --prune=now. Cero --force. No es clean ni prune a mano. Git 2.50.1.

Qué resuelve
Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.
git gc limpia archivos innecesarios y optimiza el repositorio local. El man (git-gc(1); git-scm.com/docs/git-gc HTTP 200, last-modified 2026-08-31; pie del man local Git 2.54.0, 2026-04-19; binario Git 2.50.1 / Apple Git-155): Cleanup unnecessary files and optimize the local repository. SYNOPSIS: git gc [--aggressive] [--auto] [--[no-]detach] [--quiet] [--prune=<date> | --no-prune] [--force] [--keep-largest-pack].
No es clean. clean borra untracked del working tree. gc no toca el working tree ni el índice: comprime revisiones, empaqueta refs, recorta reflog, metadatos de rerere y worktrees viejos, y puede reescribir el commit-graph.
Tampoco es git prune a mano. prune es plumbing de objetos sueltos. El man de gc ya lo llama con gracia (gc.pruneExpire, default 2 weeks). Un agente no lo sustituye.
Contrato: git gc --auto --quiet. Cero --aggressive. Cero --prune=now. Cero --force. Cero en el clone del humano.
Qué hace (y qué no)
El man: Runs a number of housekeeping tasks within the current repository. Porcelain que crea objetos ya dispara git gc --auto cuando el repo creció. gc.auto default 6700 objetos sueltos; 0 apaga toda la heurística, incluido gc.autoPackLimit (default 50 packs). Un agente no reescribe esa config.
--auto: checks whether any housekeeping is required; if not, it exits without performing any work. Si dispara, también hace el resto (rerere, worktrees, reflog). --aggressive pasa -f a git-repack (tira deltas y los recalcula). El man: It's probably not worth it… Not using this at all is the right trade-off for most users.
--prune=<date> (on by default): objetos sueltos más viejos que la fecha. --prune=now prunes loose objects regardless of their age and increases the risk of corruption if another process is writing to the repository concurrently. --no-prune no tira sueltos. --force corre aunque ya haya otro gc. --detach manda el trabajo a background (gc.autoDetach default true). --cruft (on by default) mete inalcanzables en un cruft pack en vez de soltarlos. --keep-largest-pack ignora gc.bigPackThreshold.
HOOKS: git gc --auto corre pre-auto-gc (githooks(5)). Si gc.log existe y es más reciente que gc.logExpiry (default 1.day), --auto imprime el log y sale 0 sin trabajar. Un agente no borra gc.log para “forzar”.
NOTES del man: gc intenta no borrar nada referenciado (ramas, tags, índice, remote-tracking, reflogs, refs/*). Una note no mantiene vivo el objeto anotado.
Verificado 2026-09-06 (Git 2.50.1 / Apple Git-155). Repo mínimo, un commit, working tree limpio:
git gc: 0.rev-parse HEADigual que antes.status -sbsin cambios.git gc --auto: 0. Repo chico: no hay housekeeping. HEAD igual.git gc --quiet: 0.git gc --aggressive --quiet: 0. HEAD igual. El man: tarda más; no hay benchmark que lo pida.git gc --prune=now --quiet: 0. HEAD igual. El man: riesgo si otro proceso escribe.git gc --no-prune --quiet: 0.git gc --force --quiet: 0.git gc --keep-largest-pack --quiet: 0.--foo: 129, unknown option `foo'.- Fuera de un repo: 128, not a git repository.

Lo que el agente sí / no corre
| Quiero | Comando | Trampa |
|---|---|---|
| ¿Hay que limpiar? | git gc --auto --quiet | git gc a pelo en el clone del humano |
| Ver objetos sueltos | git count-objects -v | --aggressive “porque está lento” |
| ¿Sigue vivo un SHA? | git cat-file -e <sha> | --prune=now para “asegurarme” |
| Worktree ajeno stale | nada; reporta | gc.worktreePruneExpire=now |
Prohibido en autónomo:
--aggressive. El man: más tiempo, deltas nuevos, not worth it sin benchmark. Un agente no lo tiene.--prune=now/gc.pruneExpire=now. El man: sube el riesgo de corrupción con writers concurrentes. Default 2 weeks existe por eso.--force. Otro gc puede estar corriendo. El man: even if there may be another git gc instance.--detach/ dejargc.autoDetachdecidir en un run del agente. El proceso se va a background y el agente pierde el exit.- Reescribir
gc.auto,gc.autoPackLimit,gc.reflogExpire,gc.pruneExpire. Esas perillas son del humano / del clone. - Confundirlo con clean. clean borra untracked. gc no.
git prune/git repack/git pack-refssueltos. gc ya orquesta eso.- Correr gc en el worktree del humano o en
main. Solo worktree propio. - Tratar gc como undo. No mueve HEAD. No recupera un commit. Eso es reflog, no gc.
Receta (60 segundos)
Solo en un worktree propio, y solo si porcelain no lo disparó y el disco lo pide:
git status -sb
git gc --auto --quiet
echo $?
git rev-parse HEAD
0y HEAD igual: listo. Reporta “auto-gc” y para.128: no hay repo. No reintentes con--force.129: opción desconocida. No añadas flags de clean.
Cierre = el exit code. Cero commit. Cero push a main. Cero “ahora --aggressive”.

gc vs clean vs reflog vs prune
clean opera el working tree. git clean -n primero; nunca -fdx. gc no lista untracked.
reflog es la bitácora local. gc la recorta con gc.reflogExpire (default 90 días) y gc.reflogExpireUnreachable (default 30). Un git gc no es reflog expire --expire=now. Un agente no acorta esa gracia.
git prune (man git-prune(1), HTTP 200) tira objetos sueltos inalcanzables. El man de gc ya lo llama con --expire 2.weeks.ago. Correr prune a mano salta la gracia.
gc.worktreePruneExpire default 3.months.ago. Un agente no pone now para “limpiar” worktrees ajenos.
El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. gc no es clean: housekeeping del object database, no del disco de trabajo.
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.



