Dominando la Recolección de Basura de Git para un Rendimiento Óptimo

Aprende cuándo ejecutar git gc, qué limpia y cómo evitar una limpieza agresiva riesgosa en repositorios activos.

Dominando la Recolección de Basura de Git para un Rendimiento Óptimo

La recolección de basura de Git evita que tu repositorio acumule objetos sueltos, commits inalcanzables obsoletos y archivos pack ineficientes para siempre. Si tu repositorio se siente lento, ocupa demasiado espacio en disco o ha tenido muchas reorganizaciones y limpieza de ramas, git gc es una de las primeras herramientas de mantenimiento que debes entender.

Normalmente no necesitas ejecutarlo todos los días. Git ejecuta mantenimiento automático durante comandos normales cuando se alcanzan ciertos umbrales. Aún así, saber lo que hace te ayuda a evitar dos errores comunes: ignorar un repositorio inflado durante meses, o ejecutar una limpieza agresiva en un repositorio compartido sin entender el impacto.

Qué Hace la Recolección de Basura de Git

Git almacena datos como objetos: commits, árboles, blobs y etiquetas. Los objetos nuevos pueden comenzar como archivos sueltos bajo .git/objects/. Con el tiempo, Git puede empaquetar muchos objetos juntos en archivos pack compactos. Los objetos empaquetados usan el disco de manera más eficiente y suelen ser más rápidos de escanear para Git.

git gc realiza varias tareas de mantenimiento, incluyendo:

  • Empaquetar objetos sueltos en archivos pack.
  • Consolidar archivos pack existentes cuando sea útil.
  • Eliminar objetos inalcanzables que sean lo suficientemente antiguos para podar.
  • Limpiar archivos temporales dejados por operaciones interrumpidas.
  • Actualizar datos auxiliares como archivos commit-graph en configuraciones modernas de Git cuando está configurado.

Inalcanzable no siempre significa seguro de eliminar inmediatamente. Un commit puede volverse inalcanzable después de una reorganización, enmienda, reinicio o eliminación de rama. Git normalmente mantiene objetos recientemente inalcanzables durante un período de gracia para que tengas tiempo de recuperarlos con git reflog.

Verifica el Tamaño del Repositorio Antes de Limpiar

Comienza midiendo el repositorio en lugar de adivinar:

git count-objects -vH

Los campos útiles incluyen count, size, in-pack, packs y size-pack. Un recuento alto de objetos sueltos puede hacer que las operaciones diarias de Git sean más lentas. Un size-pack grande puede simplemente significar que el repositorio tiene mucha historia real, archivos binarios grandes o activos de proveedores.

Para inspeccionar el uso del disco directamente, ejecuta:

du -sh .git

Si .git es enorme porque alguien cometió artefactos de compilación o archivos grandes, la recolección de basura por sí sola puede no resolver el problema real. Puede que necesites eliminar archivos grandes de futuros commits, moverlos a Git LFS o reescribir la historia con una herramienta como git filter-repo después de coordinarte con el equipo.

Ejecuta la Recolección de Basura Normal

Para una limpieza rutinaria, usa:

git gc

Este es el valor predeterminado seguro. Permite que Git decida qué trabajo de mantenimiento vale la pena y respeta las reglas de poda normales.

Puedes pedirle a Git que haga mantenimiento automático solo si los umbrales dicen que es necesario:

git gc --auto

La mayoría de los usuarios no necesitan llamar a --auto manualmente porque Git ya lo hace en segundo plano. Aún es útil en scripts donde quieres una pasada de limpieza de bajo costo sin forzar un reempaquetado completo cada vez.

Si quieres eliminar objetos inalcanzables antiguos usando el período de gracia estándar, ejecuta:

git gc --prune=now

Usa --prune=now con cuidado. Puede eliminar puntos de recuperación que git reflog podría ayudarte a encontrar. Evítalo justo después de una reorganización complicada, eliminación de rama o reinicio a menos que estés seguro de que no necesitas los objetos antiguos.

Ten Cuidado con --aggressive

git gc --aggressive le dice a Git que gaste más tiempo de CPU tratando de optimizar el empaquetado de objetos:

git gc --aggressive

No es un botón mágico de velocidad. En muchos repositorios, el trabajo extra da poco beneficio en comparación con git gc normal, y puede tomar mucho tiempo en historias grandes. Úsalo solo cuando hayas medido un problema real de tamaño de repositorio o rendimiento y puedas permitirte la ventana de mantenimiento.

Para el trabajo diario, prefiere git gc simple. Si tu repositorio necesita regularmente una limpieza agresiva, el problema más profundo suele ser archivos grandes, artefactos generados o un flujo de trabajo que crea mucha historia inalcanzable.

Usa el Mantenimiento Moderno de Git para el Cuidado Continuo

Las versiones recientes de Git incluyen git maintenance, que puede programar tareas en segundo plano como precarga, actualizaciones de commit-graph y reempaquetado incremental dependiendo de tu plataforma y configuración.

Para ejecutar mantenimiento una vez:

git maintenance run

Para habilitar el mantenimiento programado para tu cuenta de usuario:

git maintenance start

Verifica tu versión de Git y la documentación local antes de confiar en el mantenimiento programado en automatización, porque la integración exacta del programador difiere según el sistema operativo y la compilación de Git.

Flujo de Trabajo Práctico de Limpieza

Un flujo de limpieza seguro para un repositorio local se ve así:

git status
git count-objects -vH
git gc
git count-objects -vH

Asegúrate de que tu árbol de trabajo esté limpio antes del mantenimiento. Git puede ejecutar la recolección de basura con cambios locales presentes, pero un árbol limpio elimina dudas si necesitas solucionar problemas después.

Para un repositorio compartido desnudo en un servidor, programa el mantenimiento durante un período tranquilo. Evita ejecutar reempaquetados pesados durante la actividad máxima de CI, porque las operaciones de clonación, fetch y push pueden competir por el disco y la CPU.

Cuándo la Recolección de Basura No Ayudará

La recolección de basura no puede arreglar todos los repositorios lentos de Git. No eliminará archivos que aún sean alcanzables en la historia. No hará pequeño un monorepo si la historia activa contiene genuinamente años de activos grandes. No reparará un repositorio corrupto por sí mismo.

Si el rendimiento sigue siendo pobre después de una limpieza normal, busca estas causas:

  • Archivos binarios grandes cometidos directamente en Git.
  • Demasiados archivos generados rastreados en el repositorio.
  • Antivirus o indexación del sistema de archivos escaneando .git en cada operación.
  • Almacenamiento de red lento que aloja el árbol de trabajo.
  • Árboles de trabajo muy grandes donde el checkout disperso puede ayudar.

Usa git gc como mantenimiento, no como sustituto de la higiene del repositorio. Ejecuta una limpieza normal cuando los recuentos de objetos crezcan, evita la limpieza agresiva a menos que hayas medido una necesidad, y trata los artefactos grandes rastreados como un problema de flujo de trabajo para solucionar en la fuente.