tag tab mark git

tab - git tag push to server



¿Qué son los paquetes delgados de Git? (3)

Mi entendimiento es que es una optimización para transmitir objetos entre dos repositorios.

Creo que solo lo usarías al implementar tus propios servicios git que no usen el paquete de envío y recepción.

No he encontrado mucho en paquetes delgados, y la información de las páginas de manual es bastante críptica sobre esto. Sé que tiene algo que ver con conexiones lentas, pero ¿qué sería una "conexión lenta"?

¿Cuáles son sus pros y sus contras? ¿Cuándo debería usarlo, cuándo no debería usarlo?


Nota del git 1.8.5 (Q4 2013) :

Usted pensaría que deshabilitar la opción delgada sería con push --no-thin?
Estarías equivocado hasta el 1.8.5:

" git push --no-thin " en realidad deshabilita la optimización de "transferencia de paquete delgado".

Vea commit f7c815c para todos los detalles sangrientos, gracias a "pclouds" - Nguyễn Thái Ngọc Duy :

empujar: respeto --no-thin

  • Desde el inicio de push.c en 755225d, 2006-04-29 , la opción " thin " se habilitó de forma predeterminada, pero se pudo desactivar con --no-thin .

  • Luego, Shawn cambió el valor predeterminado a 0 para guardar los recursos del servidor en a4503a1, 2007-09-09 . --no-thin funcionó muy bien.

  • Un día después, en 9b28851 , Daniel extrajo algo de código de push.c para crear transport.c . Él (probablemente accidentalmente) cambió el valor predeterminado de 0 a 1 en transport_get() .

De ahí en adelante, no --no-thin es efectivamente no-op porque git-push todavía espera que el valor predeterminado sea falso y solo llama a transport_set_option() cuando la variable " thin " en push.c es true (lo cual no es necesario).
Corrija el código para respetar --no-thin llamando a transport_set_option() en ambos casos.

receive-pack aprende acerca de la --reject-thin-pack-for-testing , que es solo para propósitos de prueba, por lo tanto, no hay actualización de documentos.


Para el registro, la página del manual ( index-pack ) indica:

Es posible que git-pack-objects construya un paquete "delgado", que registra objetos en forma deltificada en función de objetos no incluidos en el paquete para reducir el tráfico de red .
Se espera que esos objetos estén presentes en el extremo receptor y deben incluirse en el paquete para que ese paquete sea autónomo e indexable.

Eso completaría la página de --thin git push de la opción --thin :

La transferencia delgada utiliza ciclos adicionales para minimizar la cantidad de objetos que se enviarán y se usarán en una conexión más lenta

Por lo tanto, una "red lenta" en este caso es una conexión a la que desea enviar la menor cantidad de datos posible.

Consulte más información en "La obtención de Git para muchos archivos es lenta en comparación con un disco de alta latencia ".

En este hilo , Jakub Narębski explica un poco más (en el contexto sobre el uso de git gc en el lado remoto, así como en el lado local):

Git hace la deltificación solo en paquetes de archivos.
Pero cuando se empuja a través de SSH, git generaría un archivo de paquete con confirmaciones que el otro lado no tiene, y esos paquetes son paquetes delgados, por lo que también tienen deltas ...
pero el lado remoto luego agrega las bases a esos paquetes delgados haciéndolos independientes.

Más precisamente:

En el lado local:
git-commit crea objetos sueltos (comprimidos, pero no deltificados). git-gc embala y deltifica.

En el lado remoto (para protocolos inteligentes, es decir, git y ssh):
git crea paquete delgado , deltified;
en el lado remoto, git hace que el paquete sea grueso / independiente al agregar objetos base (object + deltas), o explota el paquete en un objeto suelto (objeto).
Necesita git-gc en el servidor remoto para deltificar completamente en el lado remoto. Pero la transferencia está completamente deltificada.

En el lado remoto (para protocolos simples, es decir, rsync y http):
git encuentra los paquetes necesarios y los transfiere completos.
Así que la situación es como en el lado local, pero git puede transferir más de lo que realmente se necesita porque transfiere paquetes en su totalidad.

El problema anterior estaba relacionado con el uso (o no uso) de git push --thin : ¿cuándo lo usas o no?
Resulta que sí necesita administrar con cuidado sus objetos binarios si desea que git se aproveche de esos paquetes finos:

  1. Cree el nuevo nombre de archivo simplemente copiando el antiguo (de modo que se utiliza el blob anterior)
  2. cometer
  3. EMPUJAR
  4. copia el nuevo archivo real
  5. cometer
  6. EMPUJAR.

Si omite el PUSH medio en el paso 3, ni " git push " ni " git push --thin " pueden darse cuenta de que este nuevo archivo puede "construirse de forma incremental" en el lado remoto (aunque git-gc lo aplasta por completo) El paquete).

De hecho, la forma en que funcionan los paquetes delgados es almacenar delta contra un objeto base que no está incluido en el paquete.
Los objetos que no están incluidos pero que se usan como base delta son actualmente solo la versión anterior de un archivo que forma parte de la actualización que se debe enviar / recuperar.
En otras palabras, debe haber una versión anterior con el mismo nombre para que esto funcione.
De lo contrario, no se escalaría si la confirmación anterior tuviera miles de archivos para probar.

Esos paquetes finos fueron diseñados para diferentes versiones del mismo archivo en mente, no diferentes archivos con casi el mismo contenido. El problema es decidir qué base delta preferida se agregará a la lista de objetos. Actualmente solo se consideran los objetos con la misma ruta que los modificados.