git fetch falla debido a una falla del objeto del paquete

4 minutos de lectura

avatar de usuario
niquel

Cuando agrego nuestro repositorio remoto como upstream e intento recuperarlo, falla como se muestra a continuación:

    $ git fetch upstream
    remote: Counting objects: 11901, done.
    remote: aborting due to possible repository corruption on the remote side.
    error: pack-objects died of signal 9
    error: git upload-pack: git-pack-objects died with error.
    fatal: git upload-pack: aborting due to possible repository corruption on the re
    mote side.
    fatal: protocol error: bad pack header

Entiendo que falla debido a que tiene archivos enormes en el repositorio (que sí tenemos), pero ¿por qué no falla cuando clono el mismo repositorio? Porque puedo clonar el repositorio con éxito. ¿No deberían empaquetarse los mismos objetos en el momento de una solicitud de clonación?

avatar de usuario
Torek

Para ampliar un poco la respuesta de VonC …

En primer lugar, puede ser útil tener en cuenta que signal 9 se refiere a SIGKILL y tiende a ocurrir porque el control remoto en cuestión es un host Linux y el proceso está siendo destruido por Linux “OOM asesino” (aunque algunos sistemas que no son Linux se comportan de manera similar).

A continuación, hablemos de objetos y archivos de paquete. Un “objeto” de git es uno de los cuatro tipos de elementos que se encuentran en un repositorio de git: un “blob” (un archivo); un “árbol” (una lista de blobs, sus modos y sus nombres almacenados en un directorio: es decir, qué se convertirá en un directorio o carpeta cuando se descomprima una confirmación); una “confirmación” (que proporciona el autor de la confirmación, el mensaje y el árbol de nivel superior, entre otros datos); y una “etiqueta” (una etiqueta anotada). Los objetos se pueden almacenar como “objetos sueltos”, con un objeto en un archivo por sí mismo; pero estos pueden ocupar mucho espacio en disco, por lo que en su lugar se pueden “empaquetar”, muchos objetos en un archivo con compresión adicional agregada.

Hacer un paquete con una gran cantidad de objetos sueltos, hacer esta compresión, es (o al menos puede ser) una operación intensiva en CPU y memoria. La cantidad de memoria requerida depende de la cantidad de objetos y sus tamaños subyacentes: los archivos grandes requieren más memoria. Muchos archivos grandes ocupan mucha memoria.

A continuación, como señaló VonC, git clone omite el intento de usar paquetes “delgados” (bueno, normalmente de todos modos). Esto significa que el servidor solo entrega los archivos de paquete que ya tiene. Esta es una operación de “memoria barata”: los archivos ya existen y el servidor solo necesita entregarlos.

Por otro lado, git fetch intenta, si puede, evitar enviar muchos datos que el cliente ya tiene. Usando un protocolo “inteligente”, el cliente y el servidor entablan una especie de conversación, que puede pensar que es algo como esto:

  • “Tengo el objeto A, que necesita B y C; ¿tienes B y C? También tengo D, E y F”.
  • “Tengo B pero necesito C, y tengo D y E; por favor envíeme A, C y F”.

Así informado, el servidor extrae los objetos “interesantes”https://stackoverflow.com/”buscados” de los paquetes originales y luego intenta comprimirlos en un paquete nuevo (pero “delgado”). Esto significa que el servidor invocará git-pack-objects.

Si el servidor tiene poca memoria (donde “bajo” es relativo a la cantidad que git-pack-objects va a necesitar), es probable que invoque el “asesino OOM”. Ya que git-pack-objects requiere mucha memoria, ese proceso es un candidato probable para que el “asesino OOM” mate. A continuación, verá, en el lado de su cliente, un mensaje sobre git-pack-objects muriendo de signal 9 (SIGKILL).

(Por supuesto, es posible que el asesino OOM del servidor elimine otra cosa por completo, como el servidor de la base de datos de errores. :-))

  • Detallado e instructivo, como siempre. +1

    – VoC

    26 de enero de 2014 a las 12:22

avatar de usuario
VonC

Puede depender del protocolo, pero Documentation/technical/pack-heuristics.txt señala una primera diferencia entre clonar y fetch.

En la otra dirección, busca, git-fetch-pack y git-clone-pack invoca git-upload-pack en el otro extremo (a través de ssh o hablando con el daemon).

Hay dos casos:

  • clone-pack y fetch-pack con -k mantendrá el archivo del paquete descargado sin expandirse, por lo que no usamos la transferencia de paquetes delgados.
  • De lo contrario, el paquete generado tendrá delta sin objeto base en el mismo paquete.

Pero fetch-pack sin -k explotará el paquete recibido en objetos individuales, por lo que automáticamente preguntamos upload-pack para danos un paquete delgado si upload-pack lo apoya

Entonces, en términos de protocolos, Documentation/technical/pack-protocol.txt ilustra que una búsqueda puede devolver mucho más datos que un clon de git.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad