2009-11-22 20 views
49

¿Cómo detecta git una modificación de archivo tan rápido?¿Cómo detecta git que un archivo ha sido modificado?

¿Hash todos los archivos del repositorio y compara los SHA1? Esto tomaría mucho tiempo, ¿no?

O ¿se puede comparar atime, ctime o mtime?

+0

Puede ser diferente para diferentes plataformas. Estoy particularmente interesado en cómo lo hace Git/Windows – Pacerier

Respuesta

3

Bueno, me atrevería a adivinar que está usando una combinación de llamadas stat() para averiguar qué parece haber cambiado, y luego, a su vez, asegurarse de usar este motor diferido que este es el caso.

Puede ver el código del motor diff here para tener una idea. Recorrí la base de código para asegurarme de que el comando de estado efectivamente incluye este código (¡parece que muchas cosas sí!) Y en realidad todo esto tiene mucho sentido cuando se sabe que Git funciona bastante mal en Windows, donde está utilizando una capa de emulación para realizar estas llamadas de tipo POSIX: es un orden de magnitud más lento hacer un git status en esa plataforma.

De todos modos, antes de leer todo el código de arriba a abajo (que puedo ver más adelante si tengo tiempo!) Eso es todo lo que puedo tomar por ahora ... tal vez alguien puede ser más definitivo si han trabajado con la base de código

Nota: otra aceleración posible proviene del uso juicioso de las funciones inline donde claramente tiene sentido, puede ver esto claramente en los encabezados.

[editar: here ver una explicación de stat()]

+0

para explicar qué 'stat()' es/does? – hasen

+0

@hansen j: actualizado con una referencia a la página de comando man stat(). – jkp

6

Hay una comprobación inicial -mtime de informes como "git status", pero cuando la final se calcula cometen, mtimes no importan ... es el SHA1 que importa.

+1

@Randal: No creo que esto sea cierto, siempre hace un diff: http://gist.github.com/240775. Si solo se utilizara mtime para 'git status', verías modificaciones en el pegado que hice. – jkp

+2

@jkp Mi propia experiencia muestra que los archivos de árbol de trabajo sin cambios solo tienen 'lstat' hecho para ellos. – Tobu

2

Según la plataforma, debería ser capaz de averiguar qué syscalls utiliza Git para determinar su estado. Trate strace git status en Linux, truss git status en SunOS, o la herramienta aparentemente basadas en DTrace que los buques de Apple con sus herramientas de desarrollo en Mac OS X.

28

Git se esfuerza para conseguir convencidos de la lstat() Valor solo que el worktree coincide con el índice, porque retroceder en el contenido del archivo es muy caro.

Documentation/technical/racy-git.txt describe qué campos de estadísticas se utilizan y cómo se evitan algunas condiciones de carrera debido a la baja granularidad mtime. This article has some more detail.

los valores de las estadísticas no son a prueba de manipulaciones, ver futámenes (3). Git puede ser engañado al perder un cambio en un archivo; eso no compromete la integridad del hash de contenido.

+1

¿Pero cada confirmación recae en el contenido del archivo? ¿O está adivinando incluso en commit? – Pacerier

Cuestiones relacionadas