Git rebase: tutto quello che c'è da sapere

Pubblicato: 2022-12-15
Computer portatile su sfondo blu che mostra un prompt dei comandi di Linux.
fatmawati achmad zaenuri/Shutterstock.com
Il comando Git rebase sposta un ramo in una nuova posizione all'inizio di un altro ramo. A differenza del comando Git merge, rebase comporta la riscrittura della cronologia del progetto. È un ottimo strumento, ma non rebase commit su cui altri sviluppatori hanno basato il lavoro.

Il comando Git rebase combina due rami del codice sorgente in uno solo. Anche il comando Git merge fa questo. Spieghiamo cosa fa rebase , come viene utilizzato e quando invece utilizzare merge .

Sommario

L'esplosione di Git
Cos'è l'unione di Git?
Cos'è il rebase di Git?
Come ribasare su un altro ramo
Git Rebase vs. Merge: quale dovresti usare?
Ribasare o non ribasare?

L'esplosione di Git

Frustrato da altri sistemi di controllo di versione e dai loro lenti aggiornamenti e commit, Linus Torvalds, famoso per il kernel Linux, ha messo da parte un mese nel 2005 per scrivere il proprio. Lo ha chiamato Git.

Siti come GitHub, GitLab e BitBucket hanno promosso e beneficiato simbioticamente di Git. Oggi Git è utilizzato a livello globale, con un enorme 98% di 71mila intervistati in un sondaggio del 2022 che utilizza Git come sistema di controllo della versione.

Una delle principali decisioni di progettazione di Git è stata la velocità. In particolare, lavorare con le filiali doveva essere il più veloce possibile. I rami sono una parte fondamentale dei sistemi di controllo della versione. Un repository di progetto avrà un ramo principale o principale. Qui è dove si trova la base di codice del progetto. Lo sviluppo, come le nuove funzionalità, avviene in rami secondari separati. Ciò impedisce al lavoro svolto nei rami di incasinare il ramo principale e consente lo sviluppo simultaneo in diverse parti della base di codice.

Come scegliere il flusso di lavoro Git e il modello di branching adatto al tuo team
CORRELATO Come scegliere il flusso di lavoro Git e il modello di ramificazione adatto al tuo team

Man mano che gli sviluppi nei rami secondari vengono completati, le modifiche vengono trasferite al ramo principale unendo il ramo di sviluppo nel ramo principale. In altre versioni i sistemi di controllo che lavorano con i rami erano difficili e computazionalmente costosi. Lavorare con i rami in Git è molto veloce e molto leggero. Quello che una volta era un esercizio noioso e spesso evitato in altri sistemi, è diventato banale in Git.

Il comando Git rebase è un altro modo per trasferire le modifiche da un ramo a un altro ramo. I comandi merge e rebase hanno obiettivi simili, ma raggiungono i loro scopi in modi diversi e producono risultati leggermente diversi.

Cos'è l'unione di Git?

Allora a cosa serve il comando Git merge ? Supponiamo che tu abbia creato un ramo chiamato dev-branch per lavorare su una nuova funzionalità.

Un diagramma di un ramo master e di un ramo non unito denominato dev-branch
Dave McKay/How-To-Geek

Fai alcuni commit e provi la tua nuova funzionalità. Funziona tutto bene. Ora vuoi inviare la tua nuova funzione al ramo master . Devi essere nel ramo master per unirne un altro.

Possiamo assicurarci di essere nel ramo master controllandolo esplicitamente prima di unirci.

 maestro di checkout git

Ora possiamo dire a Git di fondere il dev-branch nel ramo corrente, che è il ramo master .

 git merge dev-branch 

Unire il ramo dev-branch nel ramo master

La nostra merge è completata per noi. Se controlli il ramo master e lo compili, conterrà la funzionalità appena sviluppata. Ciò che Git ha effettivamente eseguito è un'unione a tre vie. confronta i commit più recenti nei rami master e dev-branch e il commit nel ramo master immediatamente prima della creazione dev-branch . Quindi esegue un commit sul ramo master .

Le unioni sono considerate non distruttive perché non eliminano nulla e non modificano la cronologia di Git. Il dev-branch esiste ancora e nessuno dei commit precedenti viene modificato. Viene creato un nuovo commit che acquisisce i risultati dell'unione a tre vie.

Dopo l'unione, il nostro repository Git si presenta come una timeline con una linea alternativa che si dirama e poi ritorna alla timeline principale.

Il ramo dev-branch si è unito al ramo master
Dave McKay/How-To Geek

Il dev-branch è stato incorporato nel ramo master .

Se hai molti rami in un progetto, la cronologia del progetto può diventare confusa. Questo è spesso il caso se un progetto ha molti contributori. Poiché lo sforzo di sviluppo si suddivide in molti percorsi diversi, la cronologia dello sviluppo non è lineare. Districare la cronologia dei commit diventa ancora più difficile se i rami hanno i propri rami.

Come funzionano i rami Git?
CORRELATO Come funzionano i rami Git?

Nota che se hai modifiche non salvate nel ramo master , dovrai fare qualcosa con queste modifiche prima di poter unire qualsiasi cosa ad esso. Potresti creare un nuovo ramo e confermare le modifiche lì, quindi eseguire l'unione. Dovresti quindi unire nuovamente il tuo ramo temporaneo nel ramo principale.

Funziona, ma Git ha un comando che ottiene la stessa cosa, senza dover creare nuovi rami. Il comando stash memorizza le modifiche non salvate per te e ti consente di richiamarle con stash pop .

Li useresti così:

 scorta

git merge dev-branch

schiocco di scorta

Il risultato finale è un ramo unito, con le modifiche non salvate ripristinate.

Cos'è il rebase di Git?

Il comando Git rebase raggiunge i suoi obiettivi in ​​un modo completamente diverso. Prende tutti i commit dal ramo che stai per ribasare e li riproduce alla fine del ramo su cui stai ribasando.

Prendendo il nostro esempio precedente, prima di eseguire qualsiasi azione il nostro repository Git si presenta così. Abbiamo un ramo chiamato dev-branch e vogliamo spostare quelle modifiche al ramo master .

Un diagramma di un ramo master e di un ramo non unito denominato dev-branch
Dave McKay/How-To-Geek

Dopo il rebase , sembra un'unica linea temporale di modifiche completamente lineare.

Il ramo master con il ramo dev è stato ribasato su di esso
Dave McKay/How-To Geek

Il dev-branch è stato rimosso e i commit nel dev-branch sono stati aggiunti al ramo master. Il risultato finale è lo stesso che se i commit nel dev-branch fossero stati effettivamente impegnati direttamente nel ramo master in primo luogo. I commit non vengono semplicemente aggiunti al ramo master , ma vengono "riprodotti" e aggiunti di nuovo.

Questo è il motivo per cui il comando rebase è considerato distruttivo. Il ramo ribasato non esiste più come ramo separato e la cronologia Git del tuo progetto è stata riscritta. Non è possibile determinare in un secondo momento quali commit sono stati originariamente effettuati su dev-branch .

Tuttavia, ti lascia con una storia semplificata, lineare. Rispetto a un repository con dozzine o addirittura centinaia di rami e fusioni, leggendo il registro Git o utilizzando una GUI grafica git per guardare un grafico del repository, un repository ribasato è un gioco da ragazzi da capire.

Come ribasare su un altro ramo

Proviamo un esempio di git rebase . Abbiamo un progetto con un ramo chiamato new-feature . rebase quel ramo sul ramo master in questo modo.

Innanzitutto, controlliamo che il ramo master non abbia modifiche in sospeso.

 stato git

Controlliamo il ramo delle new-feature .

 git checkout nuova funzionalità

Diciamo a Git di rebase il ramo corrente sul ramo master.

 git rebase master

Possiamo vedere che abbiamo ancora due rami.

 ramo git

Torniamo al ramo master

 maestro di checkout git

Uniamo il ramo new-feature nel ramo corrente, che nel nostro caso è il ramo master .

 git merge nuova funzionalità 
Il ramo master con la nuova funzionalità è stato ribasato su di esso
Dave McKay/How-To Geek

È interessante notare che abbiamo ancora due rami dopo la fusione finale.

Utilizzo del comando Git branch per elencare i rami nel repository git
Dave McKay/How-To Geek

La differenza è che ora l'head del ramo new-feature e l'head del branch master sono impostati per puntare allo stesso commit, e la cronologia di Git non mostra che prima c'era un ramo new-feature separato, a parte l'etichetta del ramo.

Il ramo master con il ramo dev è stato ribasato su di esso
Dave McKay/How-To Geek

Git Rebase vs. Merge: quale dovresti usare?

Non è un caso di rebase vs. merge . Sono entrambi comandi potenti e probabilmente li userai entrambi. Detto questo, ci sono casi d'uso in cui rebase non funziona molto bene. Gli errori di unpicking causati da errori che utilizzano merge sono spiacevoli, ma gli errori di unpicking causati da rebase sono infernali.

Se sei l'unico sviluppatore che utilizza un repository, ci sono meno possibilità che tu faccia qualcosa con rebase che sia disastroso. Potresti ancora rebase nella direzione sbagliata, ad esempio, e rebase il tuo ramo principale sul ramo della new-feature . Per riavere il tuo ramo master , dovresti eseguire nuovamente il rebase , questa volta dal ramo della new-feature al ramo master . Ciò ripristinerebbe il tuo ramo master , anche se con una storia dall'aspetto strano.

Non utilizzare rebase su rami condivisi in cui è probabile che altri funzionino. Le tue modifiche al tuo repository causeranno problemi a molte persone quando invii il tuo codice ribasato al tuo repository remoto.

Se il tuo progetto ha più contributori, la cosa sicura da fare è utilizzare solo rebase sul tuo repository locale e non su rami pubblici. Allo stesso modo, se le richieste pull fanno parte delle revisioni del codice, non utilizzare rebase . O almeno, non utilizzare rebase dopo aver creato la richiesta pull. È probabile che altri sviluppatori guardino i tuoi commit, il che significa che tali modifiche si trovano su un ramo pubblico, anche se non si trovano sul ramo master .

Il pericolo è che stai per rebase i commit che sono già stati inviati a un repository remoto e altri sviluppatori potrebbero aver già basato il lavoro su quei commit. Il tuo rebase locale farà svanire quei commit esistenti. Se invii tali modifiche al repository, non diventerai popolare.

Come correggere, modificare o annullare i commit di Git (modificare la cronologia di Git)
CORRELATO Come correggere, modificare o annullare i commit di Git (modificare la cronologia di Git)

Altri contributori dovranno passare attraverso merge disordinata per riportare il loro lavoro nel repository. Se poi riporti le loro modifiche al tuo repository locale, ti troverai di fronte alla rimozione di un pasticcio di modifiche duplicate.

Ribasare o non ribasare?

Rebase potrebbe essere fuorilegge nel tuo progetto. Potrebbero esserci obiezioni locali e culturali. Alcuni progetti o organizzazioni considerano il rebase come una forma di eresia e un atto di profanazione. Alcune persone credono che la storia di Git dovrebbe essere una registrazione inviolabile e permanente di ciò che è accaduto. Quindi, rebase potrebbe essere fuori dal tavolo.

Ma, utilizzato localmente, su filiali private, rebase è uno strumento utile.

Invia dopo aver ribasato e limitalo ai rami in cui sei l'unico sviluppatore. O almeno, dove tutto lo sviluppo si è fermato e nessun altro ha basato nessun altro lavoro sui commit del tuo ramo.

Fallo ed eviterai qualsiasi problema.

CORRELATO: Come controllare e aggiornare la tua versione di Git