2016-01-15 13 views
6

Se I touch è un file rintracciato in un repository git ed è in esecuzione git diff-index HEAD, stampa l'output con M indicando che il file è stato modificato. Ad esempio,Perché la modifica del risultato HEAD git diff-index per i file toccati dopo lo stato git diff o git?

$ touch foo 
$ git diff-index HEAD 
:100644 100644 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 0000000000000000000000000000000000000000 M foo 

Io sono sicuro se questo ha un senso o no, ma che non è la questione. La domanda è: perché l'output cambia (in assenza di diff) se eseguo git diff HEAD o git status?

$ touch foo 
$ git diff-index HEAD 
:100644 100644 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 0000000000000000000000000000000000000000 M foo 
$ git diff     # no output 
$ git diff-index HEAD  # no output 

mi aspetterei il risultato, qualunque esso sia, per rimanere gli stessi comandi in tutto che non dovrebbero cambiare nulla.

risposta

5

di prima dare un'occhiata a ciò che significa l'uscita di Let:

:100644 100644 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 0000000000000000000000000000000000000000 M foo 

The manual dice il seguente, da sinistra a destra:

  1. due punti.
  2. modalità per "src"; 000000 se la creazione o non interposta.
  3. uno spazio.
  4. modalità per "dst"; 000000 in caso di cancellazione o non interposta.
  5. uno spazio.
  6. sha1 per "src"; 0 {40} se la creazione o non interposta.
  7. uno spazio.
  8. sha1 per "dst"; 0 {40} se la creazione, non viene interrotta o "guarda l'albero del lavoro".
  9. uno spazio.
  10. stato, seguito dal numero "punteggio" opzionale.
  11. una scheda o un NUL quando opzione -z viene utilizzata.
  12. percorso per "src"
  13. una scheda o l'opzione NUL when -z viene utilizzata; esiste solo per C o R.
  14. percorso per "dst"; esiste solo per C o R.
  15. un LF o un NUL quando viene utilizzata l'opzione -z, per terminare il record.

Interessante è il punto 8:

SHA1 per "DST"; 0 {40} se la creazione, non viene interrotta o "guarda l'albero del lavoro".

Quindi nel tuo caso, ottieni 40 zeri, quindi significa "creazione", "non interrotto" o "guarda albero di lavoro". Poiché hai toccato solo il file, ed era già stato tracciato, puoi eliminare le prime due opzioni. Questo ci lascia con "guarda all'albero di lavoro".

E se lo fai, usando git diff (che proverà a generare le differenze di contenuto effettivo per tutte le modifiche e come tale in realtà guardano i contenuti del file), allora Git apparentemente scopre che non ci sono stati cambiamenti dopo tutto, quindi successivi le chiamate non dicono più nulla al riguardo.

Questa osservazione mi fa credere che per impostazione predefinita, git diff-index darà solo una rapida occhiata ai file, senza effettivamente confrontare alcun contenuto. Dato che hai modificato la data del file, Git lo considera come "eventualmente modificato" e richiede un aspetto più dettagliato per capirlo correttamente.

Se si esegue git diff-index con un'opzione che richiede di dare uno sguardo più approfondito ai file, quindi non troverà alcuna modifica, ad es. quando si utilizza l'opzione -p per generare una patch (che è esattamente ciò che fa git diff).

Quindi è probabile che solo un'ottimizzazione delle prestazioni di assumere un file potrebbe essere cambiato se la data di modifica del file è stato modificato, senza fare affermazioni sulle effettive esso; invece lascia semplicemente un indicatore "guarda più tardi".

+0

interessante 'git diff-index -p HEAD' non cambia l'output di un successivo' git diff-index HEAD'. – Jani

+2

'git update-index --refresh' aggiornerà le informazioni sull'indice in modo che un successivo' git diff-index' funzioni come ci si aspetterebbe. – Irfy