Introduzione
L'index, chiamato anche staging area o cache, è una delle caratteristiche distintive di Git. È un file binario in .git/index che contiene l'albero che intendi committare prossimamente. Capire l'index toglie la maggior parte del mistero dall'output di git status.
Perché esiste
L'index ti permette di comporre un commit deliberatamente invece di scaricare ogni modifica in una volta sola. Puoi modificare dieci file ma committarne solo i tre che risolvono un bug, lasciando gli altri in stage per un commit successivo. Questo disaccoppiamento abilita una storia pulita e atomica.
Ispezionare l'index
Due comandi confrontano le tre aree:
git diff # working tree vs index
git diff --staged # index vs HEAD
git diff HEAD # working tree vs HEAD
Il comando plumbing git ls-files --stage mostra il contenuto grezzo dell'index, inclusi gli hash SHA-1:
git ls-files --stage
Mettere in stage le modifiche
git add file.txt # aggiungi o aggiorna
git add . # aggiungi tutto dalla cwd in giù
git add -u # aggiorna solo i file tracciati
git add -p # interattivo, hunk per hunk
git add -N new.txt # intent-to-add (traccia vuoto)
Togliere dallo stage
Se hai messo in stage qualcosa per errore, toglilo senza perdere la modifica:
# Moderno (Git 2.23+)
git restore --staged file.txt
# Sintassi più vecchia, funziona ancora
git reset HEAD file.txt
L'index nei conflitti
Durante un conflitto di merge, l'index acquisisce tre entry per ogni path in conflitto: stage 1 è l'antenato comune, stage 2 è "ours", stage 3 è "theirs". git ls-files -u le mostra:
git ls-files -u
Risolvere il conflitto significa scrivere una versione finale e fare git add, riducendo a una singola entry stage-0.
Il formato del file index
L'index è un formato binario documentato nel sorgente di Git in Documentation/gitformat-index.txt. Inizia con un header di 12 byte (signature DIRC, versione, conteggio entry) seguito da entry ordinate. Diverse estensioni opzionali aggiungono caching: TREE memorizza nella cache gli hash dei sottoalberi per write-tree veloce, e UNTR memorizza nella cache le liste di file untracked per git status veloce. Git moderno supporta anche un sparse index che omette le entry fuori dal cono che hai checkoutato:
git sparse-checkout init --cone
git config core.sparseCheckoutCone true
git update-index --test-untracked-cache
Errori comuni
Credere che git add sia definitivo. Non lo è: puoi mettere in stage, modificare di nuovo e rimettere in stage. L'index è solo la bozza del prossimo commit. Un'altra confusione classica: modificare un file in stage, poi committare, ed essere perplessi che le nuove modifiche non siano incluse. git add cattura uno snapshot al momento dell'esecuzione; le modifiche successive vivono solo nella working tree. Esegui git diff (senza flag) per vedere cosa è in stage ma poi modificato. Infine, non cancellare mai .git/index manualmente; ricostruiscilo con git read-tree HEAD se mai si corrompe.