¿Qué contiene exactamente el índice Git y qué comando puedo usar para ver el contenido del índice?
Actualizar
Gracias por todas sus respuestas. Sé que el índice actúa como un área de ensayo, y lo que está comprometido está en el índice en lugar del árbol de trabajo. Tengo curiosidad por saber en qué consiste un objeto índice. Supongo que podría ser una lista de nombre de archivo / nombre de directorio, pares SHA-1, ¿una especie de árbol virtual tal vez?
¿Existe, en la terminología de Git, algún comando de plomería que pueda usar para enumerar el contenido del índice?
Respuestas:
El libro de Git contiene un artículo sobre lo que incluye un índice :
El problema de Racy git da más detalles sobre esa estructura:
Para ver más, cf. " git / git / Documentation / technical / index-format.txt ":
El archivo de índice de Git tiene el siguiente formato
mljrg comenta :
Debido a que el índice representa lo que se está rastreando , y justo después de una confirmación, lo que se está rastreando es idéntico a la última confirmación (
git diff --cached
no devuelve nada).Entonces,
git ls-files -s
enumera todos los archivos rastreados (nombre del objeto, bits de modo y número de etapa en la salida).Esa lista (de elemento rastreado) se inicializa con el contenido de una confirmación.
Cuando cambia de rama, el contenido del índice se restablece a la confirmación a la que hace referencia la rama a la que acaba de cambiar.
Git 2.20 (Q4 2018) agrega una tabla de compensación de entrada de índice (IEOT) :
Ver commit 77ff112 , commit 3255089 , commit abb4bb8 , commit c780b9c , commit 3b1d9e0 , commit 371ed0d (10 de octubre de 2018) por Ben Peart (
benpeart
) .Ver commit 252d079 (26 de septiembre de 2018) por Nguyễn Thái Ngọc Duy (
pclouds
) .(Fusionada por Junio C Hamano -
gitster
- en commit e27bfaa , 19 oct 2018)Con la nueva configuración de index.threads , la carga del índice ahora es más rápida.
Como resultado ( de usar IEOT ), confirme 7bd9631 limpia la
read-cache.c load_cache_entries_threaded()
función para Git 2.23 (Q3 2019).Ver commit 8373037 , commit d713e88 , commit d92349d , commit 113c29a , commit c95fc72 , commit 7a2a721 , commit c016579 , commit be27fb7 , commit 13a1781 , commit 7bd9631 , commit 3c1dce8 , commit cf7a901 , commit d64db5b , commit 76a7b0 ( Jeff
peff
May 09b ) ( ) .(Fusionada por Junio C Hamano -
gitster
- en commit c0e78f7 , 13 jun 2019)fuente
Análisis bit a bit
He decidido hacer una pequeña prueba para comprender mejor el formato e investigar algunos de los campos con más detalle.
Los resultados a continuación son los mismos para las versiones Git
1.8.5.2
y2.3
.He marcado puntos que no estoy seguro / no he encontrado
TODO
: por favor, siéntase libre de complementar esos puntos.Como otros mencionaron, el índice se almacena en
.git/index
, no como un objeto de árbol estándar, y su formato es binario y está documentado en: https://github.com/git/git/blob/master/Documentation/technical/index-format. TXTLas estructuras principales que definen el índice están en cache.h , porque el índice es un caché para crear confirmaciones.
Preparar
Cuando comenzamos un repositorio de prueba con:
El
.git
directorio se ve así:Y si obtenemos el contenido del único objeto:
Nosotros conseguimos
a
. Esto indica que:index
puntos al contenido del archivo, ya quegit add b
creó un objeto blobanálisis de alta definición
Ahora echemos un vistazo al índice en sí:
Da:
A continuación concluiremos:
Primero viene el encabezado, definido en: struct cache_header :
44 49 52 43
:DIRC
. TODO: ¿por qué es esto necesario?00 00 00 02
: versión de formato: 2. El formato de índice ha evolucionado con el tiempo. Actualmente existe una versión hasta 4. El formato del índice no debería ser un problema al colaborar entre diferentes computadoras en GitHub porque los repositorios desnudos no almacenan el índice: se genera en tiempo de clonación.00 00 00 01
: recuento de archivos en el índice: solo unob
,.Luego comienza una lista de entradas de índice, definida por struct cache_entry Aquí tenemos solo una. Contiene:
un montón de metadatos de archivo: 8 bytes
ctime
, 8 bytesmtime
, luego 4 bytes: dispositivo, inodo, modo, UID y GID.Tenga en cuenta cómo:
ctime
ymtime
son los mismos (54 09 76 e6 1d 81 6f c6
) como se esperaba ya que no hemos modificado el archivoLos primeros bytes son segundos desde EPOCH en hexadecimal:
Da:
Que es cuando hice este ejemplo.
Los segundos 4 bytes son nanosegundos.
UID y GID son
00 00 03 e8
1000 en hexadecimal: un valor común para configuraciones de usuario único.Todos estos metadatos, la mayoría de los cuales no están presentes en los objetos del árbol, le permiten a Git verificar si un archivo ha cambiado rápidamente sin comparar todo el contenido.
al principio de la línea
30
::00 00 00 02
tamaño del archivo: 2 bytes (a
y\n
deecho
)78 98 19 22 ... c1 99 4e 85
: 20 bytes SHA-1 sobre el contenido anterior de la entrada. Tenga en cuenta que de acuerdo con mis experimentos con el indicador de asumir válido , los indicadores que lo siguen no se consideran en este SHA-1.Banderas de 2 bytes:
00 01
1 bit: asume un indicador válido. Mis investigaciones indican que esta bandera mal nombrada es donde
git update-index --assume-unchanged
almacena su estado: https://stackoverflow.com/a/28657085/895245Bandera extendida de 1 bit. Determina si las banderas extendidas están presentes o no. Debe estar
0
en la versión 2 que no tiene banderas extendidas.Indicador de etapa de 2 bits utilizado durante la fusión. Las etapas están documentadas en
man git-merge
:0
: archivo normal, no en un conflicto de fusión1
: base2
: el nuestro3
: de ellosDurante un conflicto de fusión, todas las etapas de 1-3 se almacenan en el índice para permitir operaciones como
git checkout --ours
.Si es así
git add
, se agrega una etapa 0 al índice de la ruta, y Git sabrá que el conflicto se ha marcado como resuelto. TODO: mira esto.Longitud de 12 bits de la ruta que seguirá
0 01
: 1 byte solo desde que la ruta fueb
Banderas extendidas de 2 bytes. Solo tiene sentido si el "indicador extendido" se estableció en los indicadores básicos. QUE HACER.
62
(ASCIIb
): ruta de longitud variable. Longitud determinada en los pabellones anteriores, aquí sólo 1 byte,b
.Luego viene un
00
: 1-8 bytes de relleno cero para que la ruta sea terminada en nulo y el índice termine en un múltiplo de 8 bytes. Esto solo ocurre antes de la versión de índice 4.No se utilizaron extensiones. Git lo sabe porque no quedaría suficiente espacio en el archivo para la suma de comprobación.
Finalmente, hay una suma de verificación de 20 bytes
ee 33 c0 3a .. 09 ab 49 94
sobre el contenido del índice.fuente
git add
, por suTODO
: tiene razón. Si tiene entradas de índice de etapa alta (un conflicto) en una ruta determinada, cuando usegit add
esa ruta, todas las entradas de índice de etapa alta se eliminarán y la copia del directorio de trabajo se agregará en la etapa0
. (Resolviendo el conflicto).El índice Git es un área de ensayo entre su directorio de trabajo y su repositorio. Puede usar el índice para crear un conjunto de cambios que desea confirmar juntos. Cuando crea una confirmación, lo que se confirma es lo que está actualmente en este índice, no lo que está en su directorio de trabajo.
Para ver qué hay dentro del índice, emita el comando:
Cuando ejecuta el estado de git, puede ver qué archivos están almacenados (actualmente en su índice), cuáles están modificados pero aún no almacenados, y cuáles están completamente sin seguimiento.
Puedes leer esto . Una búsqueda en Google arroja muchos enlaces, que deberían ser bastante autosuficientes.
fuente
git status
no enumera todos los archivos del índice. Solo enumera aquellos archivos que difieren entre el índice y el directorio de trabajo. Para ver todos los archivos en el índice, debe usargit ls-files
.git status
lo hace en los archivos de índice de la lista de hecho, con independencia de que difieren entre el índice y workdir.git status
enumera los archivos que están en el índice, sí, pero no enumera todos los archivos en el índice. Explicar cómo funcionagit status
realmente sería una respuesta beneficiosa a alguna pregunta, aunque probablemente no esta.git status
muestra el estado del árbol de trabajo (diferencia entre el árbol de trabajo y el índice). En realidad no muestra el índice. git-scm.com/docs/git-statusEsto es exactamente lo que necesita, use este comando.
$ binwalk index
fuente
El índice Git es un archivo binario (generalmente guardado
.git/index
) que contiene una lista ordenada de nombres de ruta, cada uno con permisos y el SHA1 de un objeto blob;git ls-files
puede mostrarle el contenido del índice. Tenga en cuenta que las palabrasindex
,stage
ycache
son lo mismo en Git: se usan indistintamente.El índice Git, o caché Git, tiene 3 propiedades importantes:
Fuente :
fuente