¿Cuál es el mecanismo de almacenamiento detrás de Git Large File Storage?

6 minutos de lectura

avatar de usuario
Tarun Chabarval

Github introdujo recientemente un extensión a git para almacenar archivos grandes de una manera diferente. ¿Qué quieren decir exactamente con extensión reemplaza archivos grandes con punteros de texto dentro de Git ?

  • El enlace que cita lo explica bastante a fondo. ¿Qué parte no entiendes?

    – Andrés C.

    9 de abril de 2015 a las 5:22

  • @AndrewC Texto en negrita cursiva. Diferencia entre punteros de texto y datos binarios de archivo.

    – Tarun Chabarval

    9 de abril de 2015 a las 5:41

  • Es solo la diferencia entre tener c:\very_large_video.wmv consumiendo 5 Gb en su disco duro versus almacenar la cadena url/a/video_muy_grande.wmv y tenerlo guardado en otro lugar

    – Andrés C.

    9 de abril de 2015 a las 6:08

  • ¿Quiere decir que los datos del archivo no estarán en control de fuente?

    – Tarun Chabarval

    9 de abril de 2015 a las 6:21

  • while storing the file contents on a remote server like GitHub.com

    – Andrés C.

    9 de abril de 2015 a las 6:24

avatar de usuario
VonC

Puedes ver en el fuentes de git-lfs Como un “puntero de texto” está definido:

type Pointer struct {
    Version string
    Oid     string
    Size    int64
    OidType string
} 

los mancha y limpio fuentes significa git-lfs puede usar un controlador de filtro de contenido con el fin de:

  • descargue los archivos reales al finalizar la compra
  • almacenarlos en su fuente externa en la confirmación.

Ver las especificaciones del puntero:

La idea central de Git LFS es que en lugar de escribir grandes blobs en un repositorio de Git, solo se escribe un archivo de puntero.

version https://git-lfs.github.com/spec/v1
oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
size 12345
(ending \n)

Git LFS necesita un punto final de URL para comunicarse con un servidor remoto.
Un repositorio de Git puede tener diferentes puntos finales de Git LFS para diferentes controles remotos.

El archivo real se carga o se descarga de un servidor que respeta las API Git-LFS.

Esto es confirmado por el git-lfs página manque menciona:

El archivo real se envía a un API Git LFS

Necesita un servidor Git que implemente esa API para admitir la carga y descarga de contenido binario.


Con respecto al controlador de filtro de contenido (que existe en Git desde hace mucho tiempo, mucho antes de lfs, y lfs lo usa aquí para agregar esta función de “administración de archivos grandes”), aquí es donde ocurre la mayor parte del trabajo:

los filtro de manchas se ejecuta a medida que los archivos se extraen del repositorio de Git al directorio de trabajo.
Git envía el contenido del blob de Git como STDIN y espera que el contenido se escriba en el directorio de trabajo como STDOUT.

Leer 100 bytes.

  • Si el contenido es ASCII y coincide con el formato del archivo de puntero:
    Busque el archivo en .git/lfs/objects/{OID}.

  • Si no está allí, descárguelo del servidor.
    Leer su contenido en STDOUT

  • De lo contrario, simplemente pase STDIN a través de STDOUT.

los filtro limpio se ejecuta a medida que se agregan archivos a los repositorios.
Git envía el contenido del archivo que se agrega como STDIN y espera que el contenido se escriba en Git como STDOUT.

  • Transmita contenido binario desde STDIN a un archivo temporal, mientras calcula su firma SHA-256.
  • Busque el archivo en .git/lfs/objects/{OID}.
  • Si no existe:
    • Ponga en cola el OID que se va a cargar.
    • Mover el archivo temporal a .git/lfs/objects/{OID}.
  • Elimine el archivo temporal.
  • Escriba el archivo de puntero en STDOUT.

Git 2.11 (noviembre de 2016) tiene un compromiso que detalla aún más cómo funciona esto: cometer edcc858ayudado por Martin-Louis Bright y firmado por: Lars Schneider.

convert: agregar filter.<driver>.process opción

El mecanismo de limpieza/difuminación de Git invoca un proceso de filtro externo para cada blob que se ve afectado por un filtro. Si Git filtra muchos blobs, el tiempo de inicio de los procesos de filtrado externo puede convertirse en una parte importante del tiempo de ejecución general de Git.

En una prueba de rendimiento preliminar, este desarrollador usó un filtro de limpieza/difuminado escrito en golang para filtrar 12 000 archivos. Este proceso tomó 364s con el mecanismo de filtro existente y 5s con el nuevo mecanismo. Ver detalles aquí: git-lfs/git-lfs#1382

Este parche agrega la filter.<driver>.process opción de cadena que, si se usa, mantiene el proceso de filtro externo en ejecución y procesa todos los blobs con el formato de paquete (pkt-line) protocolo basado en entrada estándar y salida estándar.
El protocolo completo se explica en detalle en Documentation/gitattributes.txt.

Algunas decisiones clave:

  • El proceso de filtro de ejecución prolongada se denomina versión 2 del protocolo de filtro porque la invocación de filtro de disparo único existente se considera la versión 1.
  • Git envía un mensaje de bienvenida y espera una respuesta justo después de que haya comenzado el proceso de filtrado externo. Esto asegura que Git no se cuelgue si un filtro de la versión 1 se usa incorrectamente con el
    filter.<driver>.process opción para filtros versión 2. Además, Git puede detectar este tipo de error y advertir al usuario.
  • El estado de una operación de filtro (por ejemplo, “éxito” o “error) se establece antes de la respuesta real y (si es necesario) se restablece después de la respuesta. La ventaja de esta respuesta de estado de dos pasos es que si el filtro detecta un error temprano, entonces el filtro puede comunicar esto y Git ni siquiera necesita crear estructuras para leer la respuesta.
  • Todas las respuestas de estado son listas de líneas de paquete terminadas con un paquete de descarga. Esto nos permite enviar otros campos de estado con el mismo protocolo en el futuro.

Esto tiene como consecuencia una advertencia establecida en Git 2.12 (Q1 2017)

Ver cometer 7eeda8b (18 de diciembre de 2016), y cometer c6b0831 (03 dic 2016) por Lars Schneider (larsxschneider).
(Combinado por Junio ​​C Hamano — gitster en cometer 08721a027 de diciembre de 2016)

docs: advertir sobre posible ‘=‘ en valores de proceso de filtro limpio/difuminado

Un valor de nombre de ruta en un proceso de filtro de limpieza/difuminación “key=value” par puede contener el ‘=‘ carácter (introducido en edcc858).
Informe al usuario de este problema en los documentos, agregue un caso de prueba correspondiente y solucione el problema en el analizador de valor de proceso de filtro de la implementación de ejemplo en contrib.

  • Para las personas como yo que luchan por comprender las ideas básicas detrás de esta respuesta integral, se ejecuta un comando ‘difuminar’ cuando se extrae el código de un repositorio; y un comando ‘limpio’ se ejecuta en la dirección opuesta, es decir, cuando se confirma el código. Los considero un poco como ganchos que se pueden usar para insertar acciones en el flujo de trabajo de confirmación o pago. Como explica @VonC, git-lfs los usa para almacenar un puntero en lugar de un archivo grande en el paso de confirmación. Encontré el enlace a los controladores de filtro de atributos de git particularmente útil: (schacon.github.io/git/gitattributes.html.

    – Juan

    6 de diciembre de 2020 a las 18:26


  • @Juan Exactamente. Puedes ver un ejemplo de smudge hook aquí: stackoverflow.com/a/64710964/6309. Y limpio: stackoverflow.com/a/30945624/6309

    – VoC

    6 de diciembre de 2020 a las 18:56

¿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