2009-11-22 14 views
49

In che modo Git rileva una modifica del file così veloce?In che modo git rileva che un file è stato modificato?

Ha hash ogni file nel repository e confronta SHA1s? Questo richiederebbe molto tempo, no?

O confronta atime, ctime o mtime?

+0

Potrebbe essere diverso per piattaforme diverse. Sono particolarmente interessato a come Git/Windows fa – Pacerier

risposta

3

Beh, azzarderei un'ipotesi che stia usando una combinazione di chiamate stat() per capire che aspetto potrebbe essere cambiato, quindi a sua volta legarsi effettivamente per accertare usando il suo motore diff'ing che questo è il caso.

È possibile visualizzare il codice per il motore diff here per avere un'idea. Ho rintracciato la base di codice per essere sicuro che il comando di stato richiama effettivamente questo codice (sembra un sacco di cose!) E in realtà tutto questo ha molto senso quando sai che Git si comporta abbastanza male su Windows dove sta usando un livello di emulazione per eseguire queste chiamate di tipo POSIX: è un ordine di grandezza più lento a fare un git status su quella piattaforma.

Ad ogni modo, a meno di leggere tutto il codice da cima a fondo (che posso più tardi se ho tempo!) Questo è il massimo che posso portarti per ora ... forse qualcuno può essere più definitivo se hanno lavorato con il codice base.

Nota: un'altra possibile accelerazione deriva dall'uso giudizioso delle funzioni inline in cui ha chiaramente un senso, è possibile vederlo chiaramente nelle intestazioni.

[edit: vedi here per una spiegazione di stat()]

+0

cura di spiegare cosa 'stat()' è/fa? – hasen

+0

@hansen j: aggiornato con un riferimento alla pagina man di stat(). – jkp

6

C'è un controllo mtime iniziale per i rapporti come "git status", ma quando la finale commit viene calcolata, date di modifica non contano ... è il SHA1 che conta.

+1

@Randal: Non penso che sia vero, fa sempre una diff: http://gist.github.com/240775. Se fosse stato usato solo mtime per 'git status', vedresti delle modifiche nella pasta che ho fatto. – jkp

+2

@jkp Il mio proprio strace-ing mostra che i file di worktree non modificati hanno solo 'lstat' fatto per loro. – Tobu

2

A seconda della piattaforma, dovresti essere in grado di scoprire quali syscalls utilizza Git per capire il suo stato. Prova strace git status su Linux, truss git status su SunOS o lo strumento apparentemente basato su DTrace fornito da Apple con gli Strumenti per sviluppatori su Mac OS X.

28

Git prova a convincersi del valore lstat() solo che il worktree corrisponde al indice, perché ricadere sui contenuti del file è molto costoso.

Documentation/technical/racy-git.txt descrive quali campi di statistiche vengono utilizzati e come si evitano alcune condizioni di gara a causa della bassa granulosità di mtime. This article has some more detail.

I valori statistici non sono a prova di manomissione, vedere i campioni (3). Git può essere ingannato nel perdere una modifica a un file; ciò non compromette l'integrità dell'hash del contenuto.

+1

Ma ogni commit ricade sul contenuto del file? O sta indovinando anche al momento del commit? – Pacerier

Problemi correlati