GNU/Linux >> Tutoriales Linux >  >> Linux

Faltan eventos de inotify (en el directorio .git)

Puedo especular que Git la mayor parte del tiempo usa atomic actualizaciones de archivos que se hacen así:

  1. El contenido de un archivo se lee en la memoria (y se modifica).
  2. El contenido modificado se escribe en un archivo separado (generalmente ubicado en el mismo directorio que el original, y tiene un formato aleatorio (mktemp -estilo) nombre.
  3. El nuevo archivo es entonces rename(2) d -d sobre el original; esta operación garantiza que cada observador que intente abrir el archivo usando su nombre obtendrá el contenido antiguo o el nuevo.

Tales actualizaciones son vistas por inotify(7) como moved_to eventos, ya que un archivo "reaparece" en un directorio.


Para responder a su pregunta por separado para git 2.24.1 en Linux 4.19.95:

  • ¿Por qué faltan estos eventos en estos archivos?

No ves IN_MODIFY /IN_CLOSE_WRITE eventos porque git clone siempre intentará usar enlaces duros para archivos bajo el .git/objects directorio. Al clonar a través de la red o a través de los límites del sistema de archivos, estos eventos volverán a aparecer.

  • ¿Qué se puede hacer al respecto? Específicamente, ¿cómo puedo responder a la finalización de escrituras en estos archivos? Nota:idealmente, me gustaría responder cuando la escritura esté "terminada" para evitar cargar innecesariamente/(incorrectamente) la escritura "sin terminar".

Para detectar la modificación de enlaces duros, debe configurar un controlador para inotify CREATE evento que sigue y realiza un seguimiento de esos enlaces. Tenga en cuenta que un simple CREATE también puede significar que se creó un archivo no vacío. Luego, en IN_MODIFY /IN_CLOSE_WRITE a cualquiera de los archivos, también debe activar la misma acción en todos los archivos vinculados. Obviamente, también debe eliminar esa relación en el DELETE evento.

Probablemente, un enfoque más simple y más sólido sería hacer un hash periódico de todos los archivos y comprobar si el contenido de un archivo ha cambiado.

Corrección

Después de comprobar el git código fuente de cerca y ejecutando git con strace , encontré que git utiliza archivos mapeados en memoria, pero principalmente para leer contenido. Ver el uso de xmmap que siempre se llama con PROT_READ solo... Por lo tanto, mi respuesta anterior a continuación es NO La respuesta correcta. Sin embargo, con fines informativos, me gustaría mantenerlo aquí:

  • No ves IN_MODIFY eventos porque packfile.c usa mmap para acceso a archivos y inotify no informa modificaciones para mmap archivos editados.

    Desde la página de manual de inotify:

    La API de inotify no informa sobre los accesos a archivos y las modificaciones que pueden ocurrir debido a mmap(2), msync(2) y munmap(2).


Según esta respuesta aceptada, supongo que podría haber alguna diferencia en los eventos según el protocolo que se utiliza (es decir, ssh o https).

¿Observa el mismo comportamiento al monitorear la clonación desde el sistema de archivos local con el --no-hardlinks opción?

$ git clone [email protected]:user/repo.git
# set up watcher for new dir
$ git clone --no-hardlinks repo new-repo

Su comportamiento observado al ejecutar el experimento en un host Linux y Mac probablemente elimine este problema abierto siendo la causa https://github.com/docker/for-mac/issues/896 pero agregando solo por si acaso.


Linux
  1. ¿Diferencia de cálculo de tamaño de directorio?

  2. Hoja de referencia de permisos de archivos/directorios de Linux

  3. Retención de permisos de archivo con Git

  4. Volumen de archivo único montado como directorio en Docker

  5. sys/types.h:No existe tal archivo o directorio

Administrador de archivos Java

¿Usando Inotify para monitorear el acceso a un archivo?

Linux – ¿Propósito del directorio /net?

¿Eficiencia de muchos relojes Inotify o llamadas de estado?

Cómo:una introducción al uso de Git

touch:no se puede tocar `foo':No existe tal archivo o directorio