Il comando git merge in Git serve a combinare più sequenze di commit in una cronologia unificata. Nei casi d’uso più frequenti, git merge viene utilizzato per combinare due branch.
Abitualmente, specie per chi utilizza piattaforme come GitHub o GitLab per come server per lo sviluppo condiviso, le operazioni di merge vengono effettuate direttamente dalla piattaforma sul repository remoto nel momento in cui le modifiche a una pull/merge request vengono approvate e incluse nel branch principale.
È comunque utile conoscere i meccanismi base del merge, visto che si tratta di un processo essenziale in Git. In particolare è importante considerare che:
- in Git l’operazione di merge combina sequenze di commit in una singola sequenza di commit unificata
- esistono due modi in cui viene effettuato il merge: Fast Forward e Three Way
- Git è in grado di completare automaticamente il merge se non ci sono conflitti tra le sequenze di commit
Prima di procedere a un merge, è opportuno eseguire alcuni step preparatori per essere sicuri che l’operazione proceda senza problemi, specie se si sta per eseguire localmente il merge di branch remoti:
- individuare i due branch che si vogliono mergiare, quello che riceverà modifiche (per esempio. main) e quello che si vuole unire (per esempio new-feature)
- fare fetch e pull sui tali branch delle rispettive modifiche remote
- fare checkout nella working copy locale del branch che riceverà le modifiche
Si potrà, quindi, far partire il merge tramite il comando git merge <branch-to-be-merged>.
L’effettiva modalità e risultato del merge dipende dallo rispettivo stato dei due branch.
Fast Forward Merge in Git
git checkout -b new-feature main git add <file> git commit -m "Start a feature" git add <file> git commit -m "Finish a feature" git checkout main git merge new-feature
Fast Forward Merge
Un merge fast-forward in Git può verificarsi quando è presente un percorso lineare dall’ HEAD del ramo da unire all’ HEAD del ramo di destinazione. In questo caso, Git non effettua un vero merge, ma semplicemente sposta la HEAD del ramo di destinazione alla HEAD del ramo da unire.
Le due history sono state effettivamente combinate, ma la history del nostro branch new-feature era, per così dire, il normale avanzare della history del branch main.
Three Way Merge in Git
git branch new-feature git add <file> git commit -m "Fix a bug" git checkout new-feature git add <file> git commit -m "Start a feature" git add <file> git commit -m "Finish a feature" git checkout main git merge new-feature
Three Way Merge
Nel caso in cui i branch siano divergenti, Git deve combinare le due history attraverso un three-way merge. In questa modalità viene usato un tipo di commit dedicato, il merge commit per unire insieme le due history.
I commit di merge sono unici rispetto agli altri commit, poiché hanno due commit genitore. Nel creare un commit di merge, Git tenterà di unire automaticamente le cronologie separate. Se Git riscontra che la stessa parte di file è stata cambiata in entrambe le cronologia, non sarà in grado di combinarle automaticamente. Questo scenario è un conflitto di controllo della versione e Git richiederà l’intervento dell’utente per continuare.
Il nome “three way” indica che a Git servono tre commit per capire come realizzare il merge: i due commit HEAD dei due branch e il rispettivo genitore comune.