¿Cómo resolver conflictos de fusión en Git?

¿Hay una buena manera de explicar cómo resolver conflictos de fusión en Git?

Prueba: git mergetool

Abre una GUI que lo guiará a través de cada conflicto y podrá elegir cómo fusionarse. Algunas veces se requiere un poco de edición manual luego, pero por lo general es suficiente por sí mismo. Es mucho mejor que hacer todo a mano ciertamente.

Según el comentario de @JoshGlover:

El command no necesariamente abre una GUI a less que instale uno. Al ejecutar git mergetool para mí, se usó vimdiff . Puede instalar una de las siguientes herramientas para usarlo en su lugar: opendiff , kdiff3 , tkdiff , xxdiff , xxdiff , tortoisemerge , gvimdiff , diffuse , ecmerge , p4merge , araxis , vimdiff , emerge .

Aquí hay un caso de uso probable, desde la parte superior:

Vas a hacer algunos cambios, pero ¡Ups !, no estás actualizado:

 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. 

Así que te actualizas e intentas de nuevo, pero tienes un conflicto:

 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. 

Entonces decides echar un vistazo a los cambios:

 git mergetool 

Oh, yo, oh mi, upstream cambió algunas cosas, pero solo para usar mis cambios … no … sus cambios …

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

Y luego probamos por última vez

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

Ta-da!

Encuentro que las herramientas de combinación rara vez me ayudan a entender el conflicto o la resolución. Por lo general, soy más exitoso mirando los marcadores de conflicto en un editor de text y usando git log como complemento.

Aquí hay algunos consejos:

Consejo uno

Lo mejor que he encontrado es usar el estilo de conflicto de fusión "diff3":

git config merge.conflictstyle diff3

Esto produce marcadores de conflicto como este:

 <<<<<<< 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 sección del medio es lo que parecía el ancestro común. Esto es útil porque puede compararlo con las versiones superior e inferior para tener una mejor idea de lo que se cambió en cada twig, lo que le da una mejor idea de cuál fue el propósito de cada cambio.

Si el conflicto es solo de unas pocas líneas, esto generalmente hace que el conflicto sea muy obvio. (Saber cómo solucionar un conflicto es muy diferente, debes ser consciente de lo que otras personas están trabajando. Si estás confundido, es mejor simplemente llamar a esa persona a tu habitación para que puedan ver lo que buscas a.)

Si el conflicto es más prolongado, cortaré y pegaré cada una de las tres secciones en tres files separados, como "mío", "común" y "de ellos".

Luego puedo ejecutar los siguientes commands para ver los dos trozos de diff que causaron el conflicto:

 diff common mine diff common theirs 

Esto no es lo mismo que usar una herramienta de fusión, ya que una herramienta de fusión también includeá todos los trozos de diff no conflictivos. Encuentro eso ser una distracción.

Consejo dos

Alguien ya lo mencionó, pero comprender la intención detrás de cada obstáculo generalmente es muy útil para entender de dónde vino un conflicto y cómo manejarlo.

 git log --merge -p <name of file> 

Esto muestra todas las confirmaciones que tocaron ese file entre el ancestro común y las dos cabezas que está fusionando. (Por lo tanto, no incluye las confirmaciones que ya existen en ambas twigs antes de la fusión). Esto le ayuda a ignorar los obstáculos que claramente no son un factor en su conflicto actual.

Consejo tres

Verifique sus cambios con herramientas automáticas.

Si tiene testings automatizadas, ejecútelas. Si tienes pelusa , ejecuta eso. Si se trata de un proyecto editable, compárelo antes de comprometerse, etc. En todos los casos, debe realizar algunas testings para asegurarse de que los cambios no hayan roto nada. (Diablos, incluso una fusión sin conflictos puede romper el código de trabajo).

Consejo cuatro

Planea por adelantado; comunicarse con compañeros de trabajo.

Planificar con anticipación y estar al tanto de lo que otros están trabajando puede ayudar a prevenir conflictos de fusión y / o ayudar a resolverlos antes, mientras que los detalles aún están frescos.

Por ejemplo, si sabe que usted y otra persona están trabajando en una refacturación diferente que afectará al mismo set de files, debe hablarse entre sí antes de time y tener una mejor idea de qué tipo de cambios es cada uno de ustedes. fabricación. Puede ahorrar un time y esfuerzo considerables si realiza los cambios planificados en serie en lugar de hacerlo en paralelo.

Para refactorizaciones importantes que atraviesan una gran franja de código, debe considerar seriamente trabajar en serie: todos dejan de trabajar en esa área del código mientras una persona realiza la refactorización completa.

Si no puede trabajar en serie (debido a la presión del time, tal vez), la comunicación sobre los conflictos de fusión esperados al less le ayuda a resolver los problemas más pronto, mientras que los detalles aún están frescos. Por ejemplo, si un compañero de trabajo está realizando una serie disruptiva de confirmaciones en el transcurso de un período de una semana, puede optar por fusionar / volver a establecer la base en esa twig de compañeros de trabajo una o dos veces al día durante esa semana. De esta forma, si encuentra conflictos de fusión / rebase, puede resolverlos más rápidamente que si espera unas pocas semanas para fusionar todo en un solo gran bulto.

Consejo cinco

Si no está seguro de una fusión, no la fuerce.

La fusión puede ser abrumadora, especialmente cuando hay muchos files en conflicto y los marcadores de conflicto cubren cientos de líneas. Muchas veces, al estimar proyectos de software, no incluimos el time suficiente para elementos generales como manejar una fusión irregular, por lo que se siente como un lastre para pasar varias horas diseccionando cada conflicto.

A largo ploop, planear con anticipación y estar al tanto de lo que otros están trabajando son las mejores herramientas para anticipar conflictos de fusión y prepararse para resolverlos correctamente en less time.

  1. Identifica qué files están en conflicto (Git debería decirte esto).

  2. Abra cada file y examine los diffs; Git los demarca. Con suerte, será obvio qué versión de cada bloque conservar. Es posible que deba discutirlo con otros desarrolladores que hayan cometido el código.

  3. Una vez que haya resuelto el conflicto en un file git add the_file .

  4. Una vez que hayas resuelto todos los conflictos, haz git rebase --continue o cualquier command que Git dijo que hicieras cuando lo completaras.

Consulte las respuestas en Stack Overflow question Abortar una fusión en Git , especialmente la respuesta de Charles Bailey que muestra cómo ver las diferentes versiones del file con problemas, por ejemplo,

 # 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 

Los conflictos de combinación ocurren cuando se realizan cambios en un file al mismo time. Aquí está cómo resolverlo.

git CLI

Aquí hay pasos simples que hacer cuando entra en estado conflictivo:

  1. Tenga en count la list de files en conflicto con: git status (en la sección de Unmerged paths ).
  2. Resuelva los conflictos por separado para cada file mediante uno de los siguientes enfoques:

    • Use GUI para resolver los conflictos: git mergetool (la forma más fácil).

    • Para aceptar la versión remota / otra, use: git checkout --theirs path/file . Esto rechazará cualquier cambio local que haya hecho para ese file.

    • Para aceptar local / nuestra versión, use: git checkout --ours path/file

      Sin embargo, debe tener cuidado, ya que los cambios remotos hacen que los conflictos se hagan por alguna razón.

      Relacionado: ¿Cuál es el significado preciso de "nuestro" y "de ellos" en git?

    • Edite los files en conflicto manualmente y busque el bloque de código entre <<<<< / >>>>> luego elija la versión ya sea desde arriba o desde abajo ===== . Ver: cómo se presentan los conflictos .

    • Los conflictos de ruta y nombre de file se pueden resolver con git add / git rm .

  3. Finalmente, revise los files listos para el commit utilizando: git status .

    Si todavía tiene files en Unmerged paths , y resolvió el conflicto manualmente, Unmerged paths Git que lo resolvió mediante: git add path/file .

  4. Si todos los conflictos se resolvieron correctamente, realice los cambios por: git commit -a y presione a control remoto como de costumbre.

Vea también: Resolviendo un conflicto de fusión desde la línea de command en GitHub

DiffMerge

He utilizado con éxito DiffMerge, que puede comparar visualmente y fusionar files en Windows, macOS y Linux / Unix.

Gráficamente puede mostrar los cambios entre 3 files y permite la fusión automática (cuando es seguro hacerlo) y un control total sobre la edición del file resultante.

DiffMerge

Fuente de la image: DiffMerge (captura de pantalla de Linux)

Simplemente descárguelo y ejecute en repos como:

 git mergetool -t diffmerge . 

Mac OS

En macOS puedes instalarlo a través de:

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

Y probablemente (si no se proporciona) necesita el siguiente envoltorio extra simple colocado en su PATH (por ejemplo, /usr/bin ):

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

Luego puede usar los siguientes atajos de keyboard:

  • AltArriba / Abajo para saltar a los cambios anteriores / siguientes.
  • AltIzquierda / Derecha para aceptar el cambio de izquierda a derecha

Alternativamente, puede usar opendiff (parte de Xcode Tools) que le permite combinar dos files o directorys para crear un tercer file o directory.

Si realiza confirmaciones pequeñas frecuentes, comience por mirar los comentarios de confirmación con git log --merge . Luego, git diff te mostrará los conflictos.

Para conflictos que involucran más de unas líneas, es más fácil ver lo que está sucediendo en una herramienta de GUI externa. Me gusta opendiff – Git también admite vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, emerge de la caja y puedes instalar otros: git config merge.tool "your.tool" configurará tu herramienta elegida y luego git mergetool después de una fusión fallida le mostrará las diferencias en el context.

Cada vez que edite un file para resolver un conflicto, git add filename actualizará el índice y su diff ya no lo mostrará. Cuando se manejan todos los conflictos y sus files han sido git add git commit , git commit completará su fusión.

Vea cómo se presentan los conflictos o, en Git, la documentation de Git git merge para comprender qué son los marcadores de conflicto de fusión.

Además, la sección Cómo resolver conflictos explica cómo resolver los conflictos:

Después de ver un conflicto, puedes hacer dos cosas:

  • Decide no fusionar. Las únicas limpiezas que necesita son restablecer el file de índice al compromiso HEAD para invertir 2. y limpiar los cambios de tree de trabajo hechos por 2. y 3 .; git merge --abort se puede usar para esto.

  • Resuelve los conflictos. Git marcará los conflictos en el tree de trabajo. Edite los files en forma y git add al índice. Usa git commit para sellar el trato.

Puede solucionar el conflicto con una serie de herramientas:

  • Usa una herramienta de combinación. git mergetool para lanzar un mergetool gráfico que te ayudará en la fusión.

  • Mira los diffs. git diff mostrará una git diff tres vías, resaltando los cambios de las versiones HEAD y MERGE_HEAD .

  • Mire los diffs de cada twig. git log --merge -p <path> mostrará primero diffs para la versión HEAD y luego la versión MERGE_HEAD .

  • Mira los originales. git show :1:filename muestra el ancestro común, git show :2:filename muestra la versión HEAD , y git show :3:filename muestra la versión MERGE_HEAD .

También puede leer sobre fusionar marcadores de conflicto y cómo resolverlos en la sección del libro Pro Git Conflictos básicos de combinación .

Para los usuarios de Emacs que desean resolver los conflictos de combinación de forma semi-manual:

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

muestra todos los files que requieren resolución de conflicto.

Abra cada uno de esos files uno por uno, o todos a la vez por:

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

Al visitar un búfer que requiera ediciones en Emacs, escriba

 ALT+x vc-resolve-conflicts 

Esto abrirá tres búferes (el mío, el suyo y el búfer de salida). Navega presionando 'n' (siguiente región), 'p' (región de previsión). Presione 'a' y 'b' para copyr la mina o su región en el búfer de salida, respectivamente. Y / o edite el buffer de salida directamente.

Cuando termine: presione 'q'. Emacs le pregunta si desea save este búfer: sí. Después de finalizar un buffer, márquelo como resuelto al ejecutar desde el teriminal:

 git add FILENAME 

Cuando haya terminado con todos los buffers, escriba

 git commit 

para terminar la fusión

Siga los siguientes pasos para solucionar los conflictos de combinación en git:

  1. Comtesting el estado de git : estado de git

  2. Obtén el patchset: git fetch (revisa el parche correcto de tu commit de git)

  3. Pagar una sucursal local (temp1 en mi ejemplo aquí): git checkout -b temp1

  4. Extraiga los contenidos recientes de master: git pull –rebase origen master

  5. Inicie el mergetool y compruebe los conflictos y corríjalos … y compruebe los cambios en la twig remota con su twig actual: git mergetool

  6. Comtesting el estado nuevamente: estado de git

  7. Elimine los files no deseados creados localmente por mergetool, generalmente mergetool crea files adicionales con la extensión * .orig. Elimine ese file, ya que es solo el duplicado y corrija los cambios de forma local y agregue la versión correcta de sus files. git add #your_changed_correct_files

  8. compruebe el estado de nuevo: estado de git

  9. Confirme los cambios en la misma identificación de confirmación (esto evita un nuevo set de parches por separado): git commit –amend

  10. Presione a la twig principal: git push (a su repository git)

Puede corregir los conflictos de fusión de varias maneras, como otros han detallado.

Creo que la verdadera key es saber cómo fluyen los cambios con los repositorys locales y remotos. La key para esto es entender las twigs de seguimiento. He descubierto que pienso en la twig de seguimiento como la "pieza faltante en el medio" entre mi directory local de files y el remoto definido como origen.

Personalmente me he acostumbrado a 2 cosas para ayudar a evitar esto.

En lugar de:

 git add . git commit -m"some msg" 

Lo cual tiene dos inconvenientes:

a) Todos los files nuevos / modificados se agregan y pueden include algunos cambios no deseados.
b) No puede revisar la list de files primero.

Entonces, en cambio, lo hago:

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

De esta forma, usted es más deliberado sobre qué files se agregan y también puede revisar la list y pensar un poco más mientras usa el editor para el post. También encuentro que mejora mis posts de confirmación cuando uso un editor de pantalla completa en lugar de la opción -m .

[Actualización: con el paso del time cambié más a:

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

]

Además (y más relevante para su situación), trato de evitar:

 git pull 

o

 git pull origin master. 

porque pull implica una combinación y si tiene cambios locales que no desea fusionar, puede terminar fácilmente con código combinado y / o conflictos de fusión para el código que no debería haberse fusionado.

En cambio, trato de hacer

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

También puede encontrar esto útil:

git branch, fork, fetch, merge, rebase y clone, ¿cuáles son las diferencias?

simplemente, si sabe bien que los cambios en uno de los repositorys no son importantes y desea resolver todos los cambios a favor del otro, utilice:

 git checkout . --ours 

para resolver los cambios a favor de su repository , o

 git checkout . --theirs 

para resolver cambios a favor del otro o del repository principal .

O bien, tendrá que usar una herramienta de combinación de GUI para recorrer los files uno por uno, digamos que la herramienta de combinación es p4merge , o escriba el nombre que ya haya instalado

 git mergetool -t p4merge 

y después de terminar un file, tendrá que save y cerrar, para que se abra el siguiente

Prima:

Al hablar de pull / fetch / merge en las respuestas anteriores, me gustaría compartir un truco interesante y productivo,

git pull --rebase

Este command anterior es el más útil en mi vida git, lo que me ahorró mucho time.

Antes de empujar su nuevo cambio comprometido al server remoto, pruebe git pull --rebase rather git pull y merge manual y sincronizará automáticamente los últimos cambios del server remoto (con un fetch + merge) y pondrá su último commit local en la parte superior en git Iniciar session. No necesita preocuparse por la extracción manual / fusión.

En caso de conflicto, solo use

 git mergetool git add conflict_file git rebase --continue 

Encuentre los detalles en: http://gitolite.com/git-pull–rebase

O deseo mi versión o la suya en su totalidad, o quiero revisar los cambios individuales y decidir por cada uno de ellos.

Acepta completamente mi versión o la suya :

Aceptar mi versión (local, la nuestra):

 git checkout --ours -- <filename> git add <filename> # marks conflict as resolved git commit -m "merged bla bla" # an "empty" commit 

Acepte su versión (remota, la de ellos):

 git checkout --theirs -- <filename> git add <filename> git commit -m "merged bla bla" 

Si desea hacer para todos los files de conflicto, ejecute:

 git merge --strategy-option ours 

o

 git merge --strategy-option theirs 

Revise todos los cambios y acéptelos individualmente

  1. git mergetool
  2. Revise los cambios y acepte cualquier versión para cada uno de ellos.
  3. git add <filename>
  4. git commit -m "merged bla bla"

mergetool pnetworkingeterminado funciona en command-line . Cómo usar una línea de command mergetool debería ser una pregunta separada.

También puede instalar una herramienta visual para esto, por ejemplo, meld y ejecutar

 git mergetool -t meld 

Abrirá la versión local (nuestra), la versión "base" o "fusionada" (el resultado actual de la fusión) y la versión remota (suya). Guarde la versión fusionada cuando haya terminado, ejecute git mergetool -t meld again hasta que obtenga "No es necesario fusionar los files", luego vaya a los pasos 3 y 4.

La respuesta de CoolAJ86 resume casi todo. En caso de que tenga cambios en ambas twigs en el mismo fragment de código, deberá realizar una fusión manual. Abra el file en conflicto en cualquier editor de text y debería ver la siguiente estructura.

 (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) 

Elija una de las alternativas o una combinación de ambas de forma que desee que sea el código nuevo, mientras elimina los signos de igual y los corchetes angulares.

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

No parece funcionar siempre para mí y generalmente termina mostrando cada confirmación que era diferente entre las dos twigs, esto sucede incluso cuando se usa -- para separar la ruta del command.

Lo que hago para evitar este problema es abrir dos líneas de command y en una ejecución

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

y en el otro

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

Reemplazando $MERGED_IN_BRANCH con la twig que $MERGED_IN_BRANCH y [path] con el file que está en conflicto. Este command registrará todos los commits, en forma de parche, entre ( .. ) dos commits. Si deja un lado vacío como en los commands anteriores, git automáticamente usará HEAD (la twig en la que se está fusionando en este caso).

Esto le permitirá ver qué cometidos entraron en el file en las dos twigs después de que divergieron. Por lo general, hace que sea mucho más fácil resolver conflictos.

A partir del 12 de diciembre de 2016, puede fusionar sucursales y resolver conflictos en github.com

Por lo tanto, si no desea utilizar la command-line o las herramientas de terceros que se ofrecen aquí desde respuestas anteriores , vaya con la herramienta nativa de GitHub.

Esta publicación de blog explica en detalle, pero los conceptos básicos son que al "fusionar" dos twigs a través de la interfaz de usuario, ahora verá una opción de "resolver conflictos" que lo llevará a un editor que le permite lidiar con estos conflictos de combinación.

enter image description here

Siempre sigo los pasos a continuación para evitar conflictos.

  • GIT Checkout Master (Ven a la twig principal)
  • git pull (Actualice su maestro para get el último código)
  • git checkout -b mybranch (Comtesting una nueva twig y comienza a trabajar en esa twig para que tu maestro siempre permanezca en la parte superior del tronco).
  • git add. Y git commit AND git push (en su sucursal local después de los cambios)
  • maestro de pago de git (vuelve a tu maestro)

Ahora puedes hacer lo mismo y mantener tantas sucursales locales que quieras y trabajar simultáneamente, simplemente haciendo un pago por git en tu sucursal cuando sea necesario.

Si desea fusionar de twig (testing) a principal, puede seguir estos pasos:

Paso 1: ve a la sucursal

 git checkout test 

Paso 2: git pull --rebase origin master

Paso 3: si hay algunos conflictos, vaya a estos files para modificarlo.

Paso 4: agregue estos cambios

 git add #your_changes_files 

Paso 5: git rebase --continue

Paso 6: si todavía hay conflicto, vuelva al paso 3 nuevamente. Si no hay conflicto, haz lo siguiente: git push origin +test

Paso 7: y luego no hay conflicto entre testing y maestro. puedes usar combinar directamente.

Los conflictos de combinación pueden ocurrir en diferentes situaciones:

  • Cuando ejecutas "git fetch" y luego "git merge"
  • Cuando ejecuta "git fetch" y luego "git rebase"
  • Cuando se ejecuta "git pull" (que en realidad es igual a una de las condiciones mencionadas anteriormente)
  • Cuando se ejecuta "git stash pop"
  • Cuando aplica parches git (commits que se exportan a files para ser transferidos, por ejemplo, por correo electrónico)

Necesita instalar una herramienta de combinación que sea compatible con Git para resolver los conflictos. Yo personalmente uso KDiff3 y lo encontré agradable y práctico. Puede download su versión de Windows aquí:

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

Por cierto, si instala extensiones de Git, hay una opción en su asistente de installation para instalar Kdiff3.

Luego configura git configs para usar Kdiff como su herramienta de combinación:

 $ 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 

(Recuerde replace la ruta con la ruta real del file Kdiff exe).

Luego, cada vez que te encuentres con un conflicto de fusión, solo necesitas ejecutar este command:

 $git mergetool 

Luego abre Kdiff3 y primero intenta resolver los conflictos de combinación automáticamente. La mayoría de los conflictos se resolverán espontáneamente y deberá arreglar el rest manualmente.

Así es como se ve Kdiff3: enter image description here

Luego, una vez que haya terminado, guarde el file y vaya al siguiente file con conflicto y vuelva a hacer lo mismo hasta que se resuelvan todos los conflictos.

Para comprobar si todo se fusionó correctamente, simplemente ejecute el command mergetool nuevamente, debería get este resultado:

 $git mergetool No files need merging 

Usando paciencia

Me sorprende que nadie más haya hablado sobre la resolución de conflictos usando la paciencia con la estrategia recursiva de fusión. Para grandes conflictos de fusión, el uso de la patience proporcionó buenos resultados. La idea es que trate de unir bloques en lugar de líneas individuales.

Si cambia la sangría de su progtwig, por ejemplo, la estrategia de combinación de git pnetworkingeterminada a veces coincide con llaves simples { que pertenecen a diferentes funciones. Esto se evita con paciencia.

 git merge -s recursive -X patience other-branch 

De la documentation:

 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. 

Comparación con el ancestro común

Si tiene un conflicto de fusión y desea ver lo que otros tenían en mente al modificar su twig, a veces es más fácil comparar su twig directamente con el antecesor común (en lugar de nuestra twig). For that you can use merge-base :

 git diff $(git merge-base <our-branch> <their-branch>) <their-branch> 

Usually, you only want to see the changes for a particular file:

 git diff $(git merge-base <our-branch> <their-branch>) <their-branch> <file> 

There are 3 steps:

  1. Find which files cause conflicts by command
    git status
  1. Check the files, in which you would find the conflicts marked like

    <<<<<<<<head blablabla

  2. Change the way you want it ,then with commands

    git add solved_conflicts_files
    git commit -m 'merge msg'

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


TL; DR

enter image description here


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.

  1. create a new feature branch from target branch
  2. patch in the changes from conflicting feature branch
  3. resolve conflicts in diff tool as you apply patch
  4. commit/review clean pull request
  5. Delete the branch that has a conflict.

This has always been faster and easier for me than using GiT. It is especially beneficial if changes mess up a pull request and your IDE doesn't handle GiT merges very well.

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.

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 <localbranch> git merge origin/<remotebranch> 

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 networking in intelliJ Also git status will show

 Unmerged paths: (use "git add <file>..." 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/<remotebranch> 

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 

git checkout branch1

git fetch origen

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

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.