Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Rebasing in Git

Impariamo ad utilizzare il rebasing in Git come alternativa alla fusione (merging) dei rami di sviluppo.
Impariamo ad utilizzare il rebasing in Git come alternativa alla fusione (merging) dei rami di sviluppo.
Link copiato negli appunti

Uno tra i comandi più utili in Git è Rebase: vediamone le differenze rispetto al merging e le operazioni che è possibile effettuare con esso.

Differenze tra rebasing e merging

In Git il rebasing (o rifondazione) è una procedura molto simile al merging che presenta però delle differenze di carattere concettuale oltre a basarsi su comandi diversi. Partendo dalle caratteristiche che accomunano questi due strumenti possiamo affermare che il rebasing, tramite l'istruzione git rebase, svolge la medesima funzionalità del merging attraverso il comando git merge, consente cioè di includere le modifiche eseguite a carico di un ramo in un altro ramo.

Detto questo, è importante sottolineare che il rebasing e il merging assolvono questo compito in modo differente. Si ipotizzi per esempio di essere coinvolti in un progetto collaborativo e di creare un nuovo ramo da dedicare all'introduzione di una feature addizionale, potrebbe succedere che mentre stiamo lavorando all'implementazione di quest'ultima un altro componente del nostro team esegua degli interventi sul ramo master ed effettui dei commit per confermare tali aggiornamenti.

Come potremmo procedere per fare in modo che i commit a carico del master vengano inclusi anche nel ramo generato per sviluppare la nuova feature? Per risolvere questo problema possiamo ricorrere al merging, che già conosciamo, ma il rebasing ci fornisce un'ulteriore alternativa.

Merging e cronologia dei rami

Se scegliessimo di operare con il merging, potremmo fondere il master nell'altro ramo, chiamato ad esempio "fbk-6", utilizzando le seguenti istruzioni:

$ git checkout fbk-6
$ git merge master

Ritornando all'esempio del nostro progetto "app-html.it", procediamo quindi alla generazione del nuovo ramo:

Figura 1. Generazione del nuovo ramo.

Generazione del nuovo ramo

Per poi procedere all'applicazione di una modifica a carico del master ed effettuare il commit necessario per la conferma dell'aggiornamento:

Figura 2. Modifica del master e commit.

Modifica del master e commit

E concludere con il merging del master da "fbk-6":

Figura 3. Fusione dei rami.

Modifica del master e commit

Una volta spostato il puntatore su "fbk-6" si può quindi procedere con il merging in modo da sincronizzare i commit (merge commit). Con il merging non viene effettuata alcuna modifica ai rami disponibili, ciò rappresenta un vantaggio ma nel caso in cui il master dovesse essere aggiornato di frequente si dovrà ricorrere spesso al merging nel ramo "fbk-6", con il possibile insorgere di problemi a carico della cronologia di quest'ultimo che potrebbe diventare difficilmente comprensibile.

Ricordiamoci infatti che nel caso specifico stiamo partecipando ad un progetto di sviluppo collaborativo in cui sono coinvolti tutti i membri di un team.

Rebasing dei rami

Ora proviamo a risolvere lo stesso problema con il rebasing:

$ git checkout fbk-6
$ git rebase master

Operazione che nel caso del nostro progetto "app-html.it" potrebbe svolgersi in questo modo:

Figura 4. Rebasing dei rami.

Rebasing dei rami

L'istruzione git rebase master sposta il ramo "fbk-6" all'estremità del master (la rappresentazione del suo stato corrente), in questo modo tutti i nuovi commit del master vengono inclusi in esso. Sostanzialmente possiamo affermare che il rebasing, si occupa di riscrivere la cronologia di un progetto, in pratica genera dei nuovi commit per ciascun commit effettuato per il ramo rifondato.

A differenza del merging il rebasing non crea delle sovrapposizioni tra rami, questo significa che la cronologia stessa risulterà più comprensibile anche nel caso in cui vi sia la necessità di incorporare frequentemente i commit di un ramo nell'altro.

Il rebasing offre quindi la possibilità di accedere ad una cronologia più lineare in quanto, come accade invece nel merging, permette di non incorporare nel ramo di destinazione commit non necessari. Quanto detto non significa però che il rebasing rappresenti sempre una soluzione ideale.

I limiti del rebasing

Il rebasing presenta delle controindicazioni che lo rendono uno strumento da adottare con estrema attenzione, a tal proposito è bene ricordarsi di non utilizzarlo su rami pubblici. Nell'esempio precedente abbiamo rifondato il ramo "fbk-6" sul master, ora ipotizziamo di effettuare l'operazione inversa.

In questo caso l'effetto del rebasing è lo spostamento dei commit del master all'estremità dei "fbk-6". Ora però la cronologia del master su cui stiamo lavorando non è più la stessa disponibile per gli altri componenti del team, che hanno invece come riferimento il master originale. Il master ha quindi due cronologie diverse, una per chi ha eseguito il rebasing e l'altra per gli altri sviluppatori, perché il rebasing ha avuto effetto soltanto sul repository di chi lo ha effettuato.

Se si ha anche il solo sospetto che un altro componente del team stia lavorando allo stesso ramo è sempre opportuno evitare il rebasing. Se per un errore di valutazione il rebasing ha portato alla duplicazione del master, la soluzione più adeguata per evitare ulteriori danni è quella di sottoporre i due master risultanti ad un merging. In questo modo però si viene a verificare una situazione in cui la cronologia verrà inquinata dalla presenza di commit riguardanti i medesimi aggiornamenti, cioè quelli applicati inizialmente e quelli ereditati dal ramo rifondato, il tutto a danno della comprensibilità della cronologia.

Ti consigliamo anche