Table of Contents
- 03 - Branching e Merging
- git branch
- git checkout / git switch
- Sintassi
- Spiegazione
- Esempi pratici
- git checkout vs git switch vs git restore
- Workflow cambio branch
- Opzioni comuni
- Note
- git merge
- Sintassi
- Spiegazione
- Esempi pratici
- Gestire Merge Conflicts
- Strategie di Merge
- Workflow completo Feature Branch
- Opzioni comuni
- Note
- git rebase
- Sintassi
- Spiegazione
- Esempi pratici
- Merge vs Rebase
- Workflow rebase per feature pulite
- Opzioni comuni
- Note
- 🔗 Collegamenti
- 📝 Riepilogo comandi
03 - Branching e Merging
Comandi per gestire branch (rami paralleli di sviluppo) e unire le modifiche.
git branch
Sintassi
git branch # Lista branch
git branch <nome> # Crea branch
git branch -d <nome> # Elimina branch
git branch [opzioni]
Spiegazione
Gestisce i branch del repository. I branch permettono sviluppo parallelo di feature senza interferire con il codice principale.
Esempi pratici
Listare tutti i branch locali:
git branch
Output:
develop
* main
feature-login
L'asterisco * indica il branch corrente.
Listare tutti i branch (locali + remoti):
git branch -a
# oppure
git branch --all
Output:
* main
develop
remotes/origin/main
remotes/origin/develop
remotes/origin/feature-api
Listare solo branch remoti:
git branch -r
Creare nuovo branch:
git branch feature-notifiche
Crea branch ma NON ci switcha.
Creare branch da commit specifico:
git branch hotfix abc123
Eliminare branch (merged):
git branch -d feature-completata
⚠️ Funziona solo se il branch è già stato merged.
Forzare eliminazione branch (anche non merged):
git branch -D feature-abbandonata
⚠️ Usa con cautela, perdi commit non merged!
Rinominare branch corrente:
git branch -m nuovo-nome
Rinominare branch diverso:
git branch -m vecchio-nome nuovo-nome
Vedere ultimo commit per branch:
git branch -v
Output:
develop abc123 Update dependencies
* main def456 Fix login bug
feature-login 789abc Add OAuth support
Branch merged/non-merged in main:
git branch --merged main # Branch già merged
git branch --no-merged main # Branch non ancora merged
Workflow tipico branch
# 1. Crea branch per nuova feature
git branch feature-dark-mode
# 2. Switcha al nuovo branch
git checkout feature-dark-mode
# 3. Lavora, commit...
git add .
git commit -m "Implement dark mode toggle"
# 4. Torna a main
git checkout main
# 5. Merge della feature
git merge feature-dark-mode
# 6. Elimina branch
git branch -d feature-dark-mode
Opzioni comuni
| Opzione | Descrizione |
|---|---|
-a, --all |
Tutti i branch (locali+remoti) |
-r |
Solo remoti |
-d |
Elimina (safe) |
-D |
Elimina (force) |
-m |
Rinomina |
-v |
Verbose (con ultimo commit) |
--merged |
Solo branch merged |
--no-merged |
Solo non merged |
Note
- Branch principale:
mainomaster - Convenzioni nomi:
feature/,bugfix/,hotfix/ - Branch sono "puntatori" leggeri a commit
git checkout / git switch
Sintassi
# Vecchio modo (checkout)
git checkout <branch>
git checkout -b <nuovo-branch>
# Nuovo modo (switch - Git 2.23+)
git switch <branch>
git switch -c <nuovo-branch>
Spiegazione
git checkout: Comando storico multi-funzione (cambia branch, ripristina file).
git switch: Comando nuovo dedicato solo al cambio branch (più chiaro).
Esempi pratici
Cambiare branch:
# Vecchio
git checkout develop
# Nuovo (preferito)
git switch develop
Creare e switchare branch in un comando:
# Vecchio
git checkout -b feature-api
# Nuovo (preferito)
git switch -c feature-api
Tornare al branch precedente:
git switch -
# oppure
git checkout -
Switchare a remote branch:
git switch feature-api
# Git crea automaticamente branch locale tracciando origin/feature-api
# Equivalente esplicito:
git switch -c feature-api origin/feature-api
Checkout di commit specifico (detached HEAD):
git checkout abc123
⚠️ Sei in "detached HEAD", commit fatti qui si perdono se non crei branch.
Per esplorare commit vecchi senza rischi:
# 1. Vai al commit
git checkout abc123
# 2. Esplora, compila, testa...
# 3. Torna a branch normale
git switch main
Checkout file da branch diverso:
git checkout develop -- config.ini
Prende config.ini dal branch develop e lo copia nel branch corrente.
git checkout vs git switch vs git restore
Git 2.23+ ha diviso checkout in due comandi più chiari:
| Comando | Uso | Esempio |
|---|---|---|
git switch |
Cambiare branch | git switch main |
git restore |
Ripristinare file | git restore file.txt |
git checkout |
Entrambi (legacy) | Vecchio modo |
Raccomandazione: usa switch e restore (più chiari).
Workflow cambio branch
# Verifica stato pulito
git status
# Se hai modifiche non salvate:
# Opzione 1: Commit
git commit -am "WIP: work in progress"
# Opzione 2: Stash (salva temporaneamente)
git stash
# Cambia branch
git switch develop
# (lavora su develop...)
# Torna a branch precedente
git switch main
# Ripristina stash (se usato)
git stash pop
Opzioni comuni
| Opzione | Descrizione |
|---|---|
-b (checkout) / -c (switch) |
Crea + switcha |
- |
Branch precedente |
-f, --force |
Forza (scarta modifiche locali) |
--detach |
Detached HEAD |
Note
- Non puoi switchare con modifiche uncommitted (usa stash o commit)
git switchè il modo moderno, usa quello- Detached HEAD: utile per esplorare, non per lavorare
git merge
Sintassi
git merge <branch>
git merge [opzioni] <branch>
Spiegazione
Unisce le modifiche di un branch in un altro. Integra la cronologia di due branch divergenti.
Esempi pratici
Merge base:
# Sei su main, vuoi mergere feature
git switch main
git merge feature-login
Merge fast-forward:
git merge develop
Se main non ha nuovi commit, Git sposta semplicemente il puntatore (fast-forward).
Output:
Updating abc123..def456
Fast-forward
src/auth.py | 10 ++++++++++
1 file changed, 10 insertions(+)
Merge con commit di merge:
git merge --no-ff feature-api
Crea sempre commit di merge anche se possibile fast-forward.
Merge con messaggio custom:
git merge feature-payment -m "Merge feature payment con gateway Stripe"
Merge senza commit automatico:
git merge --no-commit feature-test
# Verifica modifiche
git status
# Poi commit manuale
git commit -m "Merge feature test dopo review"
Annullare merge in corso:
git merge --abort
Gestire Merge Conflicts
Quando Git non riesce a unire automaticamente:
git merge feature-conflitto
Output:
Auto-merging src/app.py
CONFLICT (content): Merge conflict in src/app.py
Automatic merge failed; fix conflicts and then commit the result.
Workflow risoluzione conflitti:
# 1. Vedi file in conflitto
git status
# 2. Apri file e trova conflitti
# File conterrà:
<<<<<<< HEAD
codice nel branch corrente
=======
codice nel branch da mergere
>>>>>>> feature-conflitto
# 3. Risolvi manualmente (scegli/combina)
# Rimuovi marker <<<<, ====, >>>>
# 4. Staging file risolti
git add src/app.py
# 5. Completa merge
git commit
Tool visuale per conflitti:
git mergetool
Vedere file in conflitto:
git diff --name-only --diff-filter=U
Strategie di Merge
Merge normale (recursive):
git merge feature
Strategia default, funziona nella maggior parte dei casi.
Merge "ours" (ignora loro modifiche):
git merge -X ours feature
In caso di conflitto, prende sempre la versione del branch corrente.
Merge "theirs" (preferisci loro modifiche):
git merge -X theirs feature
Workflow completo Feature Branch
# 1. Crea feature branch da main
git switch main
git pull origin main
git switch -c feature-newsletter
# 2. Lavora sulla feature
git add .
git commit -m "Add newsletter subscription"
# 3. Aggiorna da main (se altri hanno pushato)
git switch main
git pull origin main
git switch feature-newsletter
git merge main # Porta novità di main nella feature
# 4. Merge feature in main
git switch main
git merge feature-newsletter
# 5. Push
git push origin main
# 6. Cleanup
git branch -d feature-newsletter
Opzioni comuni
| Opzione | Descrizione |
|---|---|
--no-ff |
Sempre commit di merge |
--ff-only |
Solo fast-forward |
--squash |
Squash commit in uno |
--abort |
Annulla merge in corso |
-X ours/theirs |
Strategia conflitti |
--no-commit |
Non committa automaticamente |
Note
- Prima di merge:
git pull origin main(aggiorna) - Conflitti sono normali, non aver paura
- Merge preserva cronologia completa
git rebase
Sintassi
git rebase <branch>
git rebase [opzioni] <branch>
Spiegazione
Riscrive la cronologia spostando commit sopra un altro branch. Crea cronologia lineare (più pulita di merge).
⚠️ REGOLA D'ORO: Non rebasare commit già pushati e condivisi!
Esempi pratici
Rebase base:
# Sei su feature, vuoi rebassare su main aggiornato
git switch feature-api
git rebase main
Git "stacca" i tuoi commit di feature, aggiorna a main, poi "riattacca" i commit sopra.
Rebase interattivo (riscrivere storia):
git rebase -i HEAD~3
Apre editor con ultimi 3 commit. Puoi:
pick= mantieni commitreword= cambia messaggioedit= modifica commitsquash= unisci con precedentefixup= come squash ma scarta messaggiodrop= elimina commit
Esempio interattivo:
pick abc123 Add login form
squash def456 Fix login validation
pick 789abc Add tests
Risultato: primi due commit uniti in uno.
Continuare rebase dopo risolvere conflitti:
# Conflitto durante rebase
git add file-risolto.txt
git rebase --continue
Saltare commit problematico:
git rebase --skip
Annullare rebase:
git rebase --abort
Rebase su remote branch:
git rebase origin/main
Merge vs Rebase
Merge (preserva cronologia):
A---B---C feature
/ \
D---E---F---G---H main
Rebase (cronologia lineare):
A'--B'--C' feature
/
D---E---F---G main
Quando usare Merge:
- Feature branch pubbliche condivise
- Vuoi preservare cronologia esatta
- Lavoro in team
Quando usare Rebase:
- Pulizia branch locale prima di push
- Cronologia lineare leggibile
- Feature branch personali
Workflow rebase per feature pulite
# 1. Sviluppo locale su feature
git switch feature-auth
git add .
git commit -m "WIP: auth logic"
git commit -m "WIP: tests"
git commit -m "WIP: fix bug"
# 2. Squash commit prima di push (pulizia)
git rebase -i HEAD~3
# (squash tutti in un commit pulito)
# 3. Aggiorna feature con ultimi cambiamenti main
git fetch origin
git rebase origin/main
# 4. Push (prima volta forza con -f)
git push origin feature-auth -f
# 5. Merge in main (da GitHub/Forgejo PR)
Opzioni comuni
| Opzione | Descrizione |
|---|---|
-i |
Interattivo |
--continue |
Continua dopo conflitto |
--skip |
Salta commit |
--abort |
Annulla |
--onto |
Rebase su branch diverso |
--autosquash |
Auto-squash fixup commits |
Note
- MAI rebasare commit pubblici/pushati
- Rebase riscrive SHA commit
- Utile per cronologia pulita prima PR
- Più complesso di merge, serve pratica
🔗 Collegamenti
- Precedente: ← Staging e Commit
- Prossimo: History →
- Indice: ← Torna all'indice
📝 Riepilogo comandi
# BRANCH
git branch # Lista branch
git branch feature # Crea branch
git branch -d feature # Elimina branch
git branch -a # Tutti (locali+remoti)
# SWITCH
git switch main # Cambia branch
git switch -c feature # Crea + switcha
git switch - # Branch precedente
# CHECKOUT (legacy)
git checkout main # Cambia branch
git checkout -b feature # Crea + switcha
# MERGE
git merge feature # Merge feature in branch corrente
git merge --no-ff feature # Sempre commit di merge
git merge --abort # Annulla merge
# REBASE
git rebase main # Rebase su main
git rebase -i HEAD~3 # Interattivo (ultimi 3)
git rebase --continue # Continua dopo conflitto
git rebase --abort # Annulla rebase