Skip to content

Modulo 07 — Merging

I branch creano contesti isolati, ma prima o poi le modifiche di un branch vanno incorporate in un altro. Il comando è git merge.

Due concetti chiave per non confondersi:

  1. Si mergiano branch, non commit specifici.
  2. Il merge avviene SEMPRE nel branch corrente (quello puntato da HEAD).

Per portare le modifiche di bugfix dentro master:

Terminal window
git switch master # 1. vai sul branch "ricevente"
git merge bugfix # 2. mergia il branch sorgente nel corrente

Se master non ha nuovi commit rispetto al punto in cui bugfix si è staccato, Git non crea nulla: avanza semplicemente il puntatore di master fino all’ultimo commit di bugfix. I due branch finiscono per puntare allo stesso commit — finché non divergeranno di nuovo. Questo si chiama fast-forward: master “rincorre” i commit di bugfix.

Se invece entrambi i branch hanno nuovi commit (es. un collega ha mergiato una feature su master mentre tu lavoravi sul tuo branch), il fast-forward non è possibile: Git crea un dedicato merge commit — un commit che ha due genitori e fonde le due linee. Ti verrà chiesto un messaggio.

Due branch divergenti: il fast-forward non è possibile Entrambi i branch hanno commit propri rispetto all’antenato comune: serve un merge vero e proprio.

Il merge commit con due genitori Il risultato: un commit unico che unisce le due linee, con due genitori.

A seconda delle modifiche, Git può non riuscire a mergiare automaticamente: nascono conflitti. Il terminale segnala:

CONFLICT (content): Merge conflict in blah.txt
Automatic merge failed; fix conflicts and then commit the result.

E i file coinvolti vengono modificati con i marker di conflitto:

<<<<<<< HEAD
I have 2 cats
I also have chickens
=======
I used to have a dog :(
>>>>>>> bug-fix
  • Tra <<<<<<< HEAD e =======: il contenuto del branch corrente (quello che riceve il merge).
  • Tra ======= e >>>>>>>: il contenuto del branch sorgente.
  1. Apri i file con conflitti.
  2. Modifica i file decidendo cosa tenere in ogni conflitto (contenuto di un branch, o entrambi).
  3. Rimuovi i marker di conflitto.
  4. git add dei file risolti e poi commit per concludere il merge.

A merge concluso, il branch sorgente può essere eliminato (git branch -d): i suoi commit vivono ormai nella history del branch ricevente.


Immagini: documentazione ufficiale di Git (git-scm.com, dal libro Pro Git di Scott Chacon), licenza CC BY-NC-SA 3.0.