Durante la risoluzione di un conflitto di merge in Git è particolarmente rilevante capire cosa è successo nelle due diverse versioni e se e come i due diversi contenuti possono essere riconciliati.
Le due versioni potrebbero, infatti, contenere codice che si comporta in maniera molto diversa ed è importante capire cosa si sta approvando prima di procedere.
Un primo suggerimento è quello di configurare il proprio Git per usare lo stile “diff3” per i conflitti di merge.
Se torniamo all’esempio precedente, eseguendo git config merge.conflictstyle diff3 prima di lanciare git merge, i marker aggiunti da Git per evidenziare i contenuti in conflitto cambiano:
$ git config merge.conflictstyle diff3 $ git merge new_branch_to_merge_later $ cat merge.txt <<<<<<< HEAD initial content to edit later content added to previous ||||||| 0a99708 initial content to edit later ======= new content to merge later >>>>>>> merge-me
Rispetto alla versione precedente abbiamo:
- tra ||||||| e ======= il contenuto nel commit genitore comune ai due commit in conflitto
- tra <<<<<<< e ||||||| la versione nel branch “current”
- tra ======= e >>>>>>> la versione nel branch “incoming”
Sempre nell’ottica del capire su cosa si sta mettendo mano, potrebbe risultare anche utile controllare i messaggi di commit dei rispettivi branch tramite git log –merge, magari usando l’opzione -p che mostra anche i diff dei due commit
$ git log --merge -p merge.txt commit 90640eb2ecab9ec63fcad24817a314df344e024c (HEAD -> main) Author: Frank <frank@example.com> Date: Sat Jan 14 23:33:22 2023 +0100 appended content to merge.txt diff --git a/merge.txt b/merge.txt index 3480007..c560b6f 100644 --- a/merge.txt +++ b/merge.txt @@ -1 +1,2 @@ initial content to edit later +content added to previous commit 15416df402028b78858105c84d49a86fee59e2e3 (merge-me) Author: Me <me@example.com> Date: Sat Jan 14 23:31:09 2023 +0100 edited the content for conflict diff --git a/merge.txt b/merge.txt index 3480007..202af08 100644 --- a/merge.txt +++ b/merge.txt @@ -1 +1 @@ -initial content to edit later +new content to merge later
Da non dimenticare, poi, che molti IDE, editor di testo per web developers e applicazioni GUI per Git offrono modalità visive più accattivanti per capire le esatte differenze tra due commit in conflitto.
Modificare file in conflitto con VSCode
Aprendo un file che è in conflitto, l’editor VSCode riconosce ed evidenzia i marker di conflitto e offre varie opzioni per risolvere il conflitto.
Modificare file in conflitto con VSCode
È anche disponibile una speciale vista che permette di avere davanti sia le due versioni “originali”, sia la versione che si sta riscrivendo.
NOTA: è interessante notare come mentre Git usa ours e their , alcune UI di Git hanno optato per l’uso rispettivo di “current” e “incoming”, che abbiamo preso in prestito per questa guida. Non dimenticare che l’azione di merge di due branch ha un “verso”. Da questo punto di vista la nomenclatura current/incoming risulta più esplicita nel caso in cui, per esempio, si sta facendo un merge su main di un branch su cui ci sono commit “nostri” e il conflitto è con commit fatti da altri sviluppatori: in tal caso infatti per Git sarebbero ours i commit di altri già su main e theirs i propri commit sul branch.
Una volta risolto il conflitto, il risultato sarà una nuova versione del file e, in particolare, una nuova versione di quel gruppo di righe e, alla fine del merge, si dovrà controllare che il codice sia ancora corretto e funzionante.
È sempre importante capire, quindi, cosa si sta accettando durante la risoluzione di un conflitto di merge, ma soprattutto è anche importante sapere quando è opportuno interrompere il merge e tornare sui propri passi, magari consultando il collega o i colleghi per capire insieme quale versione delle modifiche sarà alla fine quella che andrà inclusa nel repository