¿Cómo resuelvo conflictos de fusión en un repositorio Git?
¿Cómo resuelvo conflictos de fusión en mi repositorio Git?
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 mergetool
para mí resultó envimdiff
que 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 vimdiff
para resolver conflictos de fusión, basado en este enlace .
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á
vimdiff
como la herramienta de combinación predeterminada.Ejecute el siguiente comando en su terminal
git mergetool
Verá una
vimdiff
pantalla 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
vimdiff
navegación está aquí y aquí .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
Guardar, salir, confirmar y limpiar
:wqa
guardar y salir de vigit commit -m "message"
git clean
Elimine archivos adicionales (por ejemplo*.orig
). Advertencia: eliminará todos los archivos sin seguimiento si no pasa ningún argumento.
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!
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.