Corso
Che cos’è un conflitto di merge in Git?
Il sistema di controllo di versione Git riguarda il lavoro di squadra e il contributo ai progetti. Gli sviluppatori di solito lavorano su branch isolati e, quando hanno finito, fondono le modifiche nel branch principale. Questo tipo di lavoro di squadra è altamente produttivo ed efficace nel trovare bug. A volte più sviluppatori lavorano sulla stessa riga di codice e, quando tentano di unire le modifiche, sorgono conflitti.

Semplice esempio di conflitto in Git
Il diagramma sopra mostra perfettamente come si verifica un tipico conflitto di merge in Git. Il branch principale ha un file contenente il testo “HELLO, WORLD!”. L’utente abid fa il fork del branch principale e cambia il testo in “HELLO, CAT!”. Mentre abid apporta modifiche, anche il branch principale originale viene modificato in “HELLO, DOG!”. Unire questi branch genererà un conflitto di merge e interromperà il processo.
Il compito principale del comando git merge è combinare due branch e risolvere automaticamente i conflitti. Tuttavia, di tanto in tanto emergono conflitti quando due persone hanno modificato la stessa riga di codice o rimosso file critici su cui un altro sviluppatore stava lavorando. Git contrassegnerà queste modifiche e fermerà il processo di merge. In questo caso, il conflitto non è stato risolto automaticamente; lo sviluppatore deve apportare modifiche manualmente o usare strumenti per risolvere il conflitto.
Tipi di merge
Git merge e rebase sono i due modi per integrare i commit dal branch di destinazione a quello sorgente. Inoltre, Git merge esegue un merge fast-forward o no-fast-forward. Se l’head del branch di destinazione esiste nel branch sorgente, per impostazione predefinita il tipo di merge sarà fast-forward; se manca, sarà no-fast-forward. Git rebase è un altro tipo di merge che riordina la cronologia dei commit del branch di destinazione.
Merge fast-forward

Per impostazione predefinita, Git merge usa il fast-forward per integrare i commit mancanti nel branch di destinazione. Ad esempio, viene usato per aggiornare il branch locale da un server remoto tramite il comando pull. Il fast-forward non genera conflitti di merge, poiché Git non lo applicherà se l’head del branch di destinazione manca nel branch sorgente.
Merge no-fast-forward

Un merge no-fast-forward è detto anche three-way o true merge. Crea un nuovo commit su un branch di destinazione integrando le modifiche sia del branch sorgente sia di quello di destinazione. Le modifiche vengono unite dopo l’ultimo commit comune in entrambi i branch. Nel nostro caso, è dopo C. Questo tipo di merge attiverà un conflitto di merge se il branch sorgente è in contrasto con quello di destinazione. Nel diagramma sopra, il commit di merge (X) viene creato integrando il branch sorgente e quello di destinazione, dove K ed E sono i genitori del commit di merge.
Rebase

Git rebase è un po’ diverso dagli altri tipi. Cambia la sequenza della cronologia dei commit del branch di destinazione. Il rebase integra il branch sorgente in modo tale che il branch di destinazione contenga tutte le modifiche dal branch sorgente, seguite da tutti i commit del branch di destinazione dopo l’ultimo commit comune. Nel nostro caso, l’ultimo commit comune è C, mentre D ed E provengono dal branch sorgente. Il commit K* è lo stesso di K con un id di commit diverso. Invece di collegarsi a C, si collegherà a E. Analogamente a un merge no-fast-forward, se ci sono problemi di compatibilità tra branch sorgente e destinazione, Git richiederà di risolvere i conflitti prima di finalizzare il rebase.
Tipi di conflitti di merge in Git
Ci sono due tipi di conflitti di merge in Git: all’avvio e durante il processo di merging - Atlassian. In questa sezione vedremo entrambi i tipi e come risolvere ciascuno scenario.
All’avvio del merge
Git merge fallirà all’avvio se ci sono modifiche nella working directory o nello staging area. Fallisce all’avvio per evitare che le modifiche vengano sovrascritte dai commit in arrivo durante il merge. Ciò avviene per conflitti con modifiche locali, non con altri branch o sviluppatori. Per stabilizzare lo stato locale, puoi usare comandi come git stash, git commit, git checkout o git reset.
Durante il merge
Un errore durante il merge indica un conflitto tra branch sorgente e destinazione in cui più sviluppatori hanno modificato lo stesso file. Se il merge automatico fallisce, Git ti chiederà di risolvere i problemi manualmente. Puoi anche usare strumenti di terze parti per aiutarti a visualizzare e integrare le modifiche.
Comandi per risolvere i conflitti di merge in Git
In questa sezione vedremo vari comandi nativi per visualizzare e risolvere i conflitti di merge in Git.
Comandi comuni
Git status è il comando più usato per mostrare lo stato dei file modificati, dello staging area e dei commit. Durante il merge, viene usato per identificare i file in conflitto.
git status
Git log con l’argomento --merge produce l’elenco dei commit che sono in conflitto con il branch sorgente.
git log --merge
Per impostazione predefinita, l’opzione git diff ti mostra la differenza tra le modifiche non confermate e i commit precedenti. Git diff si usa per confrontare branch, commit e file. È utile per prevenire futuri conflitti di merge.
git diff
Comandi per i fallimenti all’avvio del merge
Checkout si usa per annullare modifiche o passare a un branch nuovo o vecchio.
git checkout
Git reset serve a ripristinare le modifiche nella working directory e nello staging area.
git reset --mixed
Comandi per conflitti durante il merge
L’argomento --abort interrompe il processo di merge e ripristina le modifiche allo stato originale prima dell’avvio del merge.
git merge --abort
Git reset viene solitamente usato durante il merge per riportare i file in conflitto al loro stato originale.
git reset
Risolvi i conflitti deleted-modified
Un conflitto si verifica se hai eliminato il file nel branch corrente e qualcun altro lo ha modificato in un altro branch. In questo caso, puoi aggiungere il file e fare commit,
git add <filename>
oppure puoi rimuovere il file e fare commit.
git rm <filename>
📌 Foglio di riferimento: risoluzione dei conflitti di merge in Git
| Comando | Descrizione | Esempio d’uso |
|---|---|---|
git status |
Mostra i file con conflitti di merge | git status |
git diff |
Mostra le differenze tra commit o branch | git diff HEAD |
git log --merge |
Mostra i commit coinvolti in un conflitto | git log --merge |
git merge --abort |
Annulla un merge e ripristina lo stato precedente | git merge --abort |
git reset --hard HEAD |
Reimposta il branch all’ultimo stato confermato | git reset --hard HEAD |
git checkout -- <filename> |
Scarta le modifiche in un file specifico | git checkout -- README.md |
git mergetool |
Apre lo strumento di merge configurato per risolvere i conflitti | git mergetool |
git add <filename> |
Contrassegna un conflitto come risolto dopo la modifica | git add README.md |
git commit -m "<message>" |
Salva le modifiche risolte dopo un conflitto di merge | git commit -m "Resolved merge conflict" |
git rebase --continue |
Continua un rebase interrotto dopo aver risolto i conflitti | git rebase --continue |
git rm <filename> |
Rimuove un file eliminato in un branch e modificato in un altro | git rm README.md |
git push |
Pusha le modifiche dopo aver risolto i conflitti di merge | git push origin main |
Strumenti di merge visuali
Gli strumenti di merge sono tool visuali intuitivi per identificare e risolvere tutti i tipi di conflitti di merge. Alcuni supportano funzionalità aggiuntive come confronto delle modifiche, operazioni Git e gestione di progetti e repository. Esistono due tipi di strumenti di merge per Git: solo terminale e basati su GUI. Quelli da terminale si aprono in PowerShell o Bash, mentre quelli GUI si aprono in un ambiente a finestre.
Per controllare l’elenco degli strumenti installati e validi, usa:
git mergetool --tool-help
L’elenco comprende tutti gli strumenti validi che possono essere installati e integrati con i comandi git.
Per esempio, abbiamo vim e nvim installati per impostazione predefinita e, se vuoi vedere la differenza tra un file non confermato e un commit precedente, digita:
git difftool --tool=vimdiff3
Lo strumento vimdiff3 evidenzia le modifiche e ti consente di confrontare i commit all’interno del terminale.

Differenza tra due versioni dello stesso file in vimdiff3
Meld
Meld è uno strumento gratuito e open source che porta la risoluzione dei conflitti di merge a un altro livello. Per integrarlo con Git, devi prima scaricare e installare il setup dal sito ufficiale. Poi aggiungilo alla configurazione globale, così Git avvierà Meld per impostazione predefinita per risolvere i conflitti.
I comandi di configurazione seguenti si applicano solo agli utenti Windows. L’unica modifica necessaria su Mac o Linux è aggiornare il percorso dell’eseguibile di Meld.
git config --global merge.tool meld
git config --global mergetool.meld.path "C:/Program Files (x86)/Meld/Meld.exe"
git config --global diff.tool meld
git config --global difftool.meld.path "C:/Program Files (x86)/Meld/Meld.exe"
Dopo aver impostato i valori predefiniti, puoi digitare git difftool nella directory locale Git per avviare la versione Windows di Meld, oppure git mergetool per risolvere i conflitti di merge come mostrato di seguito.

Risoluzione di un conflitto di merge con Meld
VSCode
VSCode offre il modo migliore e più popolare per risolvere i conflitti di merge. Quando Git non riesce a unire automaticamente i file, VSCode evidenzia il codice in conflitto e ti offre quattro opzioni: accetta le modifiche correnti, accetta le modifiche in arrivo, accetta entrambe le modifiche e confronta le modifiche. Puoi usare queste opzioni per ripulire il file e risolvere tutti i problemi in sospeso.

Risoluzione di un conflitto di merge con VSCode
Se cerchi una soluzione completa per le tue operazioni Git, prova GitKraken. Include un client gratuito, un’estensione per VSCode e fornisce uno strumento integrato per risolvere i conflitti di merge.
Come risolvere un conflitto di merge in Git
In questa sezione vedremo come creare un conflitto di merge in Git e poi risolverlo. Il tutorial è diviso in due parti. Nella prima impareremo a risolvere i conflitti di Git in locale; la seconda riguarda la risoluzione dei conflitti con un server remoto (GitHub).
Conflitto di merge locale
Creare conflitti di merge ci aiuterà a capire come nascono questi problemi. Potremo poi usare modi creativi per risolverli o persino prevenirli in futuro.
Ora creeremo un repository Git con un singolo file e faremo il primo commit per iniziare.
- Crea una cartella chiamata datacamp.
- Entra nella cartella datacamp.
- Inizializza Git.
- Crea un file
README.mdcon il titolo indicato. - Fai stage e commit delle modifiche al file.
mkdir datacamp
cd datacamp
git init
echo "# How to Resolve Git Merge Conflict" > README.md
git add README.md
git commit -m "first commit"
>>> [main (root-commit) 8199ea2] first commit
>>> 1 file changed, 1 insertion(+)
>>> create mode 100644 README.md
Successivamente, creeremo un nuovo branch readme e cambieremo il titolo da “..Git Merge..” a “..Git..”. Aggiungi il file e crea il commit usando l’argomento -am.
git checkout -b readme
echo "# How to Resolve Git Conflict" > README.md
git commit -am "new branch conflict added"
>>> [readme 155f694] new branch conflict added
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
Torna al branch main e aggiungi una nuova riga al file README.md usando >>. Salvando le modifiche e creando i commit, abbiamo generato con successo un conflitto tra due versioni dello stesso file.
git checkout main
echo "New change in base branch" >> README.md
git commit -am " a line added to base branch Readme file"
>>> [main f1f1874] a line added to base branch Readme file
>>> 1 file changed, 1 insertion(+)
Come possiamo vedere, durante il merge del branch readme, Git ha mostrato un messaggio che indica che il merge automatico è fallito e che dobbiamo apportare modifiche manualmente e poi fare commit del risultato.
git merge readme
>>> Auto-merging README.md
>>> CONFLICT (content): Merge conflict in README.md
>>> Automatic merge failed; fix conflicts and then commit the result.
Risolviamo il problema manualmente aprendo e modificando il file in Notepad. L’immagine qui sotto mostra la freccia con HEAD, un separatore e una freccia in direzione opposta con readme. La parte HEAD mostra le modifiche esistenti nel branch main, mentre readme è il branch che vogliamo unire, con un’intestazione diversa.
Risoluzione manuale di un conflitto di merge
Per risolvere il problema, rimuoveremo la parte del branch readme, le frecce e il separatore. La versione finale del file dovrebbe essere pulita, come mostrato sotto.

Conflitto risolto
Dopo aver aggiunto il file e creato un commit, il conflitto di merge sarà risolto. È il modo più comune e semplice per risolvere i problemi. Puoi anche usare un IDE per velocizzare la risoluzione.
git commit -am "conflict resolved in file README.md"
>>> [main 9994a29] conflict resolved in file README.md
Conflitto di merge remoto
Per creare e risolvere conflitti di merge remoti, dobbiamo creare un nuovo repository su GitHub.

Creazione di un nuovo repository su GitHub
Poi aggiungi il nome del remoto (origin) con l’indirizzo del repository e pusha tutte le modifiche dal repository locale al branch main remoto usando upstream.
git remote add origin https://github.com/kingabzpro/DataCamp-Git-Merge-Guide.git
git push --set-upstream origin main
>>> Enumerating objects: 12, done.
>>> Counting objects: 100% (12/12), done.
>>> Delta compression using up to 4 threads
>>> Compressing objects: 100% (6/6), done.
>>> Writing objects: 100% (12/12), 998 bytes | 499.00 KiB/s, done.
>>> Total 12 (delta 2), reused 0 (delta 0), pack-reused 0
>>> remote: Resolving deltas: 100% (2/2), done.
>>> To https://github.com/kingabzpro/DataCamp-Git-Merge-Guide.git
>>> * [new branch] main -> main
>>> branch 'main' set up to track 'origin/main'.
Per creare un conflitto, dobbiamo apportare modifiche al file README.md sia sul remoto sia in locale. Puoi usare l’editor di file di GitHub per cambiare “..Git merge..” in “..Sit-Merge..” e poi fare commit delle modifiche.

Modifica nell’editor di GitHub
Poi, nel repository locale, modifica il file README.md per aggiungere solo un titolo semplice e fai commit delle modifiche.
echo "# How to Resolve Merge Conflicts in Git Tutorial" > README.md
git commit -am "local branch changes in README.md"
>>> [main c677a13] local branch changes in README.md
>>> 1 file changed, 1 insertion(+), 4 deletions(-)
Infine, pusha le modifiche sul server remoto. Nota che Git ha segnalato un errore con suggerimenti su come eliminarlo.
git push
>>> To https://github.com/kingabzpro/DataCamp-Git-Merge-Guide.git
>>> ! [rejected] main -> main (fetch first)
>>> error: failed to push some refs to 'https://github.com/kingabzpro/DataCamp-Git-Merge-Guide.git'
>>> hint: Updates were rejected because the remote contains work that you do
>>> hint: not have locally. This is usually caused by another repository pushing
>>> hint: to the same ref. You may want to first integrate the remote changes
>>> hint: (e.g., 'git pull ...') before pushing again.
>>> hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Seguiamo il suggerimento più semplice, ovvero fare il pull dal server remoto prima di pusciare.
Il pull del file è fallito a causa di un conflitto di merge nel file README.md. Potremmo risolverlo manualmente con Notepad, ma stavolta useremo uno strumento visuale per assisterci in questo processo.
git pull
>>> remote: Enumerating objects: 5, done.
>>> remote: Counting objects: 100% (5/5), done.
>>> remote: Compressing objects: 100% (2/2), done.
>>> remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
>>> Unpacking objects: 100% (3/3), 681 bytes | 75.00 KiB/s, done.
>>> From https://github.com/kingabzpro/DataCamp-Git-Merge-Guide
>>> aaf149d..49b7d14 main -> origin/main
>>> Auto-merging README.md
>>> CONFLICT (content): Merge conflict in README.md
>>> Automatic merge failed; fix conflicts and then commit the result.
Lo strumento di merge Meld identificherà i file in conflitto e li mostrerà nell’applicazione GUI di Meld.
git mergetool
>>> Merging:
>>> README.md
>>> Normal merge conflict for 'README.md':
>>> {local}: modified file
>>> {remote}: modified file
Ci sono tre colonne: README_LOCAL_473.md, README.md e README_LOCAL_473.md. Se ritieni valide le modifiche remote, fai clic sulla freccia nera nella colonna remota; se vuoi mantenere le modifiche locali, fai clic sulla freccia nera nella colonna locale. È semplice così.

Conflitto risolto con lo strumento di merge Meld
Dopo aver apportato le modifiche, salva il file e fai commit. Come puoi vedere, il push di un file su un server remoto non genera più l’errore di conflitto di merge.
git commit -am "remote main branch conflict resolved"
git push
>>> Enumerating objects: 16, done.
>>> Counting objects: 100% (16/16), done.
>>> Delta compression using up to 4 threads
>>> Compressing objects: 100% (6/6), done.
>>> Writing objects: 100% (10/10), 1.08 KiB | 550.00 KiB/s, done.
>>> Total 10 (delta 2), reused 0 (delta 0), pack-reused 0
>>> remote: Resolving deltas: 100% (2/2), completed with 1 local object.
>>> To https://github.com/kingabzpro/DataCamp-Git-Merge-Guide.git
>>> 49b7d14..8f5c3aa main -> main
Abbiamo risolto con successo i conflitti di merge sia locali che remoti. Questi conflitti vengono gestiti quotidianamente da data scientist e machine learning engineer. Per migliorare le tue competenze nelle operazioni Git, segui il corso Introduction to Git.
Conclusione
Risolvere i conflitti di merge in Git è un compito complesso e ad alto rischio, perché puoi compromettere il software unendo codice difettoso. Gli strumenti di merge offrono un ambiente intuitivo e più sicuro per individuare e risolvere i conflitti di merge. In questo tutorial abbiamo visto perché si verificano i conflitti in Git e come risolverli. Abbiamo anche trattato vari tipi di merge e di conflitto, comandi Git utili e strumenti visuali. Nella sezione finale, abbiamo creato un conflitto di merge e lo abbiamo risolto in un repository locale e uno remoto.
Se sei alle prime armi con Git e vuoi capire come funziona, leggi: Intro to Git and GitHub Tutorial.
In quanto data scientist certificato, sono appassionato di sfruttare tecnologie all’avanguardia per creare applicazioni di machine learning innovative. Con una solida esperienza in riconoscimento vocale, analisi e reportistica dei dati, MLOps, AI conversazionale e NLP, ho affinato le mie competenze nello sviluppo di sistemi intelligenti in grado di avere un impatto concreto. Oltre alla mia expertise tecnica, sono anche un comunicatore efficace, con il talento di rendere chiari e sintetici concetti complessi. Di conseguenza, sono diventato un blogger molto seguito in ambito data science, condividendo idee ed esperienze con una community in crescita di professionisti dei dati. Attualmente mi concentro sulla creazione e sull’editing di contenuti, lavorando con large language model per sviluppare contenuti potenti e coinvolgenti che possano aiutare aziende e singoli a valorizzare al meglio i propri dati.
FAQs
Quali sono le migliori pratiche per evitare conflitti di merge in Git?
Per ridurre il rischio di conflitti:
- Esegui sempre il pull delle ultime modifiche (
git pull origin main) prima di iniziare nuovo lavoro. - Comunica con il team per evitare di lavorare sulle stesse righe di codice.
- Fai commit piccoli e frequenti invece di grandi e complessi.
- Usa feature branch invece di fare commit direttamente su
main. - Esegui
git diffprima del merge per individuare in anticipo potenziali conflitti.
Posso risolvere i conflitti di merge senza terminale?
Sì! Molti tool Git basati su GUI semplificano la risoluzione dei conflitti:
- VS Code: evidenzia i conflitti con le opzioni "Accept Incoming" e "Accept Current".
- GitKraken: offre un’interfaccia visuale per risolvere i conflitti in modo interattivo.
- Meld / Beyond Compare: strumenti di merge che aiutano a confrontare e risolvere visivamente le differenze. Esegui
git mergetoolper usare uno strumento visuale configurato.
Perché continuo a ottenere conflitti di merge anche dopo averli risolti?
Possibili motivi includono:
- Hai dimenticato di mettere in stage (
git add) e fare commit (git commit -m "Resolved conflict") dei file risolti. - Un altro collega ha pushato nuove modifiche in conflitto dopo che avevi risolto le tue. Prova
git pull --rebase. - Non hai pushato le modifiche risolte prima di fare di nuovo merge. Esegui sempre
git pushdopo aver risolto i conflitti.
Cosa devo fare se annullo accidentalmente un merge (git merge --abort)?
Se hai annullato un merge ma vuoi riprovare, puoi:
- ri-eseguire il comando di merge (
git merge <branch-name>). - Usare
git reflogper controllare lo stato precedente all’abort e ripristinarlo se necessario.
Come posso annullare un errore durante la risoluzione di un conflitto di merge?
Se hai commesso un errore nella risoluzione del conflitto:
- Esegui
git reset --hard HEADper scartare tutte le modifiche e ricominciare. - Usa
git checkout -- <filename>per ripristinare file specifici al loro stato originale. - Se hai già fatto commit dell’errore, usa
git revert <commit-hash>per creare un nuovo commit che annulla le modifiche.
Come risolvo un conflitto di merge in file binari?
Git non può unire automaticamente i file binari (ad es. immagini, PDF). Per risolvere:
- Scegli manualmente quale versione mantenere e sostituisci il file.
- Usa
git checkout --theirs <filename>ogit checkout --ours <filename>per tenere una versione. - Fai commit del file risolto (
git add <filename> && git commit -m "Resolved binary file conflict").
Qual è la differenza tra git merge --abort e git reset --merge?
git merge --abort: annulla in modo sicuro un merge e riporta il branch allo stato precedente al merge.git reset --merge: simile, ma mantiene i file in stage e può essere più utile se vuoi conservare alcune modifiche.
Come risolvo un conflitto di merge quando faccio push su GitHub?
Se git push fallisce con un errore di conflitto di merge, prova quanto segue:
- Fai pull delle ultime modifiche:
git pull origin main --rebase - Risolvi manualmente i conflitti nel tuo branch locale.
- Metti in stage e fai commit dei file risolti:
git add <conflicted-file>
git commit -m "Resolved merge conflict"
- Fai di nuovo push:
git push origin main
Cos’è un conflitto di rebase e come lo risolvo?
Un conflitto di rebase si verifica quando esegui git rebase <branch> e le modifiche non possono essere applicate pulitamente. Per risolvere:
- Risolvi i conflitti manualmente, poi esegui
git rebase --continue. - Se vuoi annullare il rebase, usa
git rebase --abort. - Usa
git rebase --skipse vuoi ignorare il commit in conflitto.
Posso unire branch senza conflitti usando le impostazioni di Git?
Git ha una strategia di auto-merge che a volte aiuta:
- Usa
git merge -X theirs <branch>per accettare sempre le modifiche dell’altro branch. - Usa
git merge -X ours <branch>per mantenere sempre le modifiche del tuo branch. Tuttavia, non è infallibile e va usato con cautela.


