¿Cómo resuelvo conflictos de fusión en un repositorio Git?

Resuelto Spoike asked hace 16 años • 36 respuestas

¿Cómo resuelvo conflictos de fusión en mi repositorio Git?

Spoike avatar Oct 02 '08 18:10 Spoike
Aceptado

Intentar:

git mergetool

Abre una GUI que lo guía a través de cada conflicto y puede elegir cómo fusionarse. A veces requiere un poco de edición manual después, pero normalmente es suficiente por sí solo. Sin duda, es mucho mejor que hacerlo todo a mano.


Según el comentario de Josh Glover :

[Este comando] no necesariamente abre una GUI a menos que instales una. Correr git mergetoolpara mí resultó en vimdiffque me usaran. Puede instalar una de las siguientes herramientas para utilizarlo en su lugar: meld, opendiff, kdiff3, tkdiff, xxdiff, tortoisemerge, gvimdiff, diffuse, ecmerge, p4merge, araxis, vimdiff, emerge.


A continuación se muestra un procedimiento de muestra que se utiliza vimdiffpara resolver conflictos de fusión, basado en este enlace .

  1. Ejecute los siguientes comandos en su terminal

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

    Esto se establecerá vimdiffcomo la herramienta de combinación predeterminada.

  2. Ejecute el siguiente comando en su terminal

    git mergetool
    
  3. Verá una vimdiffpantalla en el siguiente formato:

      ╔═══════╦══════╦════════╗
      ║       ║      ║        ║
      ║ LOCAL ║ BASE ║ REMOTE ║
      ║       ║      ║        ║
      ╠═══════╩══════╩════════╣
      ║                       ║
      ║        MERGED         ║
      ║                       ║
      ╚═══════════════════════╝
    

    Estas 4 vistas son

    • LOCAL: este es el archivo de la rama actual
    • BASE: el ancestro común, cómo se veía este archivo antes de ambos cambios
    • REMOTO: el archivo que estás fusionando en tu rama
    • FUSIONADO: el resultado de la fusión; esto es lo que se guarda en la confirmación de fusión y se usa en el futuro

    Puede navegar entre estas vistas usando ctrl+ w. Puede acceder directamente a la vista FUSIONADA usando ctrl+ wseguido de j.

    Más información sobre vimdiffnavegación está aquí y aquí .

  4. Puede editar la vista FUSIONADA de esta manera:

    • Si desea recibir cambios desde REMOTO

      :diffg RE
      
    • Si deseas recibir cambios desde BASE

      :diffg BA
      
    • Si desea recibir cambios desde LOCAL

      :diffg LO
      
  5. Guardar, salir, confirmar y limpiar

    :wqaguardar y salir de vi

    git commit -m "message"

    git cleanElimine archivos adicionales (por ejemplo *.orig). Advertencia: eliminará todos los archivos sin seguimiento si no pasa ningún argumento.

Peter Burns avatar Oct 02 '2008 17:10 Peter Burns

Aquí hay un caso de uso probable, desde arriba:

Vas a realizar algunos cambios, pero vaya, no estás actualizado:

git fetch origin
git pull origin master

From ssh://[email protected]:22/projectname
 * branch            master     -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.

Entonces te actualizas y vuelves a intentarlo, pero tienes un conflicto:

git add filename.c
git commit -m "made some wild and crazy changes"
git pull origin master

From ssh://[email protected]: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 Dios, oh Dios, 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 lo intentamos una última vez

git pull origin master

From ssh://[email protected]:22/projectname
 * branch            master     -> FETCH_HEAD
Already up-to-date.

¡Ta-da!

coolaj86 avatar Aug 04 '2010 17:08 coolaj86

Encuentro que las herramientas de combinación rara vez me ayudan a comprender el conflicto o su resolución. Normalmente tengo más éxito mirando los marcadores de conflicto en un editor de texto y usando git log como complemento.

Aquí hay algunos consejos:

Consejo uno

Lo mejor que he encontrado es utilizar 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 (i.e. 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 central es el aspecto del 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 rama, lo que le da una mejor idea de cuál fue el propósito de cada cambio.

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

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

Luego puedo ejecutar los siguientes comandos para ver los dos bloques de diferencias que causaron el conflicto:

diff common mine
diff common theirs

Esto no es lo mismo que usar una herramienta de combinación, ya que una herramienta de combinación también incluirá todos los bloques de diferencias que no estén en conflicto. Eso me distrae.

Consejo dos

Alguien ya mencionó esto, pero comprender la intención detrás de cada diferencia generalmente es muy útil para comprender 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 archivo entre el ancestro común y las dos cabezas que estás fusionando. (Por lo tanto, no incluye confirmaciones que ya existen en ambas ramas antes de fusionarse). Esto le ayuda a ignorar las diferencias que claramente no son un factor en su conflicto actual.

Consejo tres

Verifique sus cambios con herramientas automatizadas.

Si tiene pruebas automatizadas, ejecútelas. Si tienes pelusa , ejecútala. Si es un proyecto compilable, compílelo antes de confirmarlo, etc. En todos los casos, debe realizar algunas pruebas para asegurarse de que los cambios no rompan nada. (Diablos, incluso una fusión sin conflictos puede romper el código de trabajo).

Consejo cuatro

Planifique con anticipación; comunicarse con los compañeros de trabajo.

Planificar con anticipación y ser consciente de en qué están trabajando otros puede ayudar a prevenir conflictos de fusión y/o ayudar a resolverlos antes, mientras los detalles aún están frescos en la mente.

Por ejemplo, si sabe que usted y otra persona están trabajando en diferentes refactorizaciones que afectarán el mismo conjunto de archivos, deben hablar entre sí con anticipación y tener una mejor idea de qué tipos de cambios está realizando cada uno de ustedes. haciendo. Podría ahorrar mucho tiempo y esfuerzo si realiza los cambios planificados en serie en lugar de en paralelo.

Para refactorizaciones importantes que abarcan una gran franja de código, debería 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 (tal vez debido a la presión del tiempo), entonces comunicarse sobre los conflictos de fusión esperados al menos le ayudará a resolver los problemas antes, mientras los detalles aún están frescos en la mente. Por ejemplo, si un compañero de trabajo está realizando una serie disruptiva de compromisos en el transcurso de un período de una semana, puede optar por fusionar/reorganizar la rama de ese compañero de trabajo una o dos veces al día durante esa semana. De esa manera, si encuentra conflictos de fusión/reorganización, podrá resolverlos más rápidamente que si espera unas semanas para fusionar todo en un solo gran conjunto.

Consejo cinco

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

La fusión puede resultar abrumadora, especialmente cuando hay muchos archivos en conflicto y los marcadores de conflicto cubren cientos de líneas. Muchas veces, cuando estimamos proyectos de software, no incluimos suficiente tiempo para elementos generales, como manejar una fusión complicada, por lo que parece una verdadera molestia pasar varias horas analizando cada conflicto.

A largo plazo, planificar con antelación y ser consciente de en qué están trabajando los demás son las mejores herramientas para anticipar los conflictos de fusión y prepararse para resolverlos correctamente en menos tiempo.

Mark E. Haase avatar Sep 28 '2011 21:09 Mark E. Haase