Skip to content

05. Salvare le modifiche

Aggiunge modifiche della working directory alla staging area, cioè seleziona cosa entrerà nel prossimo commit.

Terminal window
git add <file> # un file
git add <directory> # una directory
git add -p # modalità interattiva, per chunk

La modalità interattiva (-p) è utile quando le modifiche apportate sono concettualmente slegate e solo una parte va nel commit: Git mostra i chunk e chiede azioni (y aggiungi, n ignora, s suddividi, q esci).

Buona pratica: ogni commit dovrebbe contenere tutte e sole le modifiche che realizzano un determinato cambiamento (es. l’aggiunta di una feature).

Fissa uno snapshot dello stato attuale nella history del progetto. Senza opzioni apre un editor per scrivere il messaggio.

Terminal window
git commit -m "messaggio" # messaggio direttamente da riga di comando
git commit -a # include automaticamente le modifiche ai file già tracciati
git commit -am "messaggio" # combinazione dei due
git commit --author="Jane Doe <jane@example.com>" # autore esplicito

Sul formato del messaggio, una convenzione diffusa: la prima riga come breve riassunto (come il subject di una email), poi una riga vuota e opzionali righe di dettaglio (come il body). Vedi anche la sezione 15.

5.3 git diff — visualizzare le differenze

Section titled “5.3 git diff — visualizzare le differenze”

Comando multi-uso per confrontare file, commit, branch:

Terminal window
git diff # working directory vs ultimo commit
git diff --staged # staging area vs ultimo commit
git diff ./path/to/file # solo un file
git diff <commit1> <commit2> # tra due commit
git diff branch-a..branch-b # tra due branch (confronta i tip)
git diff branch-a...branch-b # dal punto di biforcazione al tip di b

Come leggere l’output:

diff --git a/diff_test.txt b/diff_test.txt # sorgenti confrontate
index 6b0c6cf..b37e70a 100644 # metadati interni (ignorabili)
--- a/diff_test.txt # legenda: versione "a"
+++ b/diff_test.txt # legenda: versione "b"
@@ -1 +1 @@ # chunk head: riepilogo posizione
-this is a git diff test example # riga rimossa (-)
+this is a diff example # riga aggiunta (+)

Un head come @@ -34,6 +34,8 @@ significa: a partire dalla riga 34, 6 righe nella versione “a” e 8 nella “b”.

Mette da parte tutte le modifiche non ancora committate, per recuperarli in seguito. Utile quando si ha lavoro WIP (work in progress) ma serve tornare temporaneamente a uno stato pulito.

Terminal window
$ git stash
# Saved working directory and index state WIP on master: c5dfcdb add new logo
$ git status
# nothing to commit, working tree clean

Cose utili da sapere:

  • gli stash finiscono in una pila (stack): git stash list la elenca (stash@{0} il più recente);
  • git stash pop recupera l’ultimo stash rimuovendolo dalla pila; git stash apply lo recupera mantenendolo;
  • git stash pop stash@{2} recupera uno stash specifico;
  • git stash -u include anche i file untracked;
  • git stash drop stash@{1} elimina uno stash; git stash clear elimina tutti;
  • git stash show -p mostra il diff dello stash (rispetto al commit di origine);
  • gli stash restano solo nel repository locale, non vengono trasferiti al remote.

Oltre a tracked e untracked, esistono i file ignored: quelli che Git è stato istruito a escludere dal controllo di versione. Tipicamente: artefatti di build, file ricreabili dai sorgenti, segreti (password, chiavi).

Il file speciale .gitignore, di solito nella directory principale del progetto (ma può essercene uno in ogni sottodirectory), elenca i pattern da ignorare. Va committato nel repository.

Esempio per un progetto Laravel:

/vendor/
node_modules/
npm-debug.log
yarn-error.log
storage/*.key
.env
.phpunit.result.cache

Sintassi essenziale:

# commento
/logs # solo /logs nella directory corrente, non /example/logs
logs # logs ovunque (anche in sottodirectory)
logs/ # solo le directory di nome logs, non i file
*.log # pattern con wildcard
!debug.log # negazione: NON ignorare debug.log

Gitignore globale (valido per tutti i repository della macchina, per file di OS e IDE):

Terminal window
touch ~/.gitignore
git config --global core.excludesFile ~/.gitignore

Per ignorare un file già tracciato:

Terminal window
echo debug.log >> .gitignore
git rm --cached debug.log
git commit -m "rimosso debug.log dal repository"

⚠️ Il file resterà comunque presente nei commit precedenti: Git conserva la history.