Da Anonimo (non verificato) , 29 Aprile 2026

Introduzione

Ogni operazione Git sposta dati tra tre aree: la working tree (i tuoi file), l'index (bozza del prossimo commit) e il repository (storia committata sotto .git). Nominare cosa si sposta dove è il modello mentale più utile in assoluto.

Le aree

  • Working tree: la directory che modifichi.
  • Index: .git/index, il tree in stage.
  • Repository: oggetti in .git/objects più ref in .git/refs.

Comandi per direzione

# working tree -> index
git add file
git rm file
git mv old new

# index -> repository
git commit
git write-tree   # plumbing

# repository -> index
git reset <commit>
git read-tree <tree>

# repository -> working tree (e di solito index)
git checkout <commit> -- file
git restore --source <commit> file
git switch <branch>

I quattro diff

Puoi confrontare due aree qualsiasi:

git diff                  # working tree vs index
git diff --staged         # index vs HEAD
git diff HEAD             # working tree vs HEAD
git diff main feature     # repository vs repository

Status decodificato

git status -s
# XY filename
# X = stato dell'index, Y = stato della working tree
# M modificato, A aggiunto, D cancellato, R rinominato, ?? untracked

Per esempio MM significa modificato sia nell'index che nella working tree (hai messo in stage una modifica e poi modificato di nuovo).

Reset, restore, checkout

Ognuno influenza aree diverse:

  • git reset --soft: solo repository (sposta il ref).
  • git reset (mixed): repository + index.
  • git reset --hard: repository + index + working tree.
  • git restore --staged: index da HEAD.
  • git restore: working tree dall'index.
  • git restore --source=<commit>: working tree (e opzionalmente index) da un commit specifico.

Un esercizio

echo a > f.txt
git add f.txt
git commit -m "v1"
echo b >> f.txt
git add f.txt
echo c >> f.txt
git status
git diff
git diff --staged
git diff HEAD

Leggi ogni diff; capire perché differiscono cementa il modello.

Plumbing per ogni area

Conoscere il plumbing per ogni area demistifica i comandi di livello più alto:

  • Working tree: operazioni filesystem ordinarie.
  • Index: git update-index, git ls-files, git read-tree, git write-tree.
  • Object database: git hash-object, git cat-file, git mktree, git commit-tree.
  • Ref: git update-ref, git symbolic-ref, git for-each-ref.
git ls-files --stage              # index
git ls-tree HEAD                  # repo
ls -R                             # working tree

Errori comuni

Cercare di memorizzare comandi invece di aree; una volta che sai quale area è la sorgente e quale la destinazione, il comando giusto è ovvio. Confondere git restore file con git checkout file; sono equivalenti per quel caso, ma le molte altre modalità di checkout confondono i nuovi utenti. Usare git reset --hard per "fare pulizia" senza rendersi conto che distrugge la working tree. E infine, aspettarsi che git commit includa modifiche non in stage; non lo fa (a meno che non passi -a per i soli file tracciati).