modulo 03 / lezione 13

Branch e merge

Conflitti di merge: leggere i marker e risolvere

Risolvere conflitti con metodo invece di scegliere a caso 'accept current/incoming'.

60 minGit e controllo versione

Conflitti di merge: leggere i marker e risolvere

Un conflitto non è Git che si rompe. È Git che si ferma perché due linee di storia hanno modificato la stessa zona in modi che non sa combinare automaticamente.

La risoluzione non consiste nel cliccare “accetta corrente” o “accetta incoming” a caso. Consiste nel capire l’intento di entrambe le modifiche e produrre una terza versione corretta.

Perché questa lezione conta

I conflitti sono il punto in cui Git smette di essere un archivio e torna a chiedere giudizio umano. Se non sai leggere i marker, rischi di cancellare lavoro altrui, reintrodurre bug o creare codice che compila ma perde logica.

Saper risolvere conflitti è anche una competenza di comunicazione: spesso il conflitto segnala lavoro sovrapposto nel team.

Obiettivo operativo

Alla fine della lezione devi saper leggere marker, usare diff3, risolvere manualmente, testare e completare o abortire un merge.

I marker

Esempio:

 <<<<<<< HEAD
return validateEmail(input.email)
 =======
return validateLoginEmail(input.email)
 >>>>>>> feat/login-rules

La parte sopra ======= è la versione del branch corrente (HEAD). La parte sotto è la versione che stai integrando.

Non devi scegliere per forza una delle due. Puoi scrivere:

return validateLoginEmail(input.email)

oppure una terza soluzione che conserva entrambe le intenzioni.

Diff3

Config utile:

git config --global merge.conflictstyle diff3

Con diff3, Git mostra anche la base comune:

 <<<<<<< HEAD
versione corrente
 ||||||| base
versione comune prima della divergenza
 =======
versione incoming
 >>>>>>> branch

La base aiuta a capire cosa è cambiato da entrambe le parti.

Flusso di risoluzione

git merge feat/login
# conflitto
git status
git diff

Poi:

  1. apri i file in conflitto;
  2. leggi HEAD, incoming e base;
  3. ricostruisci intento;
  4. modifica il file rimuovendo marker;
  5. esegui test o build mirata;
  6. fai stage dei file risolti;
  7. completa il merge.
git add src/auth.ts
git commit

Se hai sbagliato scenario:

git merge --abort

Non fidarti del bottone

Gli editor offrono pulsanti:

  1. accept current;
  2. accept incoming;
  3. accept both;
  4. compare changes.

Sono utili, ma non sono decisioni tecniche. “Accept both” può duplicare logica. “Current” può cancellare il lavoro del branch integrato. “Incoming” può buttare via fix locali.

Usali solo dopo aver capito.

Conflitti semantici

Non tutti i conflitti hanno marker. Esempio:

  1. un branch rinomina una funzione;
  2. un altro branch aggiunge una chiamata con il vecchio nome;
  3. Git mergea senza conflitto testuale;
  4. il codice rompe a runtime o in compilazione.

Per questo dopo un merge serve testare. La risoluzione non finisce quando spariscono i marker.

Laboratorio guidato

Crea un file:

prezzo = totale * 1.22

Su un branch cambia IVA a 1.20. Su un altro branch estrai una funzione calcolaPrezzo. Fai merge e risolvi il conflitto producendo una versione finale corretta.

Poi ripeti con un conflitto semantico che non produce marker e trova il problema con test o esecuzione.

Output atteso

Un protocollo:

1. git status
2. leggo marker con diff3
3. capisco intento delle due parti
4. compongo una terza versione
5. test/build
6. git add file risolti
7. commit o continue

Errori comuni

Accettare una parte senza capire. È il modo più rapido per cancellare lavoro utile.

Lasciare marker nel file. Il build dovrebbe intercettarlo, ma non sempre.

Non testare dopo il merge. I conflitti semantici non hanno marker.

Risolvere conflitti enormi a fine branch lungo. Integrare spesso riduce la dimensione del problema.

Checklist di verifica

  • so leggere HEAD, base e incoming;
  • so abilitare merge.conflictstyle diff3;
  • so abortire un merge;
  • rimuovo tutti i marker prima dello stage;
  • testo dopo la risoluzione.

Esercizi

Base · facile

Identifica i marker di conflitto in un file dopo un merge fallito e spiega cosa rappresentano.

Soluzione
<<<<<<< HEAD
versione del branch corrente
=======
versione del branch in arrivo
>>>>>>> feature

Git inserisce questi marker dove le due versioni divergono: sopra ======= c’è la tua versione (HEAD), sotto quella del branch che stai unendo. Risolvere significa scegliere/combinare e rimuovere i marker.

Intermedio · medio

Risolvi un conflitto a mano e completa il merge. Spiega i passi dopo aver editato il file.

Soluzione
# 1. apri il file, scegli/combina le due versioni, elimina <<<<<<< ======= >>>>>>>
git add file-in-conflitto.txt   # 2. marca come risolto
git commit                      # 3. completa il merge (messaggio già precompilato)

Dopo aver editato, git add dice a Git che quel file è risolto; quando tutti i conflitti sono in stage, git commit chiude il merge. Finché restano marker o file non aggiunti, il merge resta in sospeso.

Sfida · difficile

Mostra come annullare un merge in conflitto per ripartire, e come usare uno strumento o le strategie --ours/--theirs per casi specifici. Spiega i rischi.

Soluzione
git merge --abort                 # torna allo stato precedente al merge
# oppure, dopo aver ripreso il merge, per un singolo file:
git checkout --ours file.txt      # tieni la versione di HEAD
git checkout --theirs file.txt    # tieni la versione del branch in arrivo
git add file.txt

git merge --abort è la via di fuga sicura: annulla tutto e riporti il repo a prima del merge. --ours/--theirs risolvono un file scegliendo in blocco una delle due versioni: rapido ma rischioso, perché scarti completamente l’altra senza fonderla — vai sicuro solo quando sai che una delle due è giusta per intero.

Collegamenti

  • Modulo: Branch e merge — lezione 13 del corso.
  • I conflitti tornano con rebase nel modulo 4.