GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Fehlende Inotify-Ereignisse (im .git-Verzeichnis)

Ich kann spekulieren, dass Git die meiste Zeit atomar verwendet Dateiaktualisierungen, die wie folgt durchgeführt werden:

  1. Der Inhalt einer Datei wird in den Speicher eingelesen (und modifiziert).
  2. Der geänderte Inhalt wird in eine separate Datei geschrieben (normalerweise im selben Verzeichnis wie die Originaldatei und mit zufälliger (mktemp -Stil) Name.
  3. Die neue Datei ist dann rename(2) d -d über dem Original; diese Operation garantiert, dass jeder Beobachter, der versucht, die Datei unter ihrem Namen zu öffnen, entweder den alten oder den neuen Inhalt erhält.

Solche Aktualisierungen werden von inotify(7) gesehen als moved_to Ereignisse – da eine Datei in einem Verzeichnis „wieder auftaucht“.


Um Ihre Frage separat für git zu beantworten 2.24.1 unter Linux 4.19.95:

  • Warum fehlen diese Ereignisse in diesen Dateien?

IN_MODIFY wird nicht angezeigt /IN_CLOSE_WRITE Ereignisse, weil git clone wird immer versuchen, harte Links für Dateien unter dem .git/objects zu verwenden Verzeichnis. Beim Klonen über das Netzwerk oder über Dateisystemgrenzen hinweg werden diese Ereignisse erneut angezeigt.

  • Was kann man dagegen tun? Wie kann ich insbesondere auf den Abschluss von Schreibvorgängen in diese Dateien reagieren? Hinweis:Idealerweise möchte ich antworten, wenn das Schreiben "fertig" ist, um unnötiges/(fälschliches) Hochladen von "unfertigem" Schreiben zu vermeiden.

Um die Änderung von Hardlinks abzufangen, müssen Sie einen Handler für den inotify CREATE einrichten Ereignis, das diesen Links folgt und diese verfolgt. Bitte beachten Sie, dass ein einfacher CREATE kann auch bedeuten, dass eine nicht leere Datei erstellt wurde. Dann auf IN_MODIFY /IN_CLOSE_WRITE zu einer der Dateien müssen Sie die gleiche Aktion auch für alle verknüpften Dateien auslösen. Natürlich müssen Sie auch diese Beziehung auf DELETE entfernen Veranstaltung.

Ein einfacherer und robusterer Ansatz wäre wahrscheinlich, alle Dateien regelmäßig zu hashen und zu überprüfen, ob sich der Inhalt einer Datei geändert hat.

Korrektur

Nach Überprüfung des git Quellcode genau und läuft git mit strace , habe ich diesen git gefunden verwendet speicherabgebildete Dateien, aber hauptsächlich zum Lesen von Inhalten. Siehe die Verwendung von xmmap die immer mit PROT_READ aufgerufen wird nur .. Daher ist meine vorherige Antwort unten NICHT die richtige Antwort. Trotzdem möchte ich es zu Informationszwecken hier behalten:

  • IN_MODIFY wird nicht angezeigt Ereignisse, weil packfile.c verwendet mmap für Dateizugriff und inotify meldet keine Änderungen für mmap ed-Dateien.

    Von der inotify-Manpage:

    Die Inotify-API meldet keine Dateizugriffe und -änderungen, die aufgrund von mmap(2), msync(2) und munmap(2) auftreten können.


Basierend auf dieser akzeptierten Antwort würde ich annehmen, dass es je nach verwendetem Protokoll (z. B. ssh oder https) einige Unterschiede in den Ereignissen geben könnte.

Beobachten Sie dasselbe Verhalten beim Überwachen des Klonens aus dem lokalen Dateisystem mit dem --no-hardlinks Option?

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

Ihr beobachtetes Verhalten beim Ausführen des Experiments sowohl auf einem Linux- als auch auf einem Mac-Host beseitigt wahrscheinlich dieses offene Problem als Ursache https://github.com/docker/for-mac/issues/896, fügt aber nur für den Fall hinzu.


Linux
  1. Cheat-Sheet für Linux-Datei-/Verzeichnisberechtigungen

  2. Entfernen Sie einen symbolischen Link zu einem Verzeichnis

  3. Holen Sie sich die neueste Datei in einem Verzeichnis unter Linux

  4. Dateiberechtigungen mit Git beibehalten

  5. Ausschließen des Verzeichnisses beim Erstellen einer .tar.gz-Datei

Inotify verwenden, um den Zugriff auf eine Datei zu überwachen?

Linux – Zweck des Verzeichnisses /net?

Gewusst wie:Eine Einführung in die Verwendung von Git

Bash:Keine solche Datei oder Verzeichnis?

sys/types.h:Keine solche Datei oder Verzeichnis

touch:kann `foo' nicht berühren:Keine solche Datei oder Verzeichnis