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/objectspiù 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).