🌿

Git

Version control per esseri umani. Dal primo commit al rebase interattivo, tutto quello che serve per non perdere mai piu il lavoro.

Ultimo aggiornamento: 2026-03-28

0Comandi
0Sezioni
0Quiz
Comandi Essenzialibase
base
git init

Crea un repository Git nella cartella corrente. Genera la cartella nascosta .git/ che contiene tutta la storia del progetto.

Esempio:
$ mkdir my-project && cd my-project
$ git init
Initialized empty Git repository in /home/steven/my-project/.git/
base
git clone url

Scarica un repository completo (codice + tutta la storia) da un server remoto. Il modo standard per iniziare a lavorare su un progetto esistente.

Esempio:
$ git clone git@github.com:giobi/claude-skills.git
Cloning into 'claude-skills'...
remote: Enumerating objects: 234, done.
remote: Total 234 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (234/234), 45.2 KiB | 1.2 MiB/s, done.

$ cd claude-skills && ls
README.md  plugins/  boot/
base
git status

Mostra lo stato del working tree: file modificati, file in staging, file nuovi non tracciati. Il comando che usi piu spesso in assoluto.

Esempio:
$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   src/app.py

Changes not staged for commit:
        modified:   config.yaml

Untracked files:
        notes.txt
base
git add file.txt

Aggiunge file alla staging area (il "palco" dei prossimi commit). Usa git add . per tutto, ma attenzione a non includere file sensibili.

Esempio:
# Singolo file
$ git add src/app.py

# Tutti i file modificati e nuovi
$ git add .

# Solo file gia tracciati (no nuovi)
$ git add -u

# Pattern
$ git add *.py
Attenzione: git add . include TUTTO, anche .env con le password. Usa sempre un .gitignore e controlla con git status prima di committare.
base
git commit -m "messaggio"

Salva uno snapshot del codice nella storia. Il messaggio deve spiegare il perche, non il cosa — il diff mostra gia il cosa.

Esempio:
# Commit con messaggio inline
$ git commit -m "Fix login timeout su connessioni lente"

# Commit con editor (per messaggi lunghi)
$ git commit

# Add + commit insieme (solo file gia tracciati)
$ git commit -am "Aggiorna config porta database"
Tip: Buon messaggio: "Fix race condition nel job scheduler". Cattivo messaggio: "fix bug" o "update files".
base
git push

Invia i tuoi commit al repository remoto. La prima volta su un branch nuovo serve -u per impostare il tracking.

Esempio:
# Push normale (branch gia tracciato)
$ git push

# Prima push di un branch nuovo
$ git push -u origin feature/login

# Push su un remoto specifico
$ git push origin main
base
git pull

Scarica le modifiche dal remoto e le integra nel branch locale. E un git fetch + git merge in un colpo solo.

Esempio:
$ git pull
remote: Enumerating objects: 5, done.
Already up to date.

# Pull con rebase (storia piu pulita, senza merge commit)
$ git pull --rebase
Tip: git pull --rebase evita i merge commit inutili quando lavori da solo. Metti pull.rebase = true nella config globale per farlo di default.
Comandi Intermediintermedio
intermedio
git branch / git switch

I branch sono linee di sviluppo parallele. Crea un branch per ogni feature o fix, lavora li, poi unisci quando e pronto.

Esempio:
# Lista branch locali (* = corrente)
$ git branch
* main
  feature/login
  fix/timeout

# Crea e passa a un nuovo branch
$ git switch -c feature/dark-mode

# Passa a un branch esistente
$ git switch main

# Elimina branch (solo se gia mergiato)
$ git branch -d feature/login

# Lista branch remoti
$ git branch -r
intermedio
git merge feature-branch

Unisce un branch nel branch corrente. Se ci sono conflitti, Git ti chiede di risolverli manualmente.

Esempio:
# Vai su main e mergia la feature
$ git switch main
$ git merge feature/login
Merge made by the 'ort' strategy.
 src/auth.py | 45 ++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

# Se ci sono conflitti:
$ git merge feature/api
CONFLICT (content): Merge conflict in src/routes.py
# Apri il file, risolvi i marker <<<<<<< ======= >>>>>>>
$ git add src/routes.py
$ git commit   # completa il merge
intermedio
git log --oneline --graph

Visualizza la storia dei commit. --oneline compatta, --graph mostra i branch visualmente. Il modo migliore per capire cosa e successo.

Esempio:
$ git log --oneline --graph --all -15
* 9d8648d (HEAD -> main) Brain v5.0: migrazione
* 742f480 Initial brain setup
* d966418 manifest: protocol v2.1
| * a3b1c2d (feature/radar) Add radar dashboard
|/
* 8cd67f3 Update BRAIN.md to v2.1
* 68612d2 v2.0: Brain Protocol rewrite

# Chi ha toccato un file specifico
$ git log --oneline -- src/auth.py

# Cerca nei messaggi di commit
$ git log --grep="fix" --oneline
intermedio
git diff

Mostra le differenze tra versioni. Senza argomenti mostra le modifiche non ancora in staging. Con --staged mostra cosa andra nel prossimo commit.

Esempio:
# Modifiche non in staging
$ git diff

# Modifiche in staging (pronte per il commit)
$ git diff --staged

# Differenze tra due branch
$ git diff main..feature/login

# Solo nomi dei file cambiati
$ git diff --name-only main..HEAD
intermedio
git stash

Parcheggia le modifiche correnti senza committarle. Perfetto quando devi cambiare branch urgentemente ma non vuoi fare un commit "WIP".

Esempio:
# Parcheggia tutto
$ git stash
Saved working directory and index state WIP on main: 9d8648d Brain v5.0

# Fai quello che devi...
$ git switch hotfix && git pull && ...

# Torna e riprendi le modifiche
$ git switch main
$ git stash pop   # applica e rimuovi dallo stash

# Lista stash salvati
$ git stash list
stash@{0}: WIP on main: 9d8648d Brain v5.0

# Stash con messaggio (se ne fai piu di uno)
$ git stash push -m "form validation WIP"
intermedio
.gitignore

File che elenca cosa Git deve ignorare. Mettilo nella root del progetto. Essenziale per tenere fuori credenziali, dipendenze e file generati.

.gitignore tipico:
# Credenziali e segreti
.env
*.pem
credentials.json

# Dipendenze
node_modules/
__pycache__/
venv/

# Build e generati
dist/
build/
*.pyc

# OS
.DS_Store
Thumbs.db

# IDE
.vscode/
.idea/
Attenzione: Se un file e gia tracciato, aggiungerlo a .gitignore non basta. Serve git rm --cached file.env per rimuoverlo dal tracking (senza cancellarlo dal disco).
Comandi Avanzatiavanzato
avanzato
git rebase main

Riapplica i tuoi commit sopra un altro branch, creando una storia lineare senza merge commit. Piu pulito di merge, ma riscrive la storia.

Esempio:
# Aggiorna il tuo branch con le ultime modifiche di main
$ git switch feature/api
$ git rebase main
Successfully rebased and updated refs/heads/feature/api.

# Se ci sono conflitti durante il rebase:
$ git rebase main
CONFLICT in src/routes.py
# Risolvi il conflitto, poi:
$ git add src/routes.py
$ git rebase --continue

# Tutto andato storto? Annulla tutto:
$ git rebase --abort
Attenzione: Non fare rebase di commit gia pushati su branch condivisi. Riscrive gli hash e crea casino per chi ha gia quei commit. Regola: rebase solo commit locali.
avanzato
git cherry-pick abc1234

Prende un singolo commit da un altro branch e lo applica al branch corrente. Utile per portare un hotfix senza mergiare tutto il branch.

Esempio:
# Trova il commit che ti serve
$ git log --oneline feature/api
a1b2c3d Fix CORS header
e4f5g6h Add pagination
i7j8k9l Refactor routes

# Prendi solo il fix CORS
$ git switch main
$ git cherry-pick a1b2c3d
[main 1234567] Fix CORS header
 1 file changed, 3 insertions(+)
avanzato
git reset

Sposta HEAD (e opzionalmente staging/working tree) a un commit precedente. Tre modalita: --soft (mantieni tutto in staging), --mixed (default, togli da staging), --hard (cancella tutto).

Esempio:
# Annulla ultimo commit, tieni le modifiche in staging
$ git reset --soft HEAD~1

# Annulla ultimo commit, tieni le modifiche ma fuori dallo staging
$ git reset HEAD~1

# CANCELLA tutto e torna a un commit (DISTRUTTIVO)
$ git reset --hard HEAD~1

# Togli un file dallo staging (senza perdere modifiche)
$ git restore --staged config.yaml
Attenzione: git reset --hard cancella le modifiche in modo irreversibile. Se hai gia pushato quei commit, non farlo — usa git revert invece.
avanzato
git bisect

Ricerca binaria per trovare QUALE commit ha introdotto un bug. Git fa checkout di commit intermedi, tu dici se funziona o no, e in pochi step trova il colpevole.

Esempio:
$ git bisect start
$ git bisect bad            # il commit attuale ha il bug
$ git bisect good v1.0      # questo commit era OK

# Git fa checkout di un commit intermedio
Bisecting: 15 revisions left to test
# Testa... funziona?
$ git bisect good           # si, qui va bene

# Git salta avanti...
Bisecting: 7 revisions left to test
# Testa... rotto?
$ git bisect bad            # qui e rotto

# Dopo pochi step:
abc1234 is the first bad commit
Author: whoever
Date: ...
    "Refactor auth middleware"    # TROVATO!

$ git bisect reset          # torna alla normalita
avanzato
git reflog

La rete di sicurezza definitiva. Registra OGNI movimento di HEAD — anche dopo reset --hard, rebase andati male, branch cancellati. Se l'hai committato almeno una volta, e recuperabile.

Esempio:
# Vedi la storia di tutti i movimenti
$ git reflog
9d8648d HEAD@{0}: commit: Brain v5.0
742f480 HEAD@{1}: reset: moving to HEAD~3   # oops!
a1b2c3d HEAD@{2}: commit: Important work
e4f5g6h HEAD@{3}: commit: More stuff

# Recupera il commit perso dopo un reset --hard
$ git reset --hard a1b2c3d   # torna al commit "Important work"

# Recupera un branch cancellato
$ git reflog | grep "feature/api"
f1e2d3c HEAD@{15}: checkout: moving from feature/api to main
$ git switch -c feature/api f1e2d3c
Tip: Il reflog e locale e dura ~90 giorni. Se hai fatto un disastro con reset/rebase, il reflog e il primo posto dove guardare.
Combinazioni e Workflowpratico
pratico
Feature Branch Workflow

Il workflow standard per qualsiasi progetto: branch per feature, lavora, pusha, merge/PR, cancella il branch.

Il ciclo completo:
# 1. Parti da main aggiornato
$ git switch main && git pull

# 2. Crea branch per la feature
$ git switch -c feature/user-profile

# 3. Lavora, committa (anche piu volte)
$ git add -A && git commit -m "Add user profile page"
$ git add -A && git commit -m "Add avatar upload"

# 4. Pusha il branch
$ git push -u origin feature/user-profile

# 5. Crea PR su GitHub (o merge locale)
$ git switch main
$ git merge feature/user-profile
$ git push

# 6. Pulizia
$ git branch -d feature/user-profile
$ git push origin --delete feature/user-profile
pratico
Undo cheatsheet

La guida rapida per ogni tipo di "ho sbagliato": dalla modifica non salvata al commit pushato.

Ogni scenario:
# Ho modificato un file e voglio tornare indietro
$ git restore config.yaml

# Ho fatto git add ma non voglio committare quel file
$ git restore --staged config.yaml

# Ho committato ma non ho pushato — voglio rifare il commit
$ git reset --soft HEAD~1    # torna in staging
# ...modifica, poi committa di nuovo

# Ho committato E pushato — non posso riscrivere la storia
$ git revert HEAD            # crea un nuovo commit che annulla

# Ho cancellato un branch per errore
$ git reflog                 # trova il commit
$ git switch -c recovered abc1234

# Ho fatto un rebase e ora e tutto rotto
$ git rebase --abort         # se sei ancora nel rebase
$ git reflog                 # se hai gia finito, trova lo stato precedente
Troubleshootingdebug
debug
Risolvere conflitti di merge

Quando Git non sa come unire automaticamente due versioni, inserisce dei marker nel file. Devi scegliere tu cosa tenere.

I marker nel file:
# Il file conterra qualcosa tipo:
<<<<<<< HEAD
timeout = 30
=======
timeout = 60
>>>>>>> feature/api

# Sopra ======= : la tua versione
# Sotto ======= : la versione dell'altro branch
# Scegli, rimuovi i marker, salva

# Poi:
$ git add src/config.py
$ git commit   # Git sa gia che e un merge

# Se vuoi vedere quali file hanno conflitti:
$ git diff --name-only --diff-filter=U

# Se vuoi abortire tutto il merge:
$ git merge --abort
debug
git blame file.py

Mostra chi ha scritto ogni riga di un file e quando. Non per accusare nessuno — per capire il contesto di una modifica e chiedere a chi l'ha fatta.

Esempio:
$ git blame src/auth.py
9d8648d (Steven  2026-03-27 14:30) def authenticate(user):
742f480 (Steven  2026-03-26 10:15)     if not user.token:
a1b2c3d (Claude  2026-03-28 19:00)         raise AuthError("no token")

# Solo righe specifiche (es. 10-20)
$ git blame -L 10,20 src/auth.py

Quiz — Verifica le tue conoscenze

1. Qual e la differenza tra git fetch e git pull?

2. Hai committato per errore un file .env con le password. Cosa fai?

3. Cosa fa git stash?

4. Hai fatto git reset --hard e perso dei commit. Come li recuperi?

5. Quando NON dovresti fare rebase?

6. Come annulli un commit gia pushato senza riscrivere la storia?

7. Cosa fa git bisect?

8. Qual e la differenza tra git reset --soft e --hard?

Punteggio: 0/0