GNU/Linux >> Linux Esercitazione >  >> Linux

Eventi inotify mancanti (nella directory .git)

Posso ipotizzare che Git la maggior parte delle volte usi atomic aggiornamenti dei file che vengono eseguiti in questo modo:

  1. Il contenuto di un file viene letto in memoria (e modificato).
  2. Il contenuto modificato viene scritto in un file separato (di solito situato nella stessa directory di quello originale e con un numero casuale (mktemp -style) nome.
  3. Il nuovo file è quindi rename(2) d -d su quello originale; questa operazione garantisce che ogni osservatore che tenta di aprire il file usando il suo nome ottenga o il vecchio contenuto o quello nuovo.

Tali aggiornamenti sono visti da inotify(7) come moved_to events, poiché un file "riappare" in una directory.


Per rispondere alla tua domanda separatamente per git 2.24.1 su Linux 4.19.95:

  • Perché questi eventi mancano su questi file?

Non vedi IN_MODIFY /IN_CLOSE_WRITE eventi perché git clone cercherà sempre di utilizzare gli hard link per i file sotto .git/objects directory. Durante la clonazione sulla rete o oltre i limiti del file system, questi eventi verranno visualizzati di nuovo.

  • Cosa si può fare al riguardo? Nello specifico, come posso rispondere al completamento delle scritture su questi file? Nota:idealmente vorrei rispondere quando la scrittura è "finita" per evitare di caricare inutilmente/(erroneamente) testi "non finiti".

Per rilevare la modifica degli hard link devi impostare un gestore per inotify CREATE evento che segue e tiene traccia di tali collegamenti. Tieni presente che un semplice CREATE può anche significare che è stato creato un file non vuoto. Quindi, su IN_MODIFY /IN_CLOSE_WRITE a uno qualsiasi dei file devi attivare la stessa azione anche su tutti i file collegati. Ovviamente devi anche rimuovere quella relazione sul DELETE evento.

Un approccio più semplice e robusto sarebbe probabilmente quello di eseguire periodicamente l'hashing di tutti i file e controllare se il contenuto di un file è cambiato.

Correzione

Dopo aver controllato il git codice sorgente da vicino ed eseguendo git con strace , ho trovato che git usa i file mappati in memoria, ma principalmente per leggere i contenuti. Vedi l'uso di xmmap che viene sempre chiamato con PROT_READ solo .. Pertanto la mia risposta precedente di seguito è NON la risposta corretta. Tuttavia, a scopo informativo, vorrei comunque tenerlo qui:

  • Non vedi IN_MODIFY eventi perché packfile.c utilizza mmap per l'accesso ai file e inotify non riporta modifiche per mmap ed.

    Dalla manpage di inotify:

    L'API inotify non segnala gli accessi ai file e le modifiche che possono verificarsi a causa di mmap(2), msync(2) e munmap(2).


Sulla base di questa risposta accettata, presumo che potrebbero esserci delle differenze negli eventi in base al protocollo utilizzato (ad esempio ssh o https).

Osservi lo stesso comportamento durante il monitoraggio della clonazione dal filesystem locale con --no-hardlinks opzione?

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

Il tuo comportamento osservato durante l'esecuzione dell'esperimento sia su un host Linux che Mac probabilmente elimina questo problema aperto essendo la causa https://github.com/docker/for-mac/issues/896 ma aggiungendo solo incase.


Linux
  1. Differenza nel calcolo della dimensione della directory?

  2. Ottieni il file più recente in una directory su Linux

  3. Mantenimento delle autorizzazioni sui file con Git

  4. mkdir -p fallisce quando la directory esiste

  5. git clone senza cartella del progetto

Procedura:un'introduzione all'uso di Git

Cheat sheet per le autorizzazioni di file/directory Linux

Rimuove un collegamento simbolico a una directory

Trova il file quindi cd in quella directory in Linux

Esclusione della directory durante la creazione di un file .tar.gz

Volume di file singolo montato come directory in Docker