È uscito il Corso Java Completo
Torna al blog

Come risolvere i conflitti in Git senza panico

Cosa sono i conflitti Git, come si leggono i marcatori nel file, la procedura per risolverli passo passo e come ridurne drasticamente la frequenza.

Edoardo Midali

Edoardo Midali

Developer · Content Creator

6 min di lettura

Il primo conflitto in Git è un momento di panico piuttosto universale: il comando fallisce, il file si riempie di simboli strani, e la sensazione è di aver rotto qualcosa di irreparabile. Non è così — un conflitto è semplicemente Git che ti chiede di decidere una cosa che non può decidere lui. In questo articolo trovi come leggerli, come risolverli e come averne molti di meno.

Cos'è un conflitto

Un conflitto si verifica quando due modifiche toccano le stesse righe dello stesso file e Git non può stabilire quale delle due debba prevalere.

Il punto importante: Git risolve da solo la stragrande maggioranza delle unioni. Se tu hai modificato la riga 10 e un collega la riga 200, le combina senza chiederti nulla. Il conflitto arriva solo quando le modifiche si sovrappongono davvero.

E non è un errore. È Git che si rifiuta di indovinare, il che è esattamente il comportamento corretto: nessuno vuole che un sistema decida arbitrariamente quale versione del codice tenere.

Come si presenta

Quando succede, Git modifica il file inserendo dei marcatori:

<<<<<<< HEAD
const timeout = 3000;
=======
const timeout = 5000;
>>>>>>> funzione-login

Si legge così:

  • Tra <<<<<<< HEAD e ======= → la versione del ramo su cui ti trovi
  • Tra ======= e >>>>>>> → la versione del ramo che stai unendo
  • Dopo >>>>>>> → il nome del ramo di provenienza

Il file in questo stato non è codice valido. Se provi a eseguirlo, fallisce — ed è voluto: serve a impedire che il conflitto passi inosservato.

Come si risolve

La procedura, passo per passo.

1. Guarda la situazione.

git status

Ti elenca i file in conflitto sotto "Unmerged paths".

2. Apri ogni file e decidi. Le opzioni sono quattro:

  • Tenere la tua versione
  • Tenere la loro
  • Combinarle
  • Scrivere qualcosa di diverso da entrambe

3. Rimuovi tutti i marcatori. <<<<<<<, =======, >>>>>>> devono sparire. Il file deve restare codice valido e leggibile.

4. Verifica che funzioni. Esegui il codice, lancia i test. È il passaggio che si salta più spesso, ed è quello che conta.

5. Segna come risolto e concludi.

git add file-risolto.js
git commit

Se ti accorgi di aver combinato un pasticcio, puoi sempre annullare tutto e ricominciare:

git merge --abort

Torni allo stato precedente come se non avessi mai iniziato. È la via di fuga da ricordare: nessun conflitto è irreversibile.

Gli strumenti che aiutano

Risolvere i conflitti leggendo i marcatori a mano funziona, ma esistono modi più comodi.

L'editor di codice. VS Code e gli altri editor moderni mostrano il conflitto con un'interfaccia dedicata: pulsanti per accettare l'una, l'altra o entrambe le versioni, e una vista affiancata. Per la maggior parte dei conflitti è il modo più veloce.

Vista a tre pannelli. Gli strumenti dedicati mostrano tre colonne: la tua versione, la loro, e l'antenato comune da cui entrambe derivano. Vedere l'originale è spesso ciò che chiarisce la situazione, perché ti dice cosa ciascuno stava cercando di cambiare.

Attenzione ai pulsanti "accetta tutto". Sono comodi e pericolosi: accettare in blocco una versione senza guardare significa cancellare il lavoro di qualcuno. Va bene solo se hai verificato che quelle modifiche siano davvero da scartare.

Come averne di meno

Qui sta la parte utile: i conflitti si prevengono più facilmente di quanto si risolvano.

Sincronizzati spesso. È la regola numero uno. Un ramo tenuto separato per tre settimane accumula divergenze; uno aggiornato ogni giorno ne accumula poche. La frequenza dei conflitti cresce molto più che proporzionalmente con il tempo di separazione.

Rami di vita breve. Una funzionalità che richiede un mese va spezzata in pezzi integrabili. È anche il motivo per cui molti team preferiscono rami che durano ore o giorni, non settimane.

Commit piccoli e mirati. Un commit che tocca venti file ha più probabilità di scontrarsi di uno che ne tocca due.

Dividetevi il lavoro per area. Due persone sullo stesso file nello stesso giorno è la ricetta del conflitto. È organizzazione, non tecnica.

Concordate la formattazione. Una parte consistente dei conflitti non riguarda la logica ma l'indentazione, le virgolette, i punti e virgola. Un formattatore automatico condiviso elimina un'intera categoria di conflitti — è uno degli interventi con il ritorno più alto per un team.

Comunicate. "Sto rifacendo il modulo pagamenti" detto in chat vale più di qualunque strumento. Vale anche il contrario: proposte di modifica piccole e frequenti riducono i conflitti, come spiego in cos'è una pull request.

Il caso peggiore: i file binari

Su immagini, PDF, documenti di grafica, Git non può combinare nulla: può solo tenere l'uno o l'altro.

git checkout --ours immagine.png    # la tua
git checkout --theirs immagine.png  # la loro

Non c'è via di mezzo. Su questi file l'unica prevenzione è organizzativa: non lavorateci in due contemporaneamente.

Un caso particolare: i conflitti durante un rebase

Se stai facendo un rebase invece di un merge, i comandi cambiano leggermente:

git rebase --continue   # dopo aver risolto
git rebase --abort      # per annullare tutto

E c'è una differenza pratica da conoscere: durante un rebase i conflitti si possono ripresentare a ogni commit, perché ciascuno viene riapplicato singolarmente. Su un ramo lungo può diventare laborioso — è uno dei motivi per cui il merge resta l'opzione più tranquilla, come spiego in merge vs rebase.

Una funzione che aiuta

Vale la pena conoscerla:

git config --global rerere.enabled true

Attiva una funzione che ricorda come hai risolto un certo conflitto e riapplica automaticamente la stessa soluzione se si ripresenta identico. Utile soprattutto su rami lunghi che vengono aggiornati più volte.

In sintesi

Un conflitto non è un errore: è Git che ti chiede di decidere quando due modifiche toccano le stesse righe. La grande maggioranza delle unioni avviene senza il tuo intervento.

I marcatori nel file separano la tua versione (sopra) da quella in arrivo (sotto). Si risolve scegliendo, rimuovendo i marcatori, verificando che il codice funzioni e concludendo con git add e git commit.

Due cose da ricordare sempre: git merge --abort annulla tutto e ti riporta al punto di partenza, e git status ti dice sempre dove sei.

Ma la parte più utile è la prevenzione: sincronizzarsi spesso, rami brevi, commit piccoli e un formattatore condiviso eliminano gran parte dei conflitti prima che si presentino.

Se i comandi non ti sono ancora familiari, il quadro è in comandi Git essenziali.