Packfiles, GC y rendimiento
Git empieza guardando objetos sueltos, pero con el tiempo compacta esos objetos en packfiles para ahorrar espacio y acelerar operaciones. Entender esto ayuda en repositorios grandes y en problemas de rendimiento.
Objetos sueltos
Al crear commits, Git puede guardar objetos como archivos individuales dentro de .git/objects.
.git/objects/
a1/
b2c3...Esto es simple, pero no escala bien si hay miles o millones de objetos.
Packfiles
Un packfile agrupa muchos objetos en un archivo compacto.
.git/objects/pack/
pack-abc123.pack
pack-abc123.idxEl archivo .pack contiene datos. El .idx permite buscar objetos rapidamente.
Delta compression
Git puede guardar un objeto como diferencia frente a otro objeto parecido.
Ejemplo conceptual:
version 1: archivo completo
version 2: delta contra version 1
version 3: delta contra version 2Esto es especialmente util en archivos de texto que cambian poco entre commits.
Garbage collection
git gc limpia y compacta el repositorio.
git gcGit tambien ejecuta mantenimiento automatico en algunos momentos.
Comando moderno:
git maintenance runObjetos no alcanzables
Despues de reset, rebase o amend, pueden quedar commits no alcanzables por ramas o tags. No se borran al instante.
git fsck --unreachableCon el tiempo, Git puede eliminarlos durante limpieza.
Reflog y expiracion
El reflog conserva referencias temporales a estados anteriores.
git reflogConfiguraciones utiles:
git config --get gc.reflogExpire
git config --get gc.pruneExpireNo cambies estos valores sin una razon clara.
Repositorios pesados
Sintomas:
git statustarda demasiado.git checkoutogit switchson lentos..gitocupa mucho.- Clonar tarda demasiado.
Diagnostico:
git count-objects -vH
git gc --dry-runArchivos grandes
Git no es ideal para binarios pesados que cambian a menudo.
Opciones:
- Evitar subir artefactos generados.
- Usar
.gitignore. - Usar Git LFS para binarios necesarios.
- Separar datasets o builds en almacenamiento externo.
Encontrar objetos grandes
Comando de investigacion:
git rev-list --objects --allEn shells Unix se suele combinar con git cat-file --batch-check, sort y tail. En Windows, conviene usar herramientas especificas o scripts controlados para no hacer una limpieza destructiva por error.
Clones parciales y shallow clones
Shallow clone:
git clone --depth 1 https://github.com/org/proyecto.gitEs util para CI cuando no necesitas historial completo.
Partial clone:
git clone --filter=blob:none https://github.com/org/proyecto.gitPuede reducir descargas en monorepos o repos con muchos archivos grandes.
Sparse checkout
Permite trabajar solo con parte del repositorio.
git sparse-checkout init --cone
git sparse-checkout set apps/api packages/sharedEs util en monorepos cuando un equipo solo toca una zona.
Diagrama de almacenamiento
flowchart TB
C["Commits"] --> O["Objects"]
O --> L["Loose objects"]
O --> P["Packfiles"]
P --> IDX["Index files"]
M["Maintenance"] --> P
M --> PR["Prune unreachable objects"]Buenas practicas
- No subas dependencias, builds ni caches al repo.
- Usa
.gitignoreantes de hacer el primer commit del proyecto. - Considera Git LFS para binarios grandes que deban versionarse.
- En CI, usa shallow clone solo si no necesitas tags o historial.
- Antes de limpiar historia, crea backup o rama de seguridad.
