versión ver variable pendientes modificados entorno configurar como commits cerrar archivos git git-gc

variable - ver commits pendientes git



¿Qué significan los números en la línea “Total” de la salida de git gc/git repack? (1)

Cuando ejecuto git gc o git repack en mi repositorio de Git, genera una línea "Total" una vez que se hace. Que significan estos numeros?

Un par de ejemplos de un repositorio bastante pequeño:

$ git gc ... Total 576 (delta 315), reused 576 (delta 315) $ git repack -afd --depth=250 --window=250 ... Total 576 (delta 334), reused 242 (delta 0)

Y uno de un repositorio mucho más grande:

$ git gc ... Total 347629 (delta 289610), reused 342219 (delta 285060) ...

Puedo adivinar cuál es ese primer número "Total": el número de objetos Git (por lo tanto, confirmaciones, árboles y archivos) en el repositorio. ¿Qué significan realmente todos los demás?

Ya he visto las páginas de manual de git-gc(1) y git-repack(1) , y también he leído detenidamente sus "Ver también", y mis intentos de buscar en Google solo han producido resultados irrelevantes.


Hice algunos trabajos con dulwich , una implementación de Git en python puro. Lo que voy a decir aquí refleja mi experiencia con la implementación de git de dulwich, no la fuente canónica de git, por lo que puede haber diferencias.

Git es muy simple, quiero decir, ¡tan simple que confunde! El nombre es realmente apropiado para su diseño, que es muy inteligente debido a su estupidez.

Cuando se confirma algo, git toma lo que está en el índice (área de preparación) y crea elementos de resumen SHA, de modo que cada archivo obtiene SHAed y los archivos en cada directorio se SHAed como objetos blob y, por supuesto, la estructura del directorio se SHAed como objetos de árbol, y todo lo que se enlaza en un objeto de confirmación que también tiene un SHA. Git simplemente dispara estos directamente en el sistema de archivo en .git / objects mientras procesa la confirmación. Si tiene éxito en disparar a todos ellos allí, simplemente escribe el SHA del objeto de confirmación más reciente en .git / refs / heads /.

De vez en cuando, un compromiso puede fallar a la mitad. Si algo falla al escribir en .git / objects, git no realiza ninguna limpieza en ese momento . Esto se debe a que, por lo general, solucionará el problema y volverá a realizar el compromiso. En este caso, git se reiniciará exactamente desde donde se detuvo previamente, es decir, a mitad del proceso.

Aquí es donde entra git gc. Simplemente analiza a través de todos los objetos en .git / objetos, marcando todos aquellos a los que se hace referencia de alguna manera por una HEAD o una BRANCH. Todo lo que queda, obviamente, queda huérfano y no tiene nada que ver con nada "importante", por lo que se puede eliminar. Esta es la razón por la que si realiza una bifurcación, realice algún trabajo en esa bifurcación, pero luego abandone esa bifurcación y elimine cualquier referencia a la misma desde su repositorio git, el git gc periódico que se ejecuta purgará totalmente su bifurcación. Esto puede sorprender a algunos usuarios de VCS más antiguos, por ejemplo, CVS nunca olvidó nada, excepto cuando se estrelló o se corrompió (lo cual era frecuente).

git repack (realmente git-pack-objects) es totalmente diferente a git gc (como en, un comando y una operación separados, aunque git gc puede llamar git repack). Como mencioné anteriormente, git simplemente enciende todo en su propio archivo SHAed. Hace gzip antes de ir al almacenamiento de discos, pero obviamente esto no es eficiente en espacio a largo plazo. Entonces, lo que hace git-pack-objects es examinar una serie de objetos SHA para cualquier lugar donde los datos se repliquen en las revisiones. No importa qué tipo de objeto SHA sea, todos se consideran iguales para el embalaje. Luego genera deltas binarias donde tienen sentido, y almacena todo el lote como un archivo .pack en .git / objects / pack, eliminando cualquier objeto empaquetado de la estructura de directorios normal.

Tenga en cuenta que, en general, git-pack-objects crea un nuevo archivo .pack en lugar de reemplazar los archivos .pack existentes, si el archivo del paquete más reciente tiene un tamaño inferior a 1Mb. Por lo tanto, con el tiempo verá que aparecen varios archivos .pack en .git / objects / pack. De hecho, cuando obtiene fetch, simplemente le pide al repositorio remoto que empaquete todos los elementos desempaquetados y que envíe los archivos .pack que el repositorio que busca no tiene al repositorio de recuperación. git repack simplemente llama a git-pack-objects pero le dice que combine los archivos .pack como mejor le parezca. Eso implica descomprimir cualquier cosa que haya cambiado, regenerar los deltas binarios y recomprimir.

Entonces, para responder a su pregunta, la línea total se refiere al número total de objetos en el repositorio de git. El primer número delta es el número de esos objetos totales que son objetos delta binarios, es decir, cuántos objetos ha decidido Git que tienen una gran similitud con otros objetos y se pueden almacenar como un delta binario. El número reutilizado indica cuántos objetos de una fuente comprimida (es decir, un archivo de paquete) se están utilizando sin haber sido comprimidos nuevamente para incluir cambios más recientes. Esto ocurrirá cuando tenga varios paquetes de archivos pero cuando un objeto SHA más reciente se refiera a un elemento de un paquete antiguo como su base, luego le aplica deltas para hacerlo moderno. Esto permite a git hacer uso de revisiones de datos más antiguas previamente comprimidas sin tener que volver a comprimirlas para incluir adiciones más recientes. Tenga en cuenta que git puede adjuntarse a un archivo de paquete existente sin volver a escribir el archivo de paquete completo.

En términos generales, un recuento alto reutilizado indica que se podría reclamar algo de espacio con un reenvasado completo (es decir, un git repack -a) que siempre se reutilizará a cero. Sin embargo, generalmente git se hará cargo de todo eso por ti en silencio. Además, hacer repintados completos puede obligar a algunas búsquedas de git a reiniciarse desde cero debido a que los paquetes difieren, esto depende de la configuración del servidor (permitir que la generación personalizada de paquetes por cliente sea costoso en la CPU del servidor, por lo que algunos de los principales sitios GIT lo deshabilitan).

Esperemos que esto responda a tu pregunta. Realmente, con git es tan simple que te sorprende que funcione al principio, luego, cuando lo envuelves en la cabeza, quedas realmente impresionado. Solo los programadores verdaderamente geniales pueden escribir algo tan simple, pero funciona tan bien porque pueden ver la simplicidad donde la mayoría de los programadores solo pueden ver la complejidad.

Niall