Come risolvere i conflitti di fusione in Git

C’è un buon modo per spiegare come risolvere i conflitti di merge in Git?

    Prova: git mergetool

    Apre una GUI che ti guida attraverso ogni conflitto e puoi scegliere come unire. A volte richiede un po ‘di modifica manuale, ma di solito è sufficiente da solo. È molto meglio che fare il tutto a mano certamente.

    Come da commento @JoshGlover:

    Il comando non apre necessariamente una GUI a meno che non ne installi una. L’esecuzione di git mergetool per me ha comportato l’ vimdiff di vimdiff . È ansible installare uno dei seguenti strumenti per utilizzarlo: meld , opendiff , kdiff3 , tkdiff , xxdiff , tortoisemerge , gvimdiff , diffuse , ecmerge , p4merge , vimdiff , vimdiff , emerge .

    Di seguito è riportata la procedura di esempio per utilizzare vimdiff per risolvere i conflitti di unione. Basato su questo link

    Passaggio 1 : esegui i seguenti comandi nel tuo terminale

     git config merge.tool vimdiff git config merge.conflictstyle diff3 git config mergetool.prompt false 

    Questo imposterà vimdiff come strumento di unione predefinito.

    Passaggio 2 : eseguire il comando seguente nel terminale

     git mergetool 

    Passo 3 : vedrai uno schermo Vimdiff nel seguente formato

      +----------------------+ | | | | |LOCAL |BASE |REMOTE | | | | | +----------------------+ | MERGED | | | +----------------------+ 

    Queste 4 viste sono

    LOCALE: questo è il file dal ramo corrente

    BASE – antenato comune, come il file guardava prima di entrambe le modifiche

    REMOTE: file che si sta unendo al ramo

    MERGED – Unisci risultato, questo è ciò che viene salvato nel repository

    Puoi navigare tra queste viste usando ctrl+w . Puoi raggiungere direttamente la vista MERGED usando ctrl+w seguito da j .

    Maggiori informazioni sulla navigazione di vimdiff qui e qui

    Passaggio 4 . È ansible modificare la vista MERGED nel seguente modo

    Se si desidera ottenere modifiche da REMOTE

     :diffg RE 

    Se si desidera ottenere modifiche da BASE

     :diffg BA 

    Se si desidera ottenere modifiche da LOCAL

     :diffg LO 

    Passaggio 5 . Salva, esci, conferma e ripulisci

    :wqa salva e esce da vi

    git commit -m "message"

    git clean Rimuovi i file aggiuntivi (es. * .orig) creati dallo strumento diff.

    Ecco un probabile caso d’uso, dall’alto:

    Stai per apportare alcune modifiche, ma oops, non sei aggiornato:

     git fetch origin git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Updating a030c3a..ee25213 error: Entry 'filename.c' not uptodate. Cannot merge. 

    Quindi ti aggiorni e prova di nuovo, ma hai un conflitto:

     git add filename.c git commit -m "made some wild and crazy changes" git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Auto-merging filename.c CONFLICT (content): Merge conflict in filename.c Automatic merge failed; fix conflicts and then commit the result. 

    Quindi decidi di dare un’occhiata alle modifiche:

     git mergetool 

    Oh mio, oh mio, a monte ho cambiato alcune cose, ma solo per usare i miei cambiamenti … no … i loro cambiamenti …

     git checkout --ours filename.c git checkout --theirs filename.c git add filename.c git commit -m "using theirs" 

    E poi proviamo un’ultima volta

     git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Already up-to-date. 

    Ta-da!

    Trovo che gli strumenti di unione raramente mi aiutano a capire il conflitto o la risoluzione. Di solito riesco a guardare gli indicatori di conflitto in un editor di testo e ad usare git log come supplemento.

    Ecco alcuni suggerimenti:

    Suggerimento uno

    La cosa migliore che ho trovato è usare lo stile di conflitto di unione “diff3”:

    git config merge.conflictstyle diff3

    Questo produce indicatori di conflitto come questo:

     <<<<<<< Changes made on the branch that is being merged into. In most cases, this is the branch that I have currently checked out (ie HEAD). 

    | The common ancestor version. ======= Changes made on the branch that is being merged in. This is often a feature/topic branch. >>>>>>>

    La sezione centrale è ciò che sembrava l’antenato comune. Ciò è utile perché è ansible confrontarlo con le versioni superiore e inferiore per avere un migliore senso di ciò che è stato cambiato su ciascun ramo, cosa che ti dà un’idea migliore per quale fosse lo scopo di ogni cambiamento.

    Se il conflitto è solo di poche righe, questo generalmente rende il conflitto molto ovvio. (Sapere come risolvere un conflitto è molto diverso, devi essere consapevole di ciò su cui stanno lavorando gli altri. Se sei confuso, probabilmente è meglio chiamare quella persona nella tua stanza in modo che possano vedere cosa stai cercando a.)

    Se il conflitto è più lungo, allora taglierò e incollerò ognuna delle tre sezioni in tre file separati, come “mio”, “comune” e “loro”.

    Quindi posso eseguire i seguenti comandi per vedere i due hunk diff che hanno causato il conflitto:

     diff common mine diff common theirs 

    Questo non è lo stesso che usare uno strumento di fusione, poiché uno strumento di unione includerà anche tutti i hunk diff non conflittuali. Trovo che sia fonte di distrazione.

    Suggerimento due

    Qualcuno ha già menzionato questo, ma la comprensione dell’intenzione dietro ogni diff hunk è generalmente molto utile per capire da dove viene un conflitto e come gestirlo.

     git log --merge -p  

    Questo mostra tutti i commit che hanno toccato quel file tra l’antenato comune e le due teste che si stanno unendo. (Quindi non include commit che già esistono in entrambi i rami prima della fusione.) Questo ti aiuta a ignorare i hunk diff che chiaramente non sono un fattore del tuo attuale conflitto.

    Suggerimento tre

    Verifica le tue modifiche con strumenti automatici.

    Se hai test automatici, esegui quelli. Se hai una lanugine , eseguilo . Se si tratta di un progetto costruibile, quindi costruirlo prima di eseguire il commit, ecc. In tutti i casi, è necessario eseguire un po ‘di test per assicurarsi che le modifiche non abbiano infranto nulla. (Diamine, anche una fusione senza conflitti può rompere il codice di lavoro.)

    Suggerimento quattro

    Pianificare in anticipo; comunicare con i colleghi di lavoro.

    Pianificare in anticipo e essere consapevoli di ciò su cui gli altri stanno lavorando può aiutare a prevenire conflitti di fusione e / o aiutare a risolverli prima – mentre i dettagli sono ancora in mente.

    Ad esempio, se sai che tu e un’altra persona lavorate entrambi su refactoring differenti che influenzeranno entrambi lo stesso insieme di file, dovreste parlarci prima del tempo e avere un senso migliore per quali tipi di modifiche ognuno di voi è fabbricazione. Potresti risparmiare tempo e sforzi considerevoli se conduci i cambiamenti pianificati in serie piuttosto che in parallelo.

    Per i principali refactoring che attraversano una grande quantità di codice, dovresti considerare seriamente di lavorare in serie: tutti smettono di lavorare su quell’area del codice mentre una persona esegue il refactoring completo.

    Se non puoi lavorare in serie (a causa della pressione del tempo, forse), comunicare i conflitti di fusione attesi ti aiuta almeno a risolvere i problemi prima, mentre i dettagli sono ancora in mente. Ad esempio, se un collega di lavoro sta effettuando una serie di commit disruptive nel corso di un periodo di una settimana, è ansible scegliere di unire / rebase su quella branca dei collaboratori una o due volte al giorno durante quella settimana. In questo modo, se trovi conflitti di fusione / rebase, puoi risolverli più rapidamente rispetto a quando attendi qualche settimana per unire tutto in un unico grumo.

    Suggerimento cinque

    Se non sei sicuro di un’unione, non forzarla.

    La fusione può sembrare travolgente, soprattutto quando ci sono molti file in conflitto e gli indicatori di conflitto coprono centinaia di righe. Spesso, quando valutiamo progetti software, non includiamo abbastanza tempo per gli articoli generali come la gestione di un’unione nodale, quindi sembra una vera e propria trascina per dedicare diverse ore alla dissezione di ciascun conflitto.

    A lungo termine, pianificare in anticipo e essere consapevoli di ciò su cui gli altri stanno lavorando sono i migliori strumenti per anticipare i conflitti di fusione e prepararsi a risolverli correttamente in meno tempo.

    1. Identifica quali file sono in conflitto (Git dovrebbe dirti questo).

    2. Apri ogni file ed esamina le differenze; Git li demarca. Speriamo che sia ovvio quale versione di ciascun blocco mantenere. Potrebbe essere necessario discuterne con altri sviluppatori che hanno commesso il codice.

    3. Una volta risolto il conflitto in un file git add the_file .

    4. Una volta risolti tutti i conflitti, fai git rebase --continue o qualsiasi comando che Git ha detto di fare quando hai completato.

    Controlla le risposte in Stack Overflow question Aborting a merge in Git , in particolare la risposta di Charles Bailey che mostra come visualizzare le diverse versioni del file con problemi, ad esempio,

     # Common base version of the file. git show :1:some_file.cpp # 'Ours' version of the file. git show :2:some_file.cpp # 'Theirs' version of the file. git show :3:some_file.cpp 

    I conflitti di unione si verificano quando le modifiche vengono apportate a un file contemporaneamente. Ecco come risolverlo.

    git CLI

    Ecco alcuni semplici passaggi su cosa fare quando si entra in uno stato conflittuale:

    1. Unmerged paths l’elenco dei file in conflitto con: git status (nella sezione Unmerged paths ).
    2. Risolvi i conflitti separatamente per ogni file con uno dei seguenti approcci:

      • Usa la GUI per risolvere i conflitti: git mergetool (il modo più semplice).

      • Per accettare remote / altra versione, utilizzare: git checkout --theirs path/file . Questo rifiuterà qualsiasi modifica locale che hai fatto per quel file.

      • Per accettare la versione locale / nostra, utilizzare: git checkout --ours path/file

        Tuttavia devi stare attento, in quanto modifiche remote che i conflitti sono stati fatti per qualche motivo.

        Correlato: qual è il significato preciso di “nostro” e “loro” in git?

      • Modifica manualmente i file in conflitto e cerca il blocco di codice tra < <<<< / >>>>> quindi scegli la versione dall'alto o dal basso ===== . Vedi: come vengono presentati i conflitti .

      • I conflitti tra percorso e nome file possono essere risolti da git add / git rm .

    3. Infine, rivedi i file pronti per il commit usando: git status .

      Se hai ancora dei file sotto Unmerged paths e hai risolto il conflitto manualmente, allora fai sapere a Git che lo hai risolto con: git add path/file .

    4. Se tutti i conflitti sono stati risolti correttamente, commetti le modifiche con: git commit -a e spinge al remoto come al solito.

    Vedi anche: Risoluzione di un conflitto di unione dalla riga di comando su GitHub

    DiffMerge

    Ho usato con successo DiffMerge che può confrontare visivamente e unire file su Windows, macOS e Linux / Unix.

    Può mostrare graficamente le modifiche tra 3 file e consente l'unione automatica (quando è sicuro farlo) e il pieno controllo sulla modifica del file risultante.

    DiffMerge

    Fonte immagine: DiffMerge (schermata di Linux)

    Basta scaricare ed eseguire in pronti contro termine come:

     git mergetool -t diffmerge . 

    Mac OS

    Su macOS puoi installare tramite:

     brew install caskroom/cask/brew-cask brew cask install diffmerge 

    E probabilmente (se non previsto) è necessario il seguente wrapper extra semplice inserito nel PATH (es. /usr/bin ):

     #!/bin/sh DIFFMERGE_PATH=/Applications/DiffMerge.app DIFFMERGE_EXE=${DIFFMERGE_PATH}/Contents/MacOS/DiffMerge exec ${DIFFMERGE_EXE} --nosplash "$@" 

    Quindi puoi utilizzare le seguenti scorciatoie da tastiera:

    • - Alt - Su / Giù per saltare alle modifiche precedenti / successive.
    • - Alt - Sinistra / Destra per accettare il cambiamento da sinistra o destra

    In alternativa puoi usare opendiff (parte di Xcode Tools) che ti permette di unire due file o directory insieme per creare un terzo file o directory.

    Se git log --merge frequenti piccoli commit, inizia guardando i commenti di commit con git log --merge . Quindi git diff ti mostrerà i conflitti.

    Per i conflitti che coinvolgono più di poche righe, è più facile vedere cosa sta succedendo in uno strumento GUI esterno. Mi piace l’opendiff – Git supporta anche vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, emerge out of the box e puoi installarne altri: git config merge.tool "your.tool" lo strumento scelto e quindi git mergetool dopo una fusione fallita ti mostrerà le differenze nel contesto.

    Ogni volta che si modifica un file per risolvere un conflitto, git add filename aggiornerà l’indice e il diff non lo mostrerà più. Quando tutti i conflitti vengono gestiti e i loro file sono stati git add git commit , git commit completerà l’unione.

    Vedi Come sono presentati i conflitti o, in Git, la documentazione di Git git merge per capire cosa sono i merge.

    Inoltre, la sezione Come risolvere i conflitti spiega come risolvere i conflitti:

    Dopo aver visto un conflitto, puoi fare due cose:

    • Decidi di non unire. Le uniche operazioni di pulizia necessarie sono il ripristino del file di indice sul commit HEAD per l’annullamento 2. e la pulizia delle modifiche alla struttura di lavoro effettuate da 2. e 3.; git merge --abort può essere usato per questo.

    • Risolvi i conflitti. Git segnerà i conflitti nell’albero di lavoro. Modifica i file in forma e git add all’indice. Usa git commit per sigillare l’accordo.

    Puoi lavorare attraverso il conflitto con una serie di strumenti:

    • Usa un mergetool. git mergetool per avviare un mergetool grafico che ti consentirà di completare l’unione.

    • Guarda le differenze. git diff mostrerà un git diff a tre vie, evidenziando i cambiamenti da entrambe le versioni HEAD e MERGE_HEAD .

    • Guarda le differenze da ogni ramo. git log --merge -p mostrerà prima diff per la versione HEAD e poi la versione MERGE_HEAD .

    • Guarda gli originali. git show :1:filename mostra l’antenato comune, git show :2:filename mostra la versione HEAD e git show :3:filename mostra la versione MERGE_HEAD .

    Puoi anche leggere informazioni su come unire i contrassegni di conflitto e su come risolverli nella sezione del libro di Git Pro Conflitti di unione di base .

    Per gli utenti di Emacs che desiderano risolvere conflitti di unione in modo semiautomatico:

     git diff --name-status --diff-filter=U 

    mostra tutti i file che richiedono la risoluzione dei conflitti.

    Apri ciascuno di questi file uno alla volta o tutti contemporaneamente:

     emacs $(git diff --name-only --diff-filter=U) 

    Quando si visita un buffer che richiede modifiche in Emacs, digitare

     ALT+x vc-resolve-conflicts 

    Questo aprirà tre buffer (il mio, il loro e il buffer di output). Navigare premendo ‘n’ (area successiva), ‘p’ (area di previsione). Premi “a” e “b” per copiare rispettivamente la mia o la loro regione nel buffer di output. E / o modificare direttamente il buffer di output.

    Al termine: premere “q”. Emacs ti chiede se vuoi salvare questo buffer: sì. Dopo aver terminato un buffer, contrassegnalo come risolto eseguendo dal teriminale:

     git add FILENAME 

    Al termine con tutti i tipi di buffer

     git commit 

    per finire l’unione.

    Si prega di seguire i seguenti passi per risolvere i conflitti di fusione in Git:

    1. Controlla lo stato Git: stato git

    2. Ottieni la patchset: git fetch (controlla la patch corretta dal tuo commit Git)

    3. Acquista un ramo locale (temp1 nel mio esempio qui): git checkout -b temp1

    4. Estrai i contenuti recenti dal master: git pull –rebase master di origine

    5. Avvia il mergetool e controlla i conflitti e risolvili … e controlla le modifiche nel ramo remoto con il tuo ramo corrente: git mergetool

    6. Controlla di nuovo lo stato: git status

    7. Elimina i file indesiderati creati localmente da mergetool, solitamente mergetool crea file extra con estensione * .orig. Per favore cancella quel file dato che è solo il duplicato e correggi le modifiche localmente e aggiungi la versione corretta dei tuoi file. git aggiungi #your_changed_correct_files

    8. Controlla di nuovo lo stato: git status

    9. Applica le modifiche allo stesso ID commit (questo evita un nuovo set di patch separato): git commit –amend

    10. Passa al ramo principale: git push (al tuo repository Git)

    Semplicemente, se sai bene che i cambiamenti in uno dei repository non sono importanti e vuoi risolvere tutte le modifiche a favore dell’altro, usa:

     git checkout . --ours 

    per risolvere i cambiamenti nel favore del tuo repository , o

     git checkout . --theirs 

    per risolvere le modifiche a favore dell’altro o del repository principale .

    Oppure dovrai utilizzare uno strumento di unione GUI per scorrere i file uno alla volta, ad esempio lo strumento di unione è p4merge o scrivere il nome di qualcuno che hai già installato

     git mergetool -t p4merge 

    e dopo aver finito un file, dovrai salvare e chiudere, in modo che si apra il prossimo.

    È ansible risolvere i conflitti di unione in diversi modi, come altri hanno dettagliato.

    Penso che la vera chiave sia sapere come i cambiamenti fluiscono con i repository locali e remoti. La chiave per questo è capire i rami di monitoraggio. Ho scoperto che penso che il ramo di tracciamento sia il “pezzo mancante nel mezzo” tra me, la mia directory di file locali, e il remoto definito come origine.

    Ho personalmente preso l’abitudine di 2 cose per evitare questo.

    Invece di:

     git add . git commit -m"some msg" 

    Che ha due inconvenienti:

    a) Tutti i file nuovi / modificati vengono aggiunti e ciò potrebbe includere alcune modifiche indesiderate.
    b) Non riesci prima a rivedere l’elenco dei file.

    Quindi invece faccio:

     git add file,file2,file3... git commit # Then type the files in the editor and save-quit. 

    In questo modo si è più consapevoli di quali file vengono aggiunti e si può anche consultare l’elenco e pensare un po ‘di più mentre si utilizza l’editor per il messaggio. Trovo anche di migliorare i miei messaggi di commit quando uso un editor a schermo intero piuttosto che l’opzione -m .

    [Aggiornamento: con il passare del tempo sono passato di più a:

     git status # Make sure I know whats going on git add . git commit # Then use the editor 

    ]

    Inoltre (e più pertinente alla tua situazione), cerco di evitare:

     git pull 

    o

     git pull origin master. 

    perché pull implica un’unione e se si hanno modifiche localmente che non si desidera unire si può facilmente finire con un codice unito e / o conflitti di unione per il codice che non avrebbe dovuto essere unito.

    Invece io provo a fare

     git checkout master git fetch git rebase --hard origin/master # or whatever branch I want. 

    Puoi anche trovare utile questo:

    git branch, fork, fetch, merge, rebase e clone, quali sono le differenze?

    Bonus:

    Parlando di pull / fetch / merge nelle risposte di cui sopra, mi piacerebbe condividere un trucco interessante e produttivo,

    git pull --rebase

    Questo comando sopra è il comando più utile nella mia vita git che ha risparmiato un sacco di tempo.

    Prima di git pull --rebase modifica appena effettuata al server remoto, prova git pull --rebase piuttosto git pull e merge manuale e sincronizzerà automaticamente le ultime modifiche del server remoto (con un recupero + unione) e inserirà l’ultimo commit locale nella parte superiore di git log. Non c’è bisogno di preoccuparsi di pull / fusione manuale.

    In caso di conflitto, basta usare

     git mergetool git add conflict_file git rebase --continue 

    Trova i dettagli su: http://gitolite.com/git-pull–rebase

    O voglio la mia o la loro versione per intero, o voglio rivedere le modifiche individuali e decidere per ognuna di esse.

    Accetta completamente la mia versione o la loro :

    Accetta la mia versione (locale, nostra):

     git checkout --ours --  git add  # Marks conflict as resolved git commit -m "merged bla bla" # An "empty" commit 

    Accetta la loro versione (remota, loro):

     git checkout --theirs --  git add  git commit -m "merged bla bla" 

    Se vuoi eseguire tutti i file di conflitto, esegui:

     git merge --strategy-option ours 

    o

     git merge --strategy-option theirs 

    Rivedi tutte le modifiche e accettale individualmente

    1. git mergetool
    2. Rivedi le modifiche e accetta entrambe le versioni per ognuna di esse.
    3. git add
    4. git commit -m "merged bla bla"

    Il mergetool predefinito funziona in riga di comando . Come usare una riga di comando mergetool dovrebbe essere una domanda separata.

    Puoi anche installare questo strumento visivo , ad es. meld ed esecuzione

     git mergetool -t meld 

    Aprirà la versione locale (la nostra), la versione “base” o “unita” (il risultato corrente dell’unione) e la versione remota (la loro). Salva la versione unita quando hai finito, avvia git mergetool -t meld nuovo finché non ottieni “Nessun file deve fondersi”, quindi vai ai passaggi 3 e 4.

    La risposta di CoolAJ86 riassume praticamente tutto. Nel caso in cui si apportino modifiche in entrambi i rami nello stesso pezzo di codice, sarà necessario eseguire un’unione manuale. Apri il file in conflitto in qualsiasi editor di testo e dovresti vedere la seguente struttura.

     (Code not in Conflict) >>>>>>>>>>> (first alternative for conflict starts here) Multiple code lines here =========== (second alternative for conflict starts here) Multiple code lines here too < <<<<<<<<<< (Code not in conflict here) 

    Scegli una delle alternative o una combinazione di entrambi in un modo in cui desideri che il nuovo codice sia, rimuovendo uguali segni e parentesi angolari.

     git commit -a -m "commit message" git push origin master 
     git log --merge -p [[--] path] 

    Non sembra funzionare sempre per me e di solito finisce per mostrare ogni commit che era diverso tra i due rami, questo accade anche quando si usa -- per separare il percorso dal comando.

    Quello che faccio per risolvere questo problema è aprire due righe di comando e in una sola esecuzione

     git log ..$MERGED_IN_BRANCH --pretty=full -p [path] 

    e nell’altro

     git log $MERGED_IN_BRANCH.. --pretty=full -p [path] 

    Sostituendo $MERGED_IN_BRANCH con il ramo che ho unito e [path] con il file che è in conflitto. Questo comando registrerà tutti i commit, in forma di patch, tra ( .. ) due commit. Se lasci un lato vuoto come nei comandi sopra git, userai automaticamente HEAD (il ramo in cui ti stai fondendo in questo caso).

    Ciò ti consentirà di vedere quali sono stati i commit inseriti nel file nei due rami dopo la loro divergenza. Di solito rende molto più facile risolvere i conflitti.

    A partire dal 12 dicembre 2016, puoi unire le filiali e risolvere i conflitti su github.com

    Pertanto, se non si desidera utilizzare la riga di comando o gli strumenti di terze parti offerti qui da risposte precedenti , utilizzare lo strumento nativo di GitHub.

    Questo post sul blog spiega in dettaglio, ma le basi sono che “unendo” due rami tramite l’interfaccia utente, ora vedrai un’opzione “risoluzione dei conflitti” che ti porterà ad un editor che ti consente di gestire questi conflitti di unione.

    inserisci la descrizione dell'immagine qui

    Usando la patience

    Sono sorpreso che nessun altro abbia parlato della risoluzione del conflitto usando la patience con la strategia ricorsiva di fusione. Per un grande conflitto di unione, l’uso della patience fornito buoni risultati per me. L’idea è che cercherà di abbinare i blocchi piuttosto che le singole linee.

    Se modifichi il rientro del tuo programma, ad esempio, la strategia di merge Git di default a volte corrisponde a singole parentesi { che appartiene a funzioni diverse. Questo è evitato con patience :

     git merge -s recursive -X patience other-branch 

    Dalla documentazione:

     With this option, merge-recursive spends a little extra time to avoid mismerges that sometimes occur due to unimportant matching lines (eg, braces from distinct functions). Use this when the branches to be merged have diverged wildly. 

    Confronto con l’antenato comune

    Se si verifica un conflitto di unione e si desidera visualizzare ciò che gli altri avevano in mente durante la modifica del proprio ramo, a volte è più facile confrontare il proprio ramo direttamente con l’antenato comune (anziché il nostro ramo). Per questo puoi usare merge-base :

     git diff $(git merge-base  )  

    Solitamente, vuoi solo vedere le modifiche per un particolare file:

     git diff $(git merge-base  )   

    Ci sono 3 passaggi:

    1. Trova quali file causano conflitti per comando

       git status 
    2. Controlla i file, in cui troverai i conflitti contrassegnati come

       < <<<<<< 
    3. Modificalo nel modo desiderato, quindi esegui il commit con i comandi

       git add solved_conflicts_files git commit -m 'merge msg' 

    I always follow the below steps to avoid conflicts.

    • git checkout master (Come to the master branch)
    • git pull (Update your master to get the latest code)
    • git checkout -b mybranch (Checkout a new a branch and start working on that branch so that your master always remains top of trunk.)
    • git add . AND git commit AND git push (on your local branch after your changes)
    • git checkout master (Come back to your master.)

    Now you can do the same and maintain as many local branches you want and work simultaneous my just doing a git checkout to your branch when ever necessary.

    If you want to merge from branch (test) to master, you can follow these steps:

    Step 1: Go to the branch

     git checkout test 

    Step 2: git pull --rebase origin master

    Step 3: If there are some conflicts, go to these files to modify it.

    Step 4: Add these changes

     git add #your_changes_files 

    Step 5: git rebase --continue

    Step 6: if there is still conflict, go back to step 3 again. If there is no conflict, do following: git push origin +test

    Step 7: And then there is no conflict between test and master. You can use merge directly.

    Merge conflicts could occur in different situations:

    • When running “git fetch” and then “git merge”
    • When running “git fetch” and then “git rebase”
    • When running “git pull” (which is actually equal to one of the above-mentioned conditions)
    • When running “git stash pop”
    • When you’re applying git patches (commits that are exported to files to be transferred, for example, by email)

    You need to install a merge tool which is compatible with Git to resolve the conflicts. I personally use KDiff3, and I’ve found it nice and handy. You can download its Windows version here:

    https://sourceforge.net/projects/kdiff3/files/

    BTW if you install Git Extensions there is an option in its setup wizard to install Kdiff3.

    Then setup git configs to use Kdiff as its mergetool:

     $ git config --global --add merge.tool kdiff3 $ git config --global --add mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe" $ git config --global --add mergetool.kdiff3.trustExitCode false $ git config --global --add diff.guitool kdiff3 $ git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe" $ git config --global --add difftool.kdiff3.trustExitCode false 

    (Remember to replace the path with the actual path of Kdiff exe file.)

    Then every time you come across a merge conflict you just need to run this command:

     $git mergetool 

    Then it opens the Kdiff3, and first tries to resolve the merge conflicts automatically. Most of the conflicts would be resolved spontaneously and you need to fix the rest manually.

    Here’s what Kdiff3 looks like:

    Inserisci qui la descrizione dell'immagine

    Then once you’re done, save the file and it goes to the next file with conflict and you do the same thing again until all the conflicts are resolved.

    To check if everything is merged successfully, just run the mergetool command again, you should get this result:

     $git mergetool No files need merging 

    This answers is to add an alternative for those VIM users like I that prefers to do everything within the editor.


    TL; DR

    inserisci la descrizione dell'immagine qui


    Tpope came up with this great plugin for VIM called fugitive . Once installed you can run :Gstatus to check the files that have conflict and :Gdiff to open Git in a 3 ways merge.

    Once in the 3-ways merge, fugitive will let you get the changes of any of the branches you are merging in the following fashion:

    • :diffget //2 , get changes from original ( HEAD ) branch:
    • :diffget //3 , get changes from merging branch:

    Once you are finished merging the file, type :Gwrite in the merged buffer. Vimcasts released a great video explaining in detail this steps.

    git fetch
    git checkout your branch
    git rebase master

    In this step you will try to fix the conflict using your prefer IDE

    You can follow this link to check ho to fix the conflict in the file
    https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/

    git add
    git rebase –continue
    git commit –amend
    git push origin HEAD:refs/drafts/master (push like a drafts)

    Now every thing is fine and you will find your commit in gerrit

    I hope that this will help every one concerning this issue.

    Try Visual Studio Code for editing if you aren’t already. What it does is after you try merging(and land up in merge conflicts).VS code automatically detects the merge conflicts.

    It can help you very well by showing what are the changes made to the original one and should you accept incoming or

    current change (meaning original one before merging)’?.

    It helped for me and it can work for you too !

    PS: It will work only if you’ve configured git with with your code and Visual Studio Code.

    For those who are using Visual Studio (2015 in my case)

    1. Close your project in VS. Especially in big projects VS tends to freak out when merging using the UI.

    2. Do the merge in command prompt.

      git checkout target_branch

      git merge source_branch

    3. Then open the project in VS and go to Team Explorer -> Branch. Now there is a message that says Merge is pending and conflicting files are listed right below the message.

    4. Click the conflicting file and you will have the option to Merge, Compare, Take Source, Take Target. The merge tool in VS is very easy to use.

    If you are using intelliJ as IDE Try to merge parent to your branch by

     git checkout  git merge origin/ 

    It will show all conflicts like this

    A_MBPro:test anu$ git merge origin/ Auto-merging src/test/java/com/…/TestClass.java CONFLICT (content): Merge conflict in src/test/java/com/…/TestClass.java

    Now note that the file TestClass.java is shown in red in intelliJ Also git status will show

     Unmerged paths: (use "git add ..." to mark resolution) both modified: src/test/java/com/.../TestClass.java 

    Open the file in intelliJ, it will have sections with

      < <<<<<< HEAD public void testMethod() { } ======= public void testMethod() { ... } >>>>>>> origin/ 

    where HEAD is changes on your local branch and origin/ is changes from the remote branch. Here keep the stuff that you need and remove the stuff you don’t need.After that the normal steps should do. That is

      git add TestClass.java git commit -m "commit message" git push 

    I follow the below process.

    The process to fix merge conflict:

    1. First, pull the latest from the destination branch to which you want to merge git pull origin develop

    2. As you get the latest from the destination, now resolve the conflict manually in IDE by deleting those extra characters.

    3. Do a git add to add these edited files to the git queue so that it can be commit and push to the same branch you are working on.

    4. As git add is done, do a git commit to commit the changes.

    5. Now push the changes to your working branch by git push origin HEAD

    This is it and you will see it resolved in your pull request if you are using Bitbucket or GitHub.

    A safer way to resolve conflicts is to use git-mediate (the common solutions suggested here are quite error prone imho).

    See this post for a quick intro on how to use it.

     git checkout branch1 git fetch origin git rebase -p origin/mainbranch 

    If there are merge conflicts, fix them. Then, continue the rebase process by running: git rebase –-continue

    after the fixing you can commit and push your local branch to remote branch

     git push origin branch1