Vai al contenuto
GitTree

Guide Git

Come risolvere i conflitti Git Merge sulla riga di comando e in un editor a tre vie

Come risolvere i conflitti di unione in Git: leggi gli indicatori di conflitto, risolvili con semplici comandi Git o in un editor visivo a tre vie e visualizza i conflitti che si verificano prima dell'unione. Inoltre rerere, interrompendo in modo sicuro e annullando un'unione.

Scritto da KodmoraAggiornato 14 minuti di lettura
GitTree menu del ramo con opzioni di unione, rebase, rebase interattivo, avanzamento veloce e reimpostazione che nominano entrambi i rami

Per risolvere i conflitti di unione in Git, apri ogni file che Git segnala come in conflitto, decidi quale dovrebbe essere il codice tra i marcatori <<<<<<<, ======= e >>>>>>>, elimina i marcatori, metti in stage il file con git add e finisci con git commit (o git merge --continue). Per tornare indietro, invece, esegui git merge --abort. Questa guida attraversa questo ciclo sulla riga di comando, quindi in un editor visivo a tre vie e termina con le abitudini che rendono i conflitti più rari e facili da annullare. Per mettere in pratica le scelte che ti offre un'unione in pausa, un rebase o un cherry-pick, segui la lezione gratuita Continua, salta o interrompi un'operazione attiva.

Gli esempi visivi utilizzano GitTree, il client Git che creiamo per macOS, Windows e Linux. Esegue Git installato sul tuo computer, quindi facendo clic e digitando si ottiene lo stesso risultato; l'GitTree elenco delle funzionalità offre il quadro più ampio.

Che cos'è in realtà un conflitto di unione in Git

Git unisce riga per riga utilizzando tre versioni di ciascun file: base (l'ultimo commit condiviso da entrambi i rami), nostro (il tuo ramo corrente, HEAD) e loro (il ramo in entrata, MERGE_HEAD). Se solo una parte ha cambiato una regione, Git accetta quella modifica. Se entrambe le parti hanno modificato le stesse righe in modo diverso, Git si ferma, scrive entrambe le versioni nel file e lascia a te la decisione.

La stessa cosa può succedere in git pull, git rebase, git cherry-pick, git revert e git stash pop. La correzione è identica; differisce solo il comando finale. git status etichetta ciascun percorso in conflitto:

  • entrambi modificati: entrambi i rami hanno cambiato le stesse righe. Questo è il caso comune.
  • eliminato da noi / eliminato da loro: una parte ha eliminato il file e l'altra lo ha modificato, quindi mantieni il file modificato o confermi l'eliminazione.
  • entrambi aggiunti: ogni ramo ha creato un file diverso nello stesso percorso.

Come risolvere i conflitti di unione sulla riga di comando

1. Trova i file in conflitto

Git elenca i conflitti nel momento in cui l'unione si interrompe e git status conserva l'elenco fino al termine. git diff --name-only --diff-filter=U stampa solo i percorsi non uniti.

$ git merge feature/login
Auto-merging src/auth.ts
CONFLICT (content): Merge conflict in src/auth.ts
Automatic merge failed; fix conflicts and then commit the result.

$ git status
On branch main
You have unmerged paths.

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   src/auth.ts

2. Leggete i segnalini conflitto

Tutto al di fuori dei marcatori si fondeva in modo pulito. Il blocco dopo <<<<<<< HEAD è il tuo ramo corrente, il blocco prima di >>>>>>> feature/login è quello in entrata e la riga ======= li separa.

export const retries = 3;
<<<<<<< HEAD
export const timeout = 45;
=======
export const timeout = 60;
>>>>>>> feature/login
export const debug = false;

Spesso due versioni non bastano per decidere. Imposta lo stile di conflitto zdiff3 di Git una volta e ogni conflitto mostrerà anche la base, dopo una riga |||||||:

$ git config --global merge.conflictStyle zdiff3

<<<<<<< HEAD
export const timeout = 45;
||||||| 556e564
export const timeout = 30;
=======
export const timeout = 60;
>>>>>>> feature/login

Ora puoi vedere che main ha aumentato il timeout da 30 a 45 e il ramo funzionalità a 60: decidi di quale valore ha bisogno il prodotto, non quale ramo vince.

3. Modifica il file e contrassegnalo come risolto

Scrivi il codice che desideri (un lato, l'altro, un mix o qualcosa di nuovo) ed elimina ogni riga di marcatura. Lascia che Git controlli gli avanzi prima di mettere in stage, perché un ======= commesso per sbaglio è una classica build rotta.

$ git diff --check          # lists any leftover conflict markers
$ git add src/auth.ts
$ git commit                # or: git merge --continue

Se la versione dell'intero file di una parte è corretta, prendila direttamente. Per fare in modo che Git preferisca un lato per ogni pezzo in conflitto durante la fusione, avvia invece la fusione con git merge -X ours o git merge -X theirs; i cambiamenti che non sono in conflitto provengono comunque da entrambi i rami.

$ git checkout --ours -- src/auth.ts     # keep the current branch's version
$ git checkout --theirs -- src/auth.ts   # keep the incoming version
$ git add src/auth.ts

4. Terminare l'operazione

Una volta eseguito lo stage di ogni file, continua ciò che è stato interrotto: git commit (o git merge --continue), git rebase --continue, git cherry-pick --continue o git revert --continue. Un rebase può interrompersi nuovamente in un commit successivo; ripetere il ciclo.

Comandi Git che aiutano mentre è aperto un conflitto
ComandoCosa mostra
git diffUna differenza combinata di ciascun file in conflitto rispetto a entrambe le parti
git log --merge -p <path>I commit su ciascun lato che ha toccato il file, con le relative differenze
git show :1:<path>La versione di base del file
git show :2:<path>, git show :3:<path>La tua versione (HEAD) e la versione in arrivo (MERGE_HEAD)
git mergetoolApre lo strumento di unione configurato in Git, un file in conflitto alla volta
Il terminale integrato è ancorato sotto il grafico di commit in GitTree, eseguendo la tua shell accanto alla vista visiva.
Il terminale integrato è ancorato sotto il grafico di commit in GitTree, eseguendo la tua shell accanto alla vista visiva.

Risolvi i conflitti di unione in una GUI: un risolutore di conflitti Git a tre vie

I marcatori vanno bene per uno scontro su due linee. Con una dozzina di conflitti in un file lungo, un risolutore di conflitti della GUI è più veloce e molto più difficile da sbagliare. Un buon strumento di conflitto di unione Git mostra tutte e tre le versioni insieme, ti consente di decidere conflitto per conflitto e si rifiuta di salvare mentre rimangono i marcatori.

In GitTree, un'unione che si interrompe mostra un banner con il numero di conflitti e un elenco dei file in conflitto. Aprine uno e l'editor prende l'intera finestra: i rami corrente e in entrata uno accanto all'altro in alto, ciascuno etichettato con il nome del ramo, e l'Output, il file così come verrà salvato, sotto.

  • Per conflitto: prendi il lato corrente, il lato in entrata, entrambi o nessuno dei due, oppure scegli singole righe da ciascuno.
  • Modifica output manualmente per tutto ciò che i pulsanti non coprono.
  • Mostra Base per vedere l'antenato comune (Git lo scrive quando merge.conflictStyle è diff3 o zdiff3).
  • Annulla scelta per tornare indietro nelle tue decisioni.
  • File eliminati: quando una parte elimina un file che l'altra modifica, conserva il file di quella parte o conferma l'eliminazione.

GitTree non salverà un risultato che contiene ancora linee di contrassegno. Può anche aprire il file nel tuo strumento di unione esterno: VS Code, Cursor, JetBrains IDE, Beyond Compare, Meld, KDiff3, P4Merge, WinMerge, un programma personalizzato o merge.tool di Git. Se lo strumento si chiude senza risolvere il file, il file rimane in conflitto.

Come risolvere un conflitto di unione in GitTree, passo dopo passo

  1. Avvia l'unione

    Apri il menu del ramo sul ramo che desideri importare e uniscilo al ramo corrente oppure trascina un ramo su un altro. Il menu nomina entrambi i rami, quindi la direzione non è mai un'ipotesi.

  2. Leggi l'anteprima del conflitto

    Prima che qualcosa cambi, la finestra di dialogo di unione dice che i rami si uniscono senza conflitti o elenca i file in cui si fermerà. Scegli come registrare l'unione, quindi conferma.

  3. Apri i file in conflitto

    Se l'unione si interrompe, il banner conta i conflitti e l'elenco dei file mostra ciascun file in conflitto. Apri il primo nell'editor a tre vie.

  4. Decidi ogni conflitto

    Prendi il lato corrente, il lato in entrata, entrambi o nessuno dei due, scegli singole righe o modifica l'output. Utilizza Mostra Base per vedere il codice prima che uno dei rami lo modifichi.

  5. Salva e contrassegna il file come risolto

    Scegli Salva e contrassegna come risolto. GitTree scrive e mette in stage il file, quindi passi a quello successivo. Rifiuta finché rimangono le linee dei segnalini di conflitto.

  6. Effettua l'unione

    Una volta risolto ogni file, scegli Commit and Merge (Continue Rebase per un rebase). Hai cambiato idea più tardi? Ripristina il ramo al commit su cui si trovava prima dell'unione dal menu commit; GitTree esegue prima l'istantanea del ripristino, quindi Annulla può annullarlo.

Il grafico dei commit nel tema chiaro di GitTree con un commit di unione selezionato, dove si uniscono due corsie di diramazione.
Il grafico dei commit nel tema chiaro di GitTree con un commit di unione selezionato, dove si uniscono due corsie di diramazione.

Prevedi i conflitti di unione prima di unirli

A partire da Git 2.38, git merge-tree --write-tree esegue un'unione in memoria senza leggere o scrivere l'albero o l'indice di lavoro e senza effettuare un commit. Con --name-only elenca i file che potrebbero entrare in conflitto; lo stato di uscita è 1 in caso di conflitti e 0 quando l'unione sarebbe pulita.

$ git fetch
$ git merge-tree --write-tree --name-only HEAD origin/main
0d708adc4a836d088802870278cb1f3daf06355f
src/auth.ts

Auto-merging src/auth.ts
CONFLICT (content): Merge conflict in src/auth.ts

GitTree esegue questa anteprima per te: la finestra di dialogo di unione mostra il risultato previsto prima della conferma. Dopo ogni recupero, controlla anche il tuo ramo rispetto al suo upstream e al ramo base (principale o master a meno che non ne imposti un altro) e mostra un avviso accanto al nome del ramo, come "Sarebbe in conflitto con main in 2 file". Un secondo suggerimento segnala che i file che stai modificando verranno modificati anche da altri rami recuperati e non uniti.

Entrambi i controlli utilizzano solo ciò che hai già recuperato: nulla viene recuperato, unito o modificato per calcolarli e nulla lascia il tuo computer. Entrambi possono essere disattivati ​​nelle Preferenze.

Riutilizza le risoluzioni dei conflitti con git rerere

Rerere sta per “riutilizzare la risoluzione registrata”. Quando è attivo, Git registra ogni conflitto e il modo in cui lo hai risolto. Quando si ripresenta lo stesso conflitto, ad esempio su un rebase ripetuto di un ramo di lunga durata o su una fusione che riesegui, Git scrive la tua precedente risoluzione nel file.

$ git config --global rerere.enabled true
$ git rerere forget src/auth.ts   # drop a recorded resolution that was wrong

Git lascia il risultato riutilizzato non sottoposto a fase di revisione per la revisione a meno che non sia impostato rerere.autoUpdate. In GitTree, le impostazioni del repository hanno opzioni Riutilizza risoluzioni registrate (rerere) e Stage risoluzioni riutilizzate per le opzioni Git; la visualizzazione del conflitto etichetta una risoluzione riutilizzata e Dimentica risoluzione elimina quella sbagliata.

Come interrompere o annullare un'unione in Git

Per annullare un'unione che si è interrotta a causa di conflitti, esegui git merge --abort. Un rebase, un cherry-pick o un ripristino hanno la propria interruzione:

$ git merge --abort
$ git rebase --abort
$ git cherry-pick --abort
$ git revert --abort

La documentazione di Git avverte che git merge --abort non può sempre ricostruire le modifiche non salvate che avevi all'inizio dell'unione. Esegui il commit o l'archiviazione prima dell'unione e l'interruzione richiede solo il lavoro impegnato da ripristinare.

In GitTree, Abort Merge (o Abort Rebase, Cherry-Pick, Revert) spiega innanzitutto che Git ripristina il ramo, l'indice e la copia di lavoro precedenti all'operazione e annulla le risoluzioni prese finora. GitTree salva tutto ciò che viene eliminato dall'interruzione, messo in scena o meno, negli snapshot di ripristino, quindi Annulla può ripristinarlo.

Come annullare un'unione dopo averla confermata

Cosa fare dipende da se hai effettuato il push dell'unione:

# Not pushed yet, right after the merge:
$ git reset --hard ORIG_HEAD     # also discards uncommitted changes
$ git reset --merge ORIG_HEAD    # keeps uncommitted changes

# Already pushed:
$ git revert -m 1 <merge-commit> # a new commit that reverses it

Un'unione salva il suggerimento precedente del tuo ramo in ORIG_HEAD, quindi reimpostarlo rimuove l'unione, a meno che un successivo ripristino o rebase non abbia spostato ORIG_HEAD. Una volta che gli altri hanno eseguito l'unione, ripristina invece. Annullare un'unione dice a Git che non vorrai mai quelle modifiche: unire nuovamente quel ramo non le riporterà indietro a meno che non annulli il ripristino.

In GitTree, seleziona il primo genitore dell'unione (il commit su cui si trovava prima il tuo ramo) nel grafico e scegli un soft reset, misto o hard reset dal menu commit, ciascuno etichettato con ciò che mantiene. GitTree esegue uno snapshot di 19 tipi di operazioni prima che vengano eseguite, reimpostazioni incluse, in modo che Annulla possa annullare la reimpostazione e la visualizzazione reflog recupera gli stati precedenti. La guida per annullare un ripristino, un rebase o un commit tratta il ripristino in modo approfondito.

Come prevenire la maggior parte dei conflitti di unione

  • Mantieni i rami piccoli e di breve durata. Più due rami sono lunghi e divergono, più linee si toccano.
  • Inserisci spesso il ramo base, non una volta alla fine.
  • Separa la formattazione dalla logica. Concorda un formattatore e riformatta l'intero file da solo.
  • Rigenera i file di blocco invece di unirli manualmente. Prendi uno dei due lati, quindi esegui nuovamente il gestore dei pacchetti.
  • Attiva zdiff3 e rerere una volta. Due comandi, vantaggio duraturo.
  • Esegui il commit o l'archivio prima dell'integrazione, in modo che ogni interruzione e annullamento sia esatta.

Vuoi prima esercitarti su un repository sicuro? La lezione gratuita Unisci rami divergenti e verifica entrambi i genitori nei Tutorial Git illustra una vera unione. Stai ancora valutando il terminale rispetto a una GUI? Git GUI e riga di comando li confronta entrambi in modo onesto.

GitTree ha un piano gratuito che copre tutte le funzionalità Git, repository privati ​​inclusi, e Nour, l'assistente AI, viene fornito con GitTree Pro (vedi prezzi); sono necessari Git 2.39 o più recenti e un account GitTree per accedere. Acquistalo a macOS, Windows o Linux, oppure visualizza tutti i programmi di installazione nella GitTree pagina di download. Il giorno Ubuntu 22.04, aggiorna prima Git. Bloccato in un conflitto ostinato? Chiedi assistenza a GitTree.

Domande frequenti

Cosa causa un conflitto di unione in Git?

Un conflitto di unione si verifica quando due rami modificano le stesse righe di un file in modi diversi o quando un ramo elimina un file modificato dall'altro. Git combina automaticamente le modifiche a diverse parti di un file, ma non può scegliere tra due modifiche alle stesse righe, quindi si ferma e ti chiede di decidere.

Come posso annullare un'unione in Git?

Esegui git merge --abort mentre l'unione viene interrotta in caso di conflitti. Git riporta il ramo, l'indice e l'albero di lavoro allo stato in cui erano prima dell'inizio della fusione. Per un rebase, una selezione o un ripristino, utilizza git rebase --abort, git cherry-pick --abort o git revert --abort. Se l'unione è già terminata come commit, l'interruzione non si applica più: annullala invece con un ripristino o un ripristino.

Cosa significa "Devi modificare tutti i conflitti di unione e poi contrassegnarli come risolti utilizzando git add"?

Git lo stampa quando provi a continuare, solitamente con git rebase --continue, mentre un file conta ancora come in conflitto. Apri ogni file git status elenca sotto percorsi non uniti, rimuovi gli indicatori di conflitto, esegui git add sul file e continua di nuovo. Eseguendo prima git diff --check vengono mostrati tutti gli indicatori che hai mancato.

È sicuro interrompere un'unione in caso di conflitti?

Sì, se prima hai commesso o nascosto il tuo lavoro. git merge --abort ripristina il ramo, l'indice e l'albero di lavoro precedenti all'unione e annulla le tue risoluzioni. Le modifiche non confermate che avevi prima dell'unione potrebbero non tornare esattamente, motivo per cui è importante confermare o archiviare per prime. GitTree crea istantanee di qualunque cosa venga interrotta da un'interruzione, in modo che Annulla possa recuperarla.

Cosa significano il nostro e il loro in un conflitto Git?

In una fusione, "nostro" è il ramo su cui ti trovi (HEAD) e "loro" è il ramo in cui si sta unendo. In un rebase si scambiano: "nostro" è il ramo su cui stai ribasando e "loro" è il tuo commit che viene riprodotto. Ecco perché git checkout --ours sorprende le persone a metà del rebase. GitTree etichetta ciascun lato con il nome e il ruolo del ramo.

Come posso annullare un'unione che ho già confermato?

Se non hai eseguito il push, esegui git reset --hard ORIG_HEAD subito dopo l'unione oppure git reset --merge ORIG_HEAD per mantenere le modifiche non salvate. Se l'unione è già su un ramo condiviso, esegui git revert -m 1 <merge-commit> per invertirla senza riscrivere la cronologia. In GitTree, reimposta il ramo sul primo genitore dell'unione dal menu commit; il ripristino viene eseguito per primo, quindi Annulla può annullarlo se cambi idea.

Qual è lo strumento migliore per risolvere i conflitti di unione Git?

Cerca uno strumento di unione dei conflitti che mostri tre versioni contemporaneamente (la tua parte, la parte in arrivo e la base comune), ti consenta di decidere conflitto per conflitto e non salverà un file con i marcatori rimasti al suo interno. GitTree include un editor a tre vie come questo e può anche passare un file allo strumento di unione che già utilizzi. In ogni caso, attiva zdiff3.

Git potrà risolvere automaticamente lo stesso conflitto la prossima volta?

Sì, con rerere. Esegui git config --global rerere.enabled true e Git registra il modo in cui risolvi ogni conflitto. Quando si ripresenta esattamente lo stesso conflitto, ad esempio durante un rebase ripetuto, Git scrive la tua precedente risoluzione nel file. Puoi ancora rivederlo e metterlo in scena a meno che rerere.autoUpdate non sia attivo. GitTree mostra quando è stata riutilizzata una risoluzione.

Fonti

Le affermazioni su altri prodotti sono state confrontate con le rispettive pagine ufficiali in data 28 ottobre 2026. Cambiano prezzi e caratteristiche; le pagine dei venditori sono la fonte della verità.