modulo 04 / lezione 17
Riscrivere la storia: rebase, amend, cherry-pick
git rebase: spostare commit su un'altra base
Capire cosa fa il rebase davvero e perché può produrre conflitti uno per commit.
git rebase: spostare commit su un’altra base
Rebase significa prendere una serie di commit e riprodurli sopra un’altra base. Non integra due storie come un merge: crea nuovi commit equivalenti su un punto diverso del grafo.
È uno strumento potente per mantenere una storia lineare, ma va usato con disciplina perché riscrive hash.
Perché questa lezione conta
Molti sviluppatori usano rebase come incantesimo prima della PR. Funziona finché non compare un conflitto, un force push o un collega che aveva basato lavoro sul branch vecchio.
Capire il replay dei commit permette di usare rebase senza paura e senza danneggiare branch condivisi.
Obiettivo operativo
Alla fine della lezione devi saper fare rebase di un branch personale su main, risolvere conflitti per commit, abortire se necessario e capire quando preferire merge.
Prima e dopo
Prima:
C -- D feat
/
A -- B -- E -- F main
feat è partito da B, ma main è andato avanti.
git switch feat
git fetch origin
git rebase origin/main
Dopo:
A -- B -- E -- F -- C' -- D' feat
C' e D' sono nuovi commit. Hanno contenuto simile a C e D, ma hash diverso perché hanno parent diverso.
Rebase non è merge
Merge conserva la divergenza:
C -- D
/ \
A -- B -- E -- M
Rebase riscrive la linea:
A -- B -- E -- C' -- D'
La storia diventa più lineare, ma perdi la forma originale della divergenza.
Conflitti durante rebase
Se un commit non si applica:
git status
Risolvi i file, poi:
git add file-risolto
git rebase --continue
Per saltare un commit:
git rebase --skip
Usalo con molta cautela: stai decidendo che quel commit non serve più.
Per annullare tutto:
git rebase --abort
Torna allo stato prima del rebase.
Quando usare rebase
Usalo per:
- aggiornare branch personale su
main; - preparare una PR lineare;
- evitare merge commit locali inutili;
- ripulire storia prima della condivisione.
Evitalo su:
- branch condivisi da più persone;
- branch di release;
- storia già usata come base da altri;
- situazioni in cui preservare il merge è informazione importante.
Rebase e push
Dopo rebase, il push normale può fallire:
git push
Perché il remoto ha la storia vecchia. Se il branch è tuo e il force push è previsto:
git push --force-with-lease
Mai usare --force per abitudine. --force-with-lease protegge dal sovrascrivere lavoro remoto che non hai visto.
Laboratorio guidato
In un repo demo:
- crea
maincon commitAeB; - crea branch
featcon commitCeD; - torna a
maine aggiungiE; - fai rebase di
featsumain; - osserva hash prima/dopo;
- crea un conflitto e risolvilo con
--continue; - ripeti e usa
--abort.
Output atteso
Un diagramma prima/dopo e una regola:
Rebase branch personale per linearità.
Merge branch condiviso per preservare storia.
Force push solo con --force-with-lease e solo se previsto.
Errori comuni
Pensare che rebase sposti gli stessi commit. Crea commit nuovi.
Rebasare branch condivisi. Obbliga altri a risincronizzare manualmente.
Usare --skip senza capire. Può eliminare modifiche necessarie.
Risoluzione conflitti frettolosa. Durante rebase il conflitto può ripresentarsi per commit successivi.
Checklist di verifica
- so disegnare rebase prima/dopo;
- so usare
--continue,--abort,--skip; - so perché cambiano gli hash;
- so quando serve
--force-with-lease; - so quando preferire merge.
Collegamenti
- Modulo: Riscrivere la storia: rebase, amend, cherry-pick — lezione 17 del corso.
- Il rebase interattivo della prossima lezione usa lo stesso principio di riscrittura.