Ich kann spekulieren, dass Git die meiste Zeit atomar verwendet Dateiaktualisierungen, die wie folgt durchgeführt werden:
- Der Inhalt einer Datei wird in den Speicher eingelesen (und modifiziert).
- Der geänderte Inhalt wird in eine separate Datei geschrieben (normalerweise im selben Verzeichnis wie die Originaldatei und mit zufälliger (
mktemp
-Stil) Name. - 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, weilpackfile.c
verwendetmmap
für Dateizugriff undinotify
meldet keine Änderungen fürmmap
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.