¿Cómo recupera Git todos los files de una sucursal?

Actualmente estoy aprendiendo sobre Git y tengo un problema para entender cómo Git recupera files de una sucursal cuando lo comtestings.

Por lo que entiendo, la twig es solo un puntero a una confirmación. Así que creí que cuando compras una sucursal, realiza un seguimiento de todas las confirmaciones de padres a padres a partir de la confirmación en la que se encuentra el puntero. Pero no entiendo cómo elige un padre para un compromiso que tiene múltiples padres, como en una combinación.

Por ejemplo:

enter image description here

Asumiendo que quiero ver master , ¿cómo sabe Git que en el punto C5 debería ir para C4 y no para C8 ? ¿O lo he entendido mal?

Cuando compras una sucursal, ¿cómo sabe Git qué files poner en tu tree de trabajo?

Git es diferente de la mayoría de los otros sistemas de control de versiones (VCS).

La mayoría de los VCS-es almacenan "deltas" de varias forms. Por ejemplo, si la confirmación máxima en todo el repository es C9 según lo identificado por el master y la extrae, puede get todos los files en el repository tal como está, mientras que si extrae C5 (confirmación previa de C9 ), ' Comenzaré con todos los files más recientes, y luego C5 dice "deshacer esto, deshacer eso, deshacer lo demás" y el sistema de control de versiones los deshace, y eso le proporciona el estado a partir de la confirmación C5 .

Nuevamente, git no hace esto.

En cambio, el repository de git almacena lo que git llama "objects". Hay cuatro types de objects: "confirmaciones", "tags anotadas", "treees" y "blobs". Ignoraremos las tags anotadas (no son necesarias para este propósito) y solo consideraremos las otras tres.

Cada object tiene un nombre único de 160 bits que se representa como un hash SHA-1. El valor del hash se construye al calcular el SHA-1 de los contenidos del object (más su tipo). Git supone que no habrá dos objects diferentes en el repository que calculen el mismo SHA-1 (si lo hacen, git explota desorderadamente, pero esto nunca ha sucedido). (Pero tenga en count que el mismo object, por ejemplo, el mismo file foo.c en muchos commits, tiene un único SHA-1 único).

Un object de confirmación se ve así:

 $ git cat-file -p 5f95c9f850b19b368c43ae399cc831b17a26a5ac tree 972825cf23ba10bc49e81289f628e06ad44044ff parent 9c8ce7397bac108f83d77dfd96786edb28937511 author Junio C Hamano <gitster@pobox.com> 1392406504 -0800 committer Junio C Hamano <gitster@pobox.com> 1392406504 -0800 Git 1.9.0 Signed-off-by: Junio C Hamano <gitster@pobox.com> 

Es decir, tiene un tree , una list de parent , un author y date, un committer y date, y un post de text. Eso es todo lo que tiene, también. Cada parent es el SHA-1 de los commit (s) padre (s); una confirmación raíz no tiene padres, y una combinación tiene varios padres, pero la mayoría solo tiene un padre, que es lo que le da las flechas en el diagtwig que publicó.

Un object de tree se ve así:

 $ git cat-file -p 972825cf23ba10bc49e81289f628e06ad44044ff 100644 blob 5e98806c6cc246acef5f539ae191710a0c06ad3f .gitattributes 100644 blob b5f9defed37c43b2c6075d7065c8cbae2b1797e1 .gitignore 100644 blob 11057cbcdf4c9f814189bdbf0a17980825da194c .mailmap 100644 blob 536e55524db72bd2acf175208aef4f3dfc148d42 COPYING 040000 tree 47fca99809b19aeac94aed024d64e6e6d759207d Documentation 100755 blob 2b97352dd3b113b46bbd53248315ab91f0a9356b GIT-VERSION-GEN [snip lots more] 

El tree le proporciona el directory de nivel superior que acompaña a dicha confirmación. La mayoría de las inputs de tree son blob ; subdirectorys son más tree s. El mode de un blob le da el bit ejecutable (estos se parecen a los modos de file Unix pero git realmente usa solo el bit ejecutable, de modo que el modo siempre es 100644 o 100755 ). Hay algunos modos más para casos especiales (por ejemplo, enlaces simbólicos) pero podemos ignorarlos por el momento. En cualquier caso, cada input tiene otro SHA-1 único, que es cómo git encuentra el siguiente elemento (subtree o blob).

Cada object blob contiene el file real. Por ejemplo, el blob para GIT-VERSION-GEN es el script del generador de versiones de git:

 $ git cat-file -p 2b97352dd3b113b46bbd53248315ab91f0a9356b #!/bin/sh GVF=GIT-VERSION-FILE DEF_VER=v1.9.0 [snip] 

Entonces, para extraer una confirmación, git solo necesita:

  1. traducir un nombre simbólico como HEAD o master al SHA-1 de la confirmación
  2. extraer el object commit para encontrar el tree de nivel superior
  3. extraer el object de tree de nivel superior para encontrar todos los files y subtreees
  4. para cada file, extrae el object de file; y para cada subtree, extraer recursivamente ese tree y sus objects.

(Los objects Git se almacenan comprimidos, y luego se comprimen aún más en "files de package" que usan deltas, pero de una manera muy diferente a otros VCS-es. No hay necesidad de comprimir delta un file foo.c con una versión anterior de foo.c ; git puede comprimir delta treees entre sí, por ejemplo, o algún código C contra alguna documentation. El formatting exacto del file de package también ha sufrido varias revisiones: si alguna versión futura tiene una forma aún mejor de comprimir cosas Por ejemplo, el formatting del package se puede actualizar de la versión 4 a la versión 5. En cualquier caso, los objects "sueltos" solo se comprimen en zlib en lugar de comprimirse en delta. Esto hace que accedan y actualicen con bastante rapidez. elementos más estáticos, files que no se han modificado y transmisión en networking. Se crean durante git gc , y también en operaciones de inserción y recuperación [que utilizan una variante llamada package "delgado", cuando es posible].)

Para get más de los commands de "plomería" de git que le permiten leer y escribir objects individuales, consulte el libro de Pro Git ( recordatorio de la respuesta de gatkin ).

Git almacena una instantánea completa de todos los files rastreados en cada confirmación, no solo una diferencia. Además de la ID de confirmación principal, C9 (y cada confirmación) tiene una identificación de tree. Puedes ver esto con

 git log --pretty=format:%T HEAD -1 

Ese command imprime el hash SHA1 del tree, y si luego haces git show en ese hash obtendrás una list de la carpeta superior en tu proyecto, que es el inicio del tree. Internamente, el object de tree tiene pointers a otros objects para los files y otros treees para subcarpetas.

Ver el capítulo 9 de Pro Git para más detalles.

Git es diferente a la mayoría de los otros sistemas de control de versiones. No depende de diferencias entre revisiones para volver a crear los files en su repository. A diferencia de la subversión, por ejemplo, que normalmente necesita visitar las confirmaciones principales y sus diferencias asociadas para volver a crear un file, no es necesario que git lo haga.

En otras palabras, en cualquier momento, todas las necesidades de git es el acceso a una confirmación para poder volver a crear todo el repository.

Por lo tanto, no importa si un compromiso tiene uno o más padres.