¿Qué es el git "mecanismo alternativo"?

Estoy estudiando a través del man gitglossary , y este término me ha eludido, porque no está definido en absoluto en el glosario.

Se lo menciona solo dos veces (se han agregado asteriscos):

  alternate object database Via the **alternates mechanism**, a repository can inherit part of its object database from another object database, which is called "alternate". repository A collection of refs together with an object database containing all objects which are reachable from the refs, possibly accompanied by meta data from one or more porcelains. A repository can share an object database with other repositories via **alternates mechanism**. 

Realmente dos preguntas al respecto:

  1. ¿Cuál es el "mecanismo alternativo" al que se hace reference aquí?
  2. ¿Dónde está la documentation oficial que lo define?

La respuesta corta es que puede apuntar cualquier repository git existente a cualquier cantidad de repositorys git existentes, específicamente a sus directorys .git/objects , después de lo cual su git searchá objects en su propio directory .git/objects y todos los otros listdos (en order de listdo).

Lo más difícil de describir es por qué es posible que desee hacer esto.

Ayuda si sabes cómo funciona git internamente. En git, los identificadores tienden a resolverse con bastante rapidez a su ID hash:

 $ git rev-parse master 3266f25e27f69edbfc513a3b3cfd3987a89beff2 

Git luego busca el object correspondiente a esta ID. En este caso, el object es un compromiso. Si su objective es hacer algo con la confirmación, como verificarlo, o diferirlo contra algún otro commit-git lee el object, que contiene la ID de un tree. Git luego lee el object del tree; esto contiene los nombres de treees y files adicionales ("blobs") y sus ID, y git lee esos objects para encontrar los files y, recursivamente, los subtreees y sus files.

Supongamos ahora que tiene una copy existente de un repository muy grande y, por cualquier razón, desea volver a clonarla (quizás para tener una copy separada para trabajar en una twig separada). 1 En lugar de hacer una segunda copy completa del repository original, puede decirle a git que todos los objects originales están disponibles en el primer repository. Una vez que git tenga la input alternativa, podrá encontrar esos objects y no tendrá que downloadlos.

Los nuevos objects que crees en este segundo clon irán, por supuesto, al segundo clon; pero esto ahorra mucho time y espacio.

(Por lo general, los clones "Compartidos" en una sola máquina se vinculan directamente con los objects del otro clon, utilizando enlaces duros al estilo Unix, pero si esto no es posible, el mecanismo alternativo proporciona otra manera de hacer lo mismo. El peligro con las alternativas es que si se elimina el primer clon, los objects desaparecen, los enlaces duros no tienen este defecto. Un clon de --reference también usa el mecanismo alternativo.

Como para:

¿Dónde está la documentation oficial que lo define?

la mejor respuesta es probablemente "en la fuente". 🙂


1 Ahora que git tiene la capacidad de proporcionar treees de trabajo múltiples a partir de un único clon, esto es less importante de lo que era antes.

Con respecto a git en sí, la primera mención de una "location de database de objects alternativa" se realizó en commit ace1534 (mayo de 2005, git v0.99)

Introduzca SHA1_FILE_DIRECTORIES para admitir bases de datos de objects múltiples.

SHA1_FILE_DIRECTORIES variable de entorno SHA1_FILE_DIRECTORIES es una SHA1_FILE_DIRECTORIES separada por dos puntos utilizada al search files SHA1 que no se encuentran en el lugar habitual de lectura. La creación de un nuevo file SHA1 no utiliza este mecanismo alternativo de location de database de objects. Esto es útil para archivar objects antiguos y poco utilizados en directorys separados.

Ese fue un primer ejemplo, rápidamente eliminado de git (en septiembre de 2005, commit a9ab586 )

La struct database de object alternativa se introdujo formalmente en la confirmación 9a217f2 (junio de 2005, v0.99) en cache.h#L236-L239 .

Hoy ( más reciente cache.h ), esa struct aún está allí, pero esta vez con un mecanismo de encadenamiento , presentado en agosto de 2005, v0.99.5, commit d5a63b9 .

 extern struct alternate_object_database { struct alternate_object_database *next; char *name; char base[FLEX_ARRAY]; /* more */ } *alt_odb_list; 

Prepare el logging de database de objects alternativos.

La variable alt_odb_list apunta a la list de struct alternate_object_database .

Los elementos en esta list provienen de elementos no vacíos de la variable de entorno ALTERNATE_DB_ENVIRONMENT separada por dos puntos y GIT_OBJECT_DIRECTORY/info/alternates , cuyo contenido está exactamente en el mismo formatting que esa variable de entorno .

Su base apunta a un buffer estáticamente asignado que contiene " /the/directory/corresponding/to/.git/objects/... ", mientras que su nombre apunta justo después de la barra al final de " .git/objects/ " en el ejemplo anterior, y tiene espacio suficiente para contener SHA1 hexadecimal de 40 bytes, una barra adicional para la indirección de primer nivel y NUL de terminación.

Esa es probablemente la definición más cercana del "mecanismo alternativo" que puede encontrar en las fonts de git.


Puede ver un ejemplo de una implementación de database alternativa en libgit2 ( Libgit2 es una implementación de Git escrita en C puro)

Solo hay dos estructuras principales en el corazón de un repository de Git, en el que todo se basa: existe la database de objects y existe la database de ref .

La database de objects es donde se almacenan todos los datos . El contenido de todos los files, las estructuras de los directorys, las confirmaciones, todo, va en la database de objects. Sin embargo, lo notable de la database de objects es que básicamente no es más que un almacén de valores-key .

Git almacena datos en la database de objects utilizando una recuperación basada en hash, lo que significa que las keys de la tienda son los valores hash (SHA1) de los valores.
Eso tiene algunas implicaciones adicionales interesantes: los valores en la database de objects son esencialmente inmutables y no necesita una operación de actualización .

http://blog.deveo.com/content/images/2014/10/git_object_database.png

en lugar de almacenar la database de objects y la database ref de la forma en que lo hace Git, en files planos, puede proporcionar su propia implementación de back-end y hacer lo que quiera.

Git tradicionalmente apoya:

  • odb_loose implementa el backend de formatting de file suelto. Accede a cada object en un file separado dentro del directory de objects, con el nombre de cada file correspondiente al hash SHA1 de su contenido.
  • odb_pack implementa el backend packfile. Accede a los objects en los files packet de Git, que es un formatting de file utilizado tanto para el almacenamiento eficiente de objects como para transferir los objects al empujar o tirar.

(ver también " ¿Está estandarizado el algorithm bit diff de git (almacenamiento delta)? ")