sábado, 23 de julio de 2011

Ahorrando espacio con git gc

Pregunta frecuente ¿Cuanto espacio ocupa un repositorio de git?
Respuesta: Depende, no solamente de los contenidos sino tambien de si los objetos estan empaquetados o no.
Si estan empaquetados pueden llegar a ocupar hasta 10 veces menos cantidad de espacio que si no lo estuvieran.

Para empaquetar los objetos, hay que ejecutar el comando

git gc

NOTA: Despues de que gc limpie y comprima los objetos el repositorio se puede seguir usando de manera transparente. No es necesario ejecutar ningun comando especifico ni nada ya que git trabaja con los objetos empaquetados
NOTA2: por default git viene configurado para correr este comando automaticamente cuando sea necesario, pero puede ser util correrlo a mano algunas veces


Si despues de esto todavia se necesita liberar todavia mas espacio, se pueden eliminar los logs y hacer git gc de nuevo

rm -fr .git/logs


Pero un advertencia, esos logs almacenan los registros que se acceden mediante git reflog y los stashes, con lo que seguramente se perderan cambios que no hayan sido commiteados a alguna rama existente

Como Funciona

Este comando, lo que hace como su nombre lo indica es actuar de "garbage collector", es decir que elimina todos aquellos objetos que son inalcazables, esto es analago a un entorno gestionado como .NET, Java, Ruby, etc... donde el gc borra de la memoria objetos que no estan siendo referenciados por nadie, en este caso las referencias vendrian a ser los branches, los tags, las entradas de logs y los propios objetos que hacen referencia a parent commits (si son commits), blobs y trees. Es decir que git gc no elimina nada que este a nuestro alcance como la informacion referenciada por los branches en los que estamos trabajando e incluso los commits referenciados por los logs.

Pero la accion de git gc no solo se limita a su papel como garbage collector, sino que tambien se encarga de realizar el packing de los objetos, lo cual implica reorganizarlos todos en un solo archivo y comprimirlo usando delta compression, un metodo de compresion optimizado para comprimir snapshots que tiene ligeras diferencias uno con el otro

Para dar un ejemplo, en un repo relativamente nuevo (200 commits aproximadamente) que pesa 1.8 Megabytes, si se examina el directorio .git/objects se podria ver como git almacena los objetos unpacked:
dario@dario-laptop:~/projects/imageruby-devil/.git/objects$ find | head -n 15
.
./71
./71/a0a195d6b9192f3a2ed92afce74600a18d5463
./5e
./5e/d0b14304e16bb8404fc1106923e47b9e8efc65
./11
./11/4db5a061a6a3d9c010c132cc90890bbfe5c8a9
./34
./34/66e89a2fe1078cbd96bccdce9f0525e1039f2c
./06
./06/21559a3294f6d11c7fa80727d8f9dbc8594ad8
./0f
./0f/f89b8482e83ee109dbf2061ea77b436eaa91c8
./0f/ccf20d3f9fc5f92d56ea4f5959218d6a3109eb
./be
...
...
# sigue un monton
...
...

Pero despues de ejecutar git gc, el repositorio pasa a pesar 232 Kilobytes y los objetos ya no estan almacenados de esa forma, ya que se empaquetaron y comprimieron en solo dos archivos:

dario@dario-laptop:~/projects/imageruby-devil/.git/objects$ find
.
./info
./info/packs
./pack
./pack/pack-eaadc1cff53d9b6d8f5a5ba7eb52fe733c61aac6.pack
./pack/pack-eaadc1cff53d9b6d8f5a5ba7eb52fe733c61aac6.idx

NOTA: Para los que no esten enterados, el comando find busca todos los archivos en el directorio y subdirectorios y muestra las rutas de los archivos que encontro por por salida estandar

Links

No hay comentarios:

Publicar un comentario