ver tipos tag qué modificados log existen etiquetas crear archivos git

tag - qué tipos de etiquetas existen en git



¿Qué algoritmo usa git para detectar cambios en su árbol de trabajo? (2)

Esto es sobre los git internos de git .

He estado leyendo el gran libro ''Pro Git'' y aprendiendo un poco acerca de cómo funciona git internamente (todo sobre SHA1, blobs, referencias, árboles, confirmaciones, etc.). Arquitectura bastante inteligente, por cierto.

Por lo tanto, para poner en contexto, git hace referencia al contenido de un archivo como un valor SHA1, por lo que es capaz de saber si un contenido específico ha cambiado solo comparando los valores hash. Pero mi pregunta es específicamente acerca de cómo git verifica que el contenido en el árbol de trabajo haya cambiado o no.

El enfoque ingenuo será pensar que, cada vez que ejecute un comando como git status o comando similar, buscará a través de todos los archivos en el directorio de trabajo, calculando el SHA1 y comparándolo con el que tiene el último compromiso. Pero eso parece muy ineficiente para grandes proyectos, como el kernel de Linux.

Otra idea podría ser verificar la fecha de la última modificación en el archivo, pero creo que git no está almacenando esa información (cuando clonas un repositorio, todos los archivos tienen una nueva hora)

Estoy seguro de que lo está haciendo de una manera eficiente (git es muy rápido), ¿alguien sabe cómo se logra eso?

PD: Solo para agregar un link interesante sobre el índice de git, indicando específicamente que el índice mantiene información sobre las marcas de tiempo de los archivos, incluso cuando los objetos del árbol no lo hacen.


El índice de Git mantiene las marcas de tiempo de cuando git escribió por última vez cada archivo en el árbol de trabajo (y las actualiza cada vez que se almacenan en caché los archivos desde el árbol de trabajo o desde una confirmación). Puedes ver los metadatos con git ls-files --debug . Además de la marca de tiempo, registra el tamaño, el inodo y otra información de lstat para reducir la posibilidad de un falso positivo.

Cuando realiza git-status, simplemente llama a lstat en cada archivo en el árbol de trabajo y compara los metadatos para determinar rápidamente qué archivos no se han modificado. Esto se describe en la documentación bajo racy-git y update-index .


En un sistema de archivos Unix, la información del archivo se rastrea y se puede acceder utilizando el método lstat . La lstat contiene múltiples sellos de tiempo, información de tamaño y más:

struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ mode_t st_mode; /* protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device ID (if special file) */ off_t st_size; /* total size, in bytes */ blksize_t st_blksize; /* blocksize for file system I/O */ blkcnt_t st_blocks; /* number of 512B blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last status change */ };

Parece que inicialmente Git simplemente se basó en esta lstat para decidir si un archivo había sido modificado ( ver referencia ):

Al verificar si son diferentes, Git primero ejecuta lstat(2) en los archivos y compara el resultado con esta información

Sin embargo, se informó una condición de carrera ( racy-git ) que encontró si un archivo se modificó de la siguiente manera:

: modify ''foo'' $ git update-index ''foo'' : modify ''foo'' again, in-place, without changing its size (And quickly enough to not change it''s timestamps)

Esto dejó el archivo en un estado que fue modificado pero no detectable por lstat.

Para solucionar este problema, ahora en situaciones en las que el estado del estado es ambiguo, Git compara el contenido de los archivos para determinar si se ha cambiado.

NOTA:

Si alguien está confundido, como yo, con lstat , que indica que se actualiza mediante escrituras "de más de cero bytes", esto significa cambio absoluto .

Por ejemplo, en el caso de un archivo de texto con un solo carácter A : si A se cambia a B hay un cambio neto de 0 en el tamaño total de bytes, pero el st_mtime todavía se actualizará (tuve que probarlo yo mismo para verificar ls -l para ver la marca de tiempo).