Cómo resolver conflictos de fusión en git

¿Hay una buena manera de explicar cómo resolver conflictos de combinación en git?

4274
02 окт. Set de spoike 02 oct. 2008-10-02 14:31 '08 a las 2:31 pm 2008-10-02 14:31
@ 37 respuestas
  • 1
  • 2

Prueba: git mergetool

Abre la interfaz gráfica que se ejecuta a través de cada conflicto, y puede elegir cómo combinar. A veces esto requiere un poco de edición manual después, pero por lo general es suficiente por sí mismo. Esto es mucho mejor que hacer todo manualmente.

Según el comentario de @JoshGlover:

El comando no necesariamente abre la GUI si no la instala. Ejecutar git mergetool para mí llevó al uso de vimdiff . Puede instalar una de las siguientes herramientas para usarla: opendiff , kdiff3 , tkdiff , xxdiff , xxdiff , tortoisemerge , gvimdiff , diffuse , ecmerge , p4merge , araxis , vimdiff , emerge .

A continuación se muestra un ejemplo del procedimiento para usar vimdiff para resolver conflictos de combinación. Por este enlace

Paso 1 : Ejecuta los siguientes comandos en tu terminal

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

Esto establecerá vimdiff como la herramienta de combinación predeterminada.

Paso 2 : Ejecuta el siguiente comando en el terminal

 git mergetool 

Paso 3 : Verás una pantalla vimdiff en el siguiente formato.

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

Estos 4 tipos

LOCAL es el archivo de la rama actual.

BASE: un ancestro común, cómo se veía el archivo antes de ambos cambios

REMOTO: un archivo que fusionas en tu rama

MERGED - el resultado de la fusión, esto es lo que se almacena en el repositorio.

Puede navegar entre estas vistas usando ctrl+w Puede ir directamente a la vista MERGED usando ctrl+w y j .

Más información sobre la navegación vimdiff aquí y aquí.

Paso 4 Puedes editar MERGED de la siguiente manera.

Si quieres recibir cambios desde REMOTO

 :diffg RE 

Si quieres recibir cambios de BASE

 :diffg BA 

Si quieres recibir cambios de LOCAL

 :diffg LO 

Paso 5 Guardar, salir, bloquear y borrar

:wqa guardar y salir vi

git commit -m "message"

git clean Elimine los archivos innecesarios (por ejemplo, * .orig) creados por la herramienta diff.

2535
02 окт. respuesta es dada por Peter Burns 02 oct. 2008-10-02 20:50 '08 a las 8:50 pm 2008-10-02 20:50

Aquí es un probable precedente, desde arriba:

Vas a hacer algunos cambios, pero desafortunadamente, no sabes:

 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. 

Entonces, 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. 

Así que decidiste echar un vistazo a los cambios:

border=0
 git mergetool 

Oh, yo, oh, mi upstream ha cambiado 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 intentamos la última vez.

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

¡Ta-da!

1625
04 авг. La respuesta la da CoolAJ86 04 ago. 2010-08-04 20:04 '10 a las 8:04 pm 2010-08-04 20:04

Encuentro que las herramientas de combinación rara vez me ayudan a entender conflictos o soluciones. Por lo general, observo con más éxito los marcadores de conflicto en un editor de texto y uso git log como complemento.

Aquí hay algunos consejos:

Consejo uno

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

git config merge.conflictstyle diff3

Crea 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 parte media es cómo se veía el antepasado común. Esto es útil porque puede compararlo con las versiones superior e inferior para comprender mejor lo que se ha cambiado en cada rama, lo que le da una mejor idea de cuál es el propósito de cada cambio.

Si el conflicto consiste solo en unas pocas líneas, esto, como regla, hace que el conflicto sea muy obvio. (Saber cómo solucionar un conflicto es muy diferente: necesita saber en qué están trabajando otras personas. Si está confundido, es mejor llamar a esta persona en su habitación para que puedan ver lo que está buscando).

Si el conflicto es más largo, corto y pego cada una de las tres secciones en tres archivos separados, como "mío", "común" y "ellos".

Luego puedo ejecutar los siguientes comandos para ver dos situaciones que causaron el conflicto:

 diff common mine diff common theirs 

Esto no es lo mismo que usar la herramienta de combinación, ya que la herramienta de fusión incluirá todas las diferencias de datos no conflictivas. Me parece una distracción.

Consejo dos

Alguien ya ha mencionado esto, pero comprender la intención detrás de cada palabra diff suele ser útil para entender de dónde se originó el conflicto y cómo manejarlo.

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

Esto muestra todas las confirmaciones relacionadas con este archivo entre un ancestro común y dos cabezas que combina. (Por lo tanto, no incluye los compromisos que ya existen en ambas ramas antes de la fusión). Esto ayuda a ignorar las diferencias que claramente no son un factor en su conflicto actual.

Consejo tres

Comprueba tus cambios con herramientas automatizadas.

Si tiene pruebas automatizadas, ejecútelas. Si tienes una pelusa , ejecútalo. Si se trata de un proyecto de construcción, debe construirse antes de que lo complete, etc. En todos los casos, debe realizarse algunas pruebas para asegurarse de que no se rompan los cambios. (Diablos, incluso fusionar sin conflictos puede romper el código de trabajo).

Consejo cuatro

Planea con anticipacion comunicarse con colegas

Planear con anticipación y darse cuenta de 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 son relevantes.

Por ejemplo, si sabe que usted y otra persona están trabajando en diferentes refactorizaciones que afectarán al mismo conjunto de archivos, debe hablar entre ellos con suficiente antelación y comprender mejor qué tipo de cambios está realizando cada uno de ustedes. Puede ahorrar mucho tiempo y esfuerzo si realiza los cambios planificados a su vez, y no en paralelo.

Para refactorizaciones grandes que cruzan una gran parte del código, debe considerar seriamente trabajar de manera secuencial: todos dejan de trabajar en esta área de código, y una persona realiza una refactorización completa.

Si no puede trabajar de manera consistente (posiblemente debido a una presión temporal), hablar sobre los conflictos de fusión esperados al menos lo ayudará a resolver problemas antes, mientras que los detalles aún están actualizados. Por ejemplo, si un empleado realiza una serie de confirmaciones destructivas dentro de una semana, es posible que desee fusionar / volver a empaquetar esta sucursal una o dos veces al día esta semana. De esa manera, si encuentra conflictos de combinación / redirección, puede resolverlos más rápido que si espera unas semanas para fusionar todo en una sola pieza grande.

Consejo cinco

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

La fusión puede ser abrumadora, especialmente cuando hay muchos archivos en conflicto, y los marcadores de conflicto abarcan cientos de líneas. A menudo, cuando evaluamos proyectos de software, no incluimos el tiempo suficiente para los recargos, como el procesamiento de una fusión loca, por lo que parece una verdadera resistencia pasar varias horas analizando cada conflicto.

A largo plazo, la planificación anticipada y la comprensión de que otros están trabajando son las mejores herramientas para predecir los conflictos de fusión y prepararse para la solución correcta en menos tiempo.

696
29 сент. La respuesta es dada por Mark E. Haase 29 sep. 2011-09-29 00:08 '11 a las 0:08 2011-09-29 00:08
  • Determine qué archivos están en conflicto (Git debería decirle esto).

  • Abre cada archivo y aprende las diferencias; Git los delimita. Espero que sea obvio qué versión de cada bloque guardar. Es posible que deba discutir esto con otros desarrolladores que hayan completado el código.

  • Una vez que haya resuelto el conflicto en el archivo git add the_file , git add the_file .

  • Tan pronto como resuelva todos los conflictos, ejecute git rebase --continue o cualquier comando que Git diga cuando termine.

326
02 окт. la respuesta se da davetron5000 02 oct. 2008-10-02 15:41 '08 a las 3:41 pm 2008-10-02 15:41

Verifique las respuestas en la pregunta de cancelación de cancelación de Git , especialmente la respuesta de Charles Bailey , que muestra cómo ver varias versiones de un archivo de problemas, por ejemplo.

100
03 окт. Respuesta dada por Pat Notz el 3 de octubre. 2008-10-03 18:15 '08 a las 6:15 pm 2008-10-03 18:15

La fusión de conflictos se produce cuando se realizan cambios en un archivo al mismo tiempo. Aquí está cómo resolverlo.

git CLI

Estos son los pasos simples que debe seguir cuando se encuentra en un estado de conflicto:

  • Observe la lista de archivos en conflicto: git status (en la sección de Unmerged paths ).
  • Resuelva los conflictos por separado para cada archivo con uno de los siguientes enfoques:

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

    • Para aceptar una versión remota / otra, use: git checkout --theirs path/file . Esto rechazará cualquier cambio local que haya realizado en este archivo.

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

      Sin embargo, debe tener cuidado, ya que los cambios eliminados se han eliminado por algún motivo.

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

    • Edite los archivos en conflicto manualmente y localice el bloque de código entre <<<<< / >>>>> , luego seleccione la versión arriba o abajo ===== . Ver: Cómo se presentan los conflictos .

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

  • Por último, revise los archivos listos para cometer usando: git status .

    Si todavía tiene archivos en Unmerged paths y ha resuelto el conflicto manualmente, entonces informe a Git que lo resolvió: git add path/file .

  • Si todos los conflictos se han resuelto correctamente, copie los cambios: git commit -a y haga clic en el eliminado como de costumbre.

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

DiffMerge

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

Muestra gráficamente los cambios entre 3 archivos y permite la fusión automática (cuando es seguro) y el control total sobre la edición del archivo resultante.

2019

05 авг. la respuesta se da kenorb 05 ago. 2015-08-05 17:29 '15 a las 17:29 2015-08-05 17:29

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

Para los conflictos que involucran varias líneas, es más fácil ver lo que está sucediendo en la herramienta de GUI externa. Me gusta opendiff - Git también es compatible con vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, emerge fuera de la caja, y puede instalar otros: git config merge.tool "your.tool" instalará la herramienta elegida y luego git mergetool fusionar le mostrará las diferencias en el contexto.

Cada vez que edite un archivo para resolver un conflicto, git add filename actualiza el índice y su diff ya no lo mostrará. Cuando todos los conflictos se hayan procesado y sus archivos hayan sido git add , git commit completará la fusión.

75
02 окт. La respuesta se da Pablo 02 oct. 2008-10-02 19:11 '08 a las 7:11 pm 2008-10-02 19:11

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

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

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

  • Decide no fusionar. Los únicos limpiadores que necesita son un archivo de índice de restablecimiento para reparar la HEAD de la transformada inversa 2. y para eliminar los cambios de la aldea de trabajo realizados en 2. y 3; git merge --abort se puede utilizar para esto.

  • Resolver conflictos. Git marcará los conflictos en el árbol de trabajo. Edite los archivos en el formulario y git add al índice. Usa git commit para sellar un trato.

Puedes trabajar en conflicto con varias herramientas:

  • Utilice mergetool. git mergetool para ejecutar un gráfico mergetool que funcionará a través de una combinación.

  • Mira las diferencias. git diff muestra un git diff tres lados, resaltando los cambios de las MERGE_HEAD HEAD y MERGE_HEAD .

  • Mira las diferencias entre cada rama. git log --merge -p <path> mostrará primero la diferencia para la versión HEAD y luego la versión MERGE_HEAD .

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

También puede leer acerca de la marca del conflicto de fusión y cómo resolverlos en la sección Conflictos de fusión principales de Pro Git .

43
14 июля '13 в 21:34 2013-07-14 21:34 la respuesta la da el usuario456814 14 de julio de 2013 a las 21:34 2013-07-14 21:34

Para Emacs, los usuarios que desean resolver conflictos de combinación semi-manuales:

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

Muestra todos los archivos que requieren resolución de conflictos.

Abra cada uno de estos archivos uno por uno o todos a la vez:

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

Cuando visite un búfer que requiera edición en Emacs, ingrese

 ALT+x vc-resolve-conflicts 

Esto abrirá los tres buffers (el mío, ellos y el buffer de salida). Navegue presionando "n" (siguiente área), "p" (área de predicción). Presione "a" y "b" para copiar mi o su área en el búfer de salida, respectivamente. Y / o editar el buffer de salida directamente.

Cuando termine: pulse "q". Emacs le pregunta si desea guardar este búfer: sí. Cuando se complete el búfer, márquelo como resuelto en el lanzamiento desde el lanzador:

 git add FILENAME 

Haber terminado de trabajar con todo tipo de buffers.

 git commit 

para completar la fusión.

36
23 февр. La respuesta es dada el 23 de febrero. 2013-02-23 02:04 '13 a las 2:04 2013-02-23 02:04

O bien quiero mi versión o su versión completa, o quiero ver los cambios individuales y tomar una decisión para cada uno de ellos.

Acepta totalmente mi o su versión :

Acepta mi versión (local, nuestra):

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

Acepta su versión (eliminada):

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

Si quiere hacer para todos los archivos en conflicto, ejecute:

 git merge --strategy-option ours 

o

 git merge --strategy-option theirs 

Revisa todos los cambios y acéptalos individualmente.

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

Por defecto, mergetool funciona en la línea de comando . Cómo usar la línea de comando mergetool debería ser un problema separado.

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

 git mergetool -t meld 

Se abrirá la versión local (nuestra), "básica" o "unificada" (el resultado actual de la combinación) y el (los) control (es) remoto (s). Guarde la versión combinada cuando haya terminado, ejecute git mergetool -t meld hasta que obtenga "No es necesario combinar archivos", luego vaya al Paso 3. y 4.

28
29 сент. La respuesta está dada por Noidea 29 sep . 2016-09-29 16:02 '16 a las 16:02 2016-09-29 16:02

Por favor complete los siguientes pasos para arreglar los conflictos de fusión en git:

  1. Comprobar estado de Git : Estado de Git

  2. Obtenga el conjunto de parches: git fetch (verifique el parche correcto en su git commit)

  3. Extraer rama local (en mi ejemplo, temp1): git checkout -b temp1

  4. Extrae contenido reciente del maestro: git pull --rebase origin master

  5. Ejecute mergetool, verifique los conflictos y corríjalos ... y verifique los cambios en la rama remota con su rama actual: git mergetool

  6. Compruebe el estado de nuevo: estado de git

  7. Elimine los archivos innecesarios creados localmente con mergetool, generalmente mergetool crea un archivo adicional con la extensión * .orig. Elimine este archivo, ya que es solo un duplicado, corrija los cambios localmente y agregue la versión correcta de sus archivos. git agregar #your_changed_correct_files

  8. Compruebe el estado de nuevo: estado de git

  9. Confirme los cambios en el mismo identificador (esto evita un nuevo conjunto de arreglos por separado): git commit --amend

  10. Push to master branch: git push (a su repositorio Git)

28
16 апр. La respuesta se da Chhabilal 16 de abril. 2015-04-16 10:02 '15 a las 10:02 2015-04-16 10:02

En pocas palabras, si sabe bien que los cambios en uno de los repositorios no son importantes, y desea permitir todos los cambios a favor del otro, use:

 git checkout . --ours 

permitir cambios a favor de su repositorio , o

 git checkout . --theirs 

Permitir cambios a favor de otro o repositorio principal .

O tendrá que usar la herramienta de combinación de GUI para recorrer los archivos, por ejemplo, la p4merge combinación p4merge , o escribir cualquier nombre que ya haya establecido.

 git mergetool -t p4merge 

y después de completar el archivo, tendrá que guardar y cerrar para abrir el siguiente.

27
26 янв. Respondido por Mohamed Selim el 26 de enero 2016-01-26 20:42 '16 a las 8:42 pm 2016-01-26 20:42

Puede solucionar los conflictos de combinación de varias maneras, como han detallado otros.

Creo que la verdadera clave es saber cómo fluyen los cambios con los repositorios locales y remotos. La clave para esto es entender las ramas de seguimiento. Descubrí que pienso en la rama de seguimiento como la "parte faltante en el medio" entre mi, mi directorio local de archivos y el remoto, definido como origen.

Yo personalmente me acostumbré a dos cosas para ayudar a evitar esto.

En lugar de

 git add . git commit -m"some msg" 

Lo que tiene dos inconvenientes -

a) Se agregan todos los archivos nuevos / modificados y pueden contener algunos cambios no deseados.
b) No se puede ver primero la lista de archivos.

Así que en su lugar:

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

De esta manera, está discutiendo más deliberadamente qué archivos se están agregando, y también puede desplazarse por la lista y pensar un poco más usando el editor para el mensaje. Encuentro que también mejora mis mensajes de confirmación cuando uso el editor de pantalla completa, en lugar de la opción -m .

[Actualización - a medida que pasaba el tiempo, cambié más a:

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

]