¿Cómo resuelvo los conflictos de fusión en Git?
git
instalación predeterminada . Logré llegar a la página de inicio de SE para mí hoy, 2017, con 1.3 millones de visitas y miles de votos en ambos sentidos. Fascinante.
¿Cómo resuelvo los conflictos de fusión en Git?
git
instalación predeterminada . Logré llegar a la página de inicio de SE para mí hoy, 2017, con 1.3 millones de visitas y miles de votos en ambos sentidos. Fascinante.
Respuestas:
Tratar: git mergetool
Abre una GUI que lo guía a través de cada conflicto, y puede elegir cómo fusionar. A veces requiere un poco de edición manual después, pero generalmente es suficiente por sí solo. Es mucho mejor que hacer todo a mano, sin duda.
Según el comentario de @JoshGlover:
El comando
no necesariamente abre una GUI a menos que instales una. Correr
git mergetool
por mí resultó envimdiff
ser utilizado. Puede instalar una de las siguientes herramientas para utilizarla en su lugar:meld
,opendiff
,kdiff3
,tkdiff
,xxdiff
,tortoisemerge
,gvimdiff
,diffuse
,ecmerge
,p4merge
,araxis
,vimdiff
,emerge
.
A continuación se muestra el procedimiento de ejemplo que se utilizará vimdiff
para resolver conflictos de fusión. Basado en 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 fusión predeterminada.
Paso 2 : Ejecute el siguiente comando en la terminal
git mergetool
Paso 3 : verá una pantalla vimdiff en el siguiente formato
╔═══════╦══════╦════════╗
║ ║ ║ ║
║ LOCAL ║ BASE ║ REMOTE ║
║ ║ ║ ║
╠═══════╩══════╩════════╣
║ ║
║ MERGED ║
║ ║
╚═══════════════════════╝
Estas 4 vistas son
LOCAL: este es el archivo de la rama actual
BASE: ancestro común, cómo se veía el archivo antes de ambos cambios
REMOTO: archivo que está fusionando en su rama
FUSIONADO: resultado de fusión, esto es lo que se guarda en el repositorio
Puede navegar entre estas vistas usando ctrl+ w. Puede acceder directamente a la vista MERGED usando ctrl+ wseguido de j.
Más información sobre la navegación vimdiff aquí y aquí
Paso 4 . Puede editar la vista FUSIONADA de la siguiente manera
Si desea obtener cambios desde REMOTO
:diffg RE
Si desea obtener cambios desde BASE
:diffg BA
Si desea obtener cambios de LOCAL
:diffg LO
Paso 5 . Guardar, salir, confirmar y limpiar
:wqa
guardar y salir de vi
git commit -m "message"
git clean
Elimine archivos adicionales (por ejemplo, * .orig) creados por la herramienta diff.
git mergetool -y
para guardar algunas teclas si combina muchos archivos a la vez.
git mergetool
por mí resultó en vimdiff
ser utilizado. Puede instalar una de las siguientes herramientas para utilizarla en su lugar: meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis vimdiff emerge
.
git mergetool -t bc3
).
Aquí hay un caso de uso probable, desde arriba:
Vas a hacer algunos cambios, pero 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 nuevamente, 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 my, oh my, 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 intentamos una última vez
git pull origin master
From ssh://gitosis@example.com:22/projectname
* branch master -> FETCH_HEAD
Already up-to-date.
Ta-da!
git merge --help
this question
Encuentro que las herramientas de combinación rara vez me ayudan a comprender el conflicto o la resolución. Por lo general, tengo más éxito mirando los marcadores de conflicto en un editor de texto y usando git log como suplemento.
Aquí hay algunos consejos:
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 (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 era el propósito de cada cambio.
Si el conflicto es solo unas pocas líneas, esto generalmente hace que el conflicto sea muy obvio. (Saber cómo solucionar un conflicto es muy diferente; debe saber en qué están trabajando otras personas. Si está confundido, probablemente sea mejor llamar a esa persona a su habitación para que puedan ver lo que está buscando). a.)
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 "suyo".
Luego puedo ejecutar los siguientes comandos 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 incluirá todos los trozos de diferencias no conflictivos. Me parece que eso me distrae.
Alguien ya mencionó esto, pero comprender la intención detrás de cada trozo de 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á fusionando. (Por lo tanto, no incluye las 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.
Verifique sus cambios con herramientas automatizadas.
Si tiene pruebas automatizadas, ejecútelas. Si tienes una pelusa , corre eso. Si se trata de un proyecto armable, compílelo antes de comprometerse, etc. En todos los casos, debe hacer un poco de prueba para asegurarse de que sus cambios no rompan nada. (Diablos, incluso una fusión sin conflictos puede romper el código de trabajo).
Planificar con anticipación; comunicarse con compañeros de trabajo.
Planificar con anticipación y estar al tanto de lo que otros están trabajando puede ayudar a evitar conflictos de fusión y / o ayudar a resolverlos antes, mientras los detalles aún están frescos.
Por ejemplo, si sabe que usted y otra persona están trabajando en una refactorización diferente que afectará el mismo conjunto de archivos, deben hablar entre ellos con anticipación y tener una mejor idea de qué tipo de cambios es cada uno de ustedes haciendo. Puede ahorrar tiempo y esfuerzo considerables si realiza los cambios planificados en serie en lugar de en paralelo.
Para refactorizaciones importantes que atraviesan una gran franja de código, debe considerar 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, tal vez), comunicarse sobre los conflictos de fusión esperados al menos lo ayuda a resolver los problemas antes mientras los detalles aún están frescos. Por ejemplo, si un compañero de trabajo está haciendo una serie de compromisos disruptivos en el transcurso de un período de una semana, puede optar por fusionar / rebase en esa rama de compañeros de trabajo una o dos veces al día durante esa semana. De esa manera, si encuentra conflictos de fusión / rebase, puede resolverlos más rápidamente que si espera unas semanas para fusionar todo en un gran bulto.
Si no está seguro de una fusión, no la fuerce.
La fusión puede parecer abrumadora, especialmente cuando hay muchos archivos en conflicto y los marcadores de conflicto cubren cientos de líneas. Muchas veces, al estimar proyectos de software, no incluimos suficiente tiempo para elementos generales como manejar una fusión retorcida, por lo que se siente como un verdadero lastre pasar varias horas diseccionando cada conflicto.
A la larga, planificar 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 menos tiempo.
p4merge
, que se puede instalar y usar por separado de otras herramientas de Perforce (que no he usado, pero escuché quejas).
git config merge.conflictstyle diff3
- gracias Señor. Esto es increíble y me ha liberado de intentar encontrar (y pagar $$) una buena GUI de combinación de 3 vías. OMI, esto es mejor porque muestra el ancestro común, así como local / remoto, y muestra las últimas líneas de registro de confirmación que (AFAIK) no hace GUI. Las confirmaciones definitivamente lo ayudan a identificar qué código pertenece a qué rama.
Identifique qué archivos están en conflicto (Git debería decirle esto).
Abra cada archivo y examine las diferencias; Git los demarca. Con suerte, será obvio qué versión de cada bloque mantener. Es posible que deba analizarlo con otros desarrolladores que hayan cometido el código.
Una vez que haya resuelto el conflicto en un archivo git add the_file
.
Una vez que hayas resuelto todos los conflictos, haz git rebase --continue
o cualquier comando que Git dijo que hicieras cuando lo completaras.
git add
archivos en el índice; sí no añade nada al repositorio. git commit
agrega cosas al repositorio. Este uso tiene sentido para las fusiones: la fusión automáticamente organiza todos los cambios que se pueden fusionar automáticamente; es su responsabilidad fusionar el resto de los cambios y agregarlos al índice cuando haya terminado.
Consulte las respuestas en la pregunta de desbordamiento de pila Abortar una fusión en Git , especialmente la respuesta de Charles Bailey, que muestra cómo ver las diferentes versiones del archivo 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 fusión ocurren cuando se realizan cambios en un archivo al mismo tiempo. Aquí está cómo resolverlo.
git
CLIAquí hay pasos simples sobre qué hacer cuando entra en estado de conflicto:
git status
(en la Unmerged paths
sección).Resuelva los conflictos por separado para cada archivo mediante uno de los siguientes enfoques:
Use la GUI para resolver los conflictos: git mergetool
(la forma más fácil).
Para aceptar a distancia / otra versión, utilice: git checkout --theirs path/file
. Esto rechazará cualquier cambio local que haya realizado para ese archivo.
Para aceptar local / nuestra versión, use: git checkout --ours path/file
Sin embargo, debe tener cuidado, ya que los cambios remotos que los conflictos se hicieron por alguna razón.
Relacionado: ¿Cuál es el significado preciso de "nuestro" y "suyo" en git?
Edite los archivos en conflicto manualmente y busque el bloque de código entre <<<<<
/ >>>>>
luego elija la versión desde arriba o desde 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 alguna archivos bajo Unmerged paths
, y se ha solucionado el conflicto de forma manual, a continuación, dejar que Git sabe que lo resolvió por: git add path/file
.
Si todos los conflictos se resolvieron con éxito, confirme los cambios de la siguiente manera: git commit -a
y presione en remoto como de costumbre.
Vea también: Resolver un conflicto de fusión desde la línea de comando en GitHub
Para obtener un tutorial práctico, consulte: Escenario 5: Corregir conflictos de fusión por Katacoda .
He utilizado con éxito DiffMerge que puede comparar visualmente y combinar archivos en Windows, macOS y Linux / Unix.
Gráficamente puede mostrar los cambios entre 3 archivos y permite la fusión automática (cuando sea seguro hacerlo) y un control total sobre la edición del archivo resultante.
Fuente de la imagen: DiffMerge (captura de pantalla de Linux)
Simplemente descárguelo y ejecútelo como:
git mergetool -t diffmerge .
En macOS puede instalar 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 RUTA (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 métodos abreviados de teclado:
Alternativamente, puede usar opendiff (parte de Xcode Tools) que le permite combinar dos archivos o directorios para crear un tercer archivo o directorio.
Si está haciendo pequeños commits frecuentes, entonces comience mirando los comentarios de commit con git log --merge
. Luego git diff
te mostrará los conflictos.
Para conflictos que involucran más de unas pocas líneas, es más fácil ver lo que está sucediendo en una herramienta GUI externa. Me gusta opendiff: Git también admite vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, emerge de la caja y puede instalar otros: git config merge.tool "your.tool"
configurará la herramienta elegida y luego, git mergetool
después de una fusión fallida, le mostrará las diferencias en contexto.
Cada vez que edite un archivo para resolver un conflicto, git add filename
actualizará el índice y su diff ya no lo mostrará. Cuando se manejen todos los conflictos y se hayan git add
editado sus archivos , git commit
completará su fusión.
Vea cómo se presentan los conflictos o, en Git, la git merge
documentación 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, puede hacer dos cosas:
Decide no fusionar. Las únicas limpiezas que necesita son restablecer el archivo de índice a la
HEAD
confirmación para invertir 2. y limpiar los cambios en el árbol de trabajo realizados por 2. y 3 .;git merge --abort
se puede usar para estoResolver los conflictos. Git marcará los conflictos en el árbol de trabajo. Edite los archivos en forma y
git add
en el índice. Usegit commit
para sellar el trato.Puede resolver el conflicto con una serie de herramientas:
Usa una herramienta de combinación.
git mergetool
para iniciar una herramienta de combinación gráfica que lo ayudará a completar la combinación.Mira las diferencias.
git diff
mostrará un diferencial de tres vías, resaltando los cambios de las versionesHEAD
yMERGE_HEAD
.Mira las diferencias de cada rama.
git log --merge -p <path>
mostrará diffs primero para laHEAD
versión y luego laMERGE_HEAD
versión.Mira los originales.
git show :1:filename
muestra el ancestro común,git show :2:filename
muestra laHEAD
versión ygit show :3:filename
muestra laMERGE_HEAD
versión.
También puede leer sobre los marcadores de conflicto de fusión y cómo resolverlos en la sección del libro Pro Git Conflictos básicos de fusión .
Quiero mi o su versión completa, o quiero revisar los cambios individuales y decidir por cada uno de ellos.
Acepte completamente mi versión o la de ellos :
Aceptar 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
Acepte su versión (remota, suya):
git checkout --theirs -- <filename>
git add <filename>
git commit -m "merged bla bla"
Si desea hacer para todos los archivos de conflicto ejecute:
git merge --strategy-option ours
o
git merge --strategy-option theirs
Revise todos los cambios y acéptelos individualmente
git mergetool
git add <filename>
git commit -m "merged bla bla"
El valor predeterminado mergetool
funciona en la línea de comandos . Cómo usar una línea de comando 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 (la nuestra), la versión "base" o "fusionada" (el resultado actual de la fusión) y la versión remota (la suya). Guarde la versión fusionada cuando haya terminado, git mergetool -t meld
vuelva a ejecutarla hasta que aparezca "No es necesario fusionar archivos", luego vaya a los Pasos 3. y 4.
Para usuarios de Emacs que desean resolver conflictos de fusión de forma semi-manual:
git diff --name-status --diff-filter=U
muestra todos los archivos que requieren resolución de conflictos.
Abra cada uno de esos archivos uno por uno, o todos a la vez:
emacs $(git diff --name-only --diff-filter=U)
Cuando visite un búfer que requiera modificaciones en Emacs, escriba
ALT+x vc-resolve-conflicts
Esto abrirá tres buffers (el mío, el suyo y el buffer de salida). Navegue presionando 'n' (región siguiente), 'p' (región de previsión). Presione 'a' y 'b' para copiar la región mía o de ellos en el búfer de salida, respectivamente. Y / o edite el búfer de salida directamente.
Cuando termine: presione 'q'. Emacs le pregunta si desea guardar este búfer: sí. Después de terminar un búfer, márquelo como resuelto ejecutando desde el penal:
git add FILENAME
Cuando termine con todos los tipos de tampones
git commit
para terminar la fusión
Al hablar de pull / fetch / merge en las respuestas anteriores, me gustaría compartir un truco interesante y productivo,
git pull --rebase
Este comando anterior es el comando más útil en mi vida git que ahorró mucho tiempo.
Antes de enviar su cambio recién confirmado al servidor remoto, intente git pull --rebase
más bien con el git pull
manual merge
y sincronizará automáticamente los últimos cambios del servidor remoto (con una búsqueda + fusión) y colocará su último compromiso local en la parte superior del registro git. No necesita preocuparse por la extracción / fusión manual.
En caso de conflicto, solo use
git mergetool
git add conflict_file
git rebase --continue
Encuentre detalles en: http://gitolite.com/git-pull--rebase
Simplemente, si sabe bien que los cambios en uno de los repositorios no son importantes, y desea resolver todos los cambios a favor del otro, use:
git checkout . --ours
para resolver cambios a favor de su repositorio , o
git checkout . --theirs
para resolver cambios a favor del otro o del repositorio principal .
O bien, tendrá que usar una herramienta de combinación de GUI para recorrer los archivos uno por uno, digamos que es la herramienta de combinación p4merge
o escribir el nombre de cualquiera que ya haya instalado
git mergetool -t p4merge
y después de terminar un archivo, tendrá que guardar y cerrar, para que se abra el siguiente.
Siga los siguientes pasos para solucionar conflictos de fusión en Git:
Verifique el estado de Git: estado de git
Obtenga el conjunto de parches: git fetch (consulte el parche correcto de su confirmación de Git)
Pague una sucursal local (temp1 en mi ejemplo aquí): git checkout -b temp1
Extraiga los contenidos recientes del maestro: git pull --rebase origin master
Inicie mergetool y verifique los conflictos y corríjalos ... y verifique los cambios en la rama remota con su rama actual: git mergetool
Verifique el estado nuevamente: estado de git
Elimine los archivos no deseados creados localmente por mergetool, generalmente mergetool crea un archivo adicional con la extensión * .orig. Elimine ese archivo ya que es solo el duplicado y arregle los cambios localmente y agregue la versión correcta de sus archivos. git add #your_changed_correct_files
Verifique el estado nuevamente: estado de git
Confirme los cambios en la misma ID de confirmación (esto evita un nuevo conjunto de parches por separado): git commit --amend
Empuje a la rama maestra: git push (a su repositorio de Git)
Hay 3 pasos:
Encuentra qué archivos causan conflictos por comando
git status
Verifique los archivos, en los que encontrará los conflictos marcados como
<<<<<<<<head
blablabla
Cámbielo a la forma que desee, luego confirme con comandos
git add solved_conflicts_files
git commit -m 'merge msg'
Puede solucionar conflictos de fusión de varias maneras, como otros han detallado.
Creo que la clave real es saber cómo fluyen los cambios con los repositorios locales y remotos. La clave para esto es comprender las ramas de seguimiento. He descubierto que pienso en la rama de seguimiento como la 'pieza faltante en el medio' entre mi directorio local de archivos reales y el control remoto definido como origen.
Personalmente me he acostumbrado a 2 cosas para ayudar a evitar esto.
En vez de:
git add .
git commit -m"some msg"
Que tiene dos inconvenientes:
a) Todos los archivos nuevos / modificados se agregan y eso puede incluir algunos cambios no deseados.
b) No puede revisar primero la lista de archivos.
Entonces, en cambio, hago:
git add file,file2,file3...
git commit # Then type the files in the editor and save-quit.
De esta manera, usted es más deliberado acerca de qué archivos se agregan y también puede revisar la lista y pensar un poco más mientras usa el editor para el mensaje. Creo que también mejora mis mensajes de confirmación cuando uso un editor de pantalla completa en lugar de la -m
opción.
[Actualización: a medida que pasó el tiempo, 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 fusión y si tiene cambios locales que no desea fusionar, puede terminar fácilmente con el código fusionado y / o fusionar conflictos 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?
git checkout master
y git fetch
e git rebase --hard origin/master
git add .
, ¿guardará nuestras modificaciones locales para que podamos seguir git checkout master
? o son dos escenarios diferentes?
$ git rebase --hard origin/master b5a30cc159ba8dd error: unknown option
uso duro: git rebase [-i] [opciones] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>] o: git rebase [-i] [ opciones] [--exec <cmd>] [--onto <newbase>] --root [<branch>] o: git rebase --continue | --abort | --skip | --edit-todo `
La respuesta de CoolAJ86 resume casi todo. En caso de que haya cambios en ambas ramas en el mismo código, deberá realizar una fusión manual. Abra el archivo en conflicto en cualquier editor de texto 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 la manera que desee que sea el nuevo código, mientras elimina signos de igual y corchetes angulares.
git commit -a -m "commit message"
git push origin master
git log --merge -p [[--] path]
Parece que no siempre funciona para mí y generalmente termina mostrando cada confirmación que era diferente entre las dos ramas, esto sucede incluso cuando se usa --
para separar la ruta del comando.
Lo que hago para solucionar este problema es abrir dos líneas de comando 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 rama en la que me fusioné y [path]
con el archivo que está en conflicto. Este comando registrará todas las confirmaciones, en forma de parche, entre ( ..
) dos confirmaciones. Si deja un lado vacío como en los comandos anteriores, git usará automáticamente HEAD
(la rama en la que se está fusionando en este caso).
Esto le permitirá ver qué confirmaciones ingresaron al archivo en las dos ramas después de que divergieron. Por lo general, hace que sea mucho más fácil resolver conflictos.
patience
Me sorprende que nadie más haya hablado de resolver conflictos utilizando patience
la estrategia recursiva de fusión. Para un gran conflicto de fusión, el uso me patience
proporcionó buenos resultados. La idea es que intente hacer coincidir bloques en lugar de líneas individuales.
Si cambia la sangría de su programa, por ejemplo, la estrategia de fusión Git predeterminada a veces coincide con llaves simples {
que pertenecen a diferentes funciones. Esto se evita con patience
:
git merge -s recursive -X patience other-branch
De la documentación:
With this option, merge-recursive spends a little extra time to avoid
mismerges that sometimes occur due to unimportant matching lines
(e.g., braces from distinct functions). Use this when the branches to
be merged have diverged wildly.
Si tiene un conflicto de fusión y quiere ver lo que otros tenían en mente al modificar su rama, a veces es más fácil comparar su rama directamente con el antepasado común (en lugar de nuestra rama). Para eso puedes usar merge-base
:
git diff $(git merge-base <our-branch> <their-branch>) <their-branch>
Por lo general, solo desea ver los cambios para un archivo en particular:
git diff $(git merge-base <our-branch> <their-branch>) <their-branch> <file>
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 línea de comandos 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 lo básico es que al 'fusionar' dos ramas a través de la interfaz de usuario, ahora verá una opción de 'resolver conflictos' que lo llevará a un editor que le permitirá lidiar con estos conflictos de fusión.
Si desea fusionar de rama (prueba) a maestra, 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 archivos para modificarlo.
Paso 4 : agrega 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, haga lo siguiente:
git push origin +test
Paso 7 : Y luego no hay conflicto entre prueba y maestro. Puede usar fusionar directamente.
Siempre sigo los pasos a continuación para evitar conflictos.
Ahora puede hacer lo mismo y mantener todas las sucursales locales que desee y trabajar simultáneamente, simplemente haciendo un pago de git a su sucursal cuando sea necesario.
Los conflictos de fusión pueden ocurrir en diferentes situaciones:
Debe instalar una herramienta de combinación que sea compatible con Git para resolver los conflictos. Personalmente uso KDiff3, y lo he encontrado agradable y útil. Puede descargar su versión de Windows aquí:
https://sourceforge.net/projects/kdiff3/files/
Por cierto, si instala Git Extensions, hay una opción en su asistente de configuración para instalar Kdiff3.
Luego configure 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 reemplazar la ruta con la ruta real del archivo exe Kdiff).
Luego, cada vez que encuentre un conflicto de fusión, solo necesita ejecutar este comando:
$git mergetool
Luego abre el Kdiff3, y primero intenta resolver los conflictos de fusión automáticamente. La mayoría de los conflictos se resolverían de forma espontánea y debe solucionar el resto manualmente.
Así es como se ve Kdiff3:
Luego, una vez que haya terminado, guarde el archivo y pasará al siguiente archivo con conflicto y volverá a hacer lo mismo hasta que se resuelvan todos los conflictos.
Para verificar si todo se fusionó con éxito, simplemente ejecute el comando mergetool nuevamente, debe obtener este resultado:
$git mergetool
No files need merging
Esta respuesta es agregar una alternativa para los usuarios de VIM como I que prefiere hacer todo dentro del editor.
A Tpope se le ocurrió este gran complemento para VIM llamado fugitivo . Una vez instalado, puede ejecutar :Gstatus
para verificar los archivos que tienen conflictos y :Gdiff
abrir Git de una manera combinada.
Una vez en la fusión de 3 vías, fugitivo le permitirá obtener los cambios de cualquiera de las ramas que está fusionando de la siguiente manera:
:diffget //2
, obtenga cambios de la rama original ( HEAD )::diffget //3
, obtenga cambios de la rama de fusión: Una vez que haya terminado de fusionar el archivo, escriba :Gwrite
el búfer fusionado. Vimcasts lanzó un gran video que explica en detalle estos pasos.
Puede probar Gitlense para VS Code, sus características principales son:
Ya me gusta esta característica:
Y hay muchas características que puedes consultar aquí .
git fetch
git checkout tu rama
git rebase master
En este paso, intentará solucionar el conflicto utilizando su IDE preferido
Puede seguir este enlace para verificar cómo solucionar el conflicto en el archivo
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)
Ahora todo está bien y encontrarás tu compromiso en gerrit
Espero que esto ayude a todos en relación con este tema.
Pruebe Visual Studio Code para editar si aún no lo ha hecho. Lo que hace es después de intentar fusionar (y aterrizar en conflictos de fusión). El código VS detecta automáticamente los conflictos de fusión.
Puede ayudarlo muy bien al mostrar cuáles son los cambios realizados en el original y si acepta incoming
o
current change
(que significa original antes de fusionarse)?
¡Me ayudó y también puede funcionar para ti!
PD: funcionará solo si ha configurado git con su código y Visual Studio Code.
Una forma más segura de resolver conflictos es usar git-mediate (las soluciones comunes sugeridas aquí son bastante propensas a errores).
Vea esta publicación para una introducción rápida sobre cómo usarla.
Para aquellos que usan Visual Studio (2015 en mi caso)
Cierra tu proyecto en VS. Especialmente en grandes proyectos, VS tiende a enloquecer cuando se combina con la interfaz de usuario.
Haga la fusión en el símbolo del sistema.
git checkout target_branch
git merge source_branch
Luego abra el proyecto en VS y vaya a Team Explorer -> Branch. Ahora hay un mensaje que dice que Merge está pendiente y los archivos en conflicto se enumeran justo debajo del mensaje.
Haga clic en el archivo en conflicto y tendrá la opción de Fusionar, Comparar, Tomar origen, Tomar destino. La herramienta de combinación en VS es muy fácil de usar.
Si está utilizando intelliJ como IDE Intente fusionar padre a su rama por
git checkout <localbranch>
git merge origin/<remotebranch>
Mostrará todos los conflictos como este
A_MBPro: prueba anu $ git merge origin / Auto-merging src / test / java / com /.../ TestClass.java CONFLICT (content): Merge conflict in src / test / java / com /.../ TestClass.java
Ahora tenga en cuenta que el archivo TestClass.java se muestra en rojo en intelliJ También se mostrará el estado de git
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: src/test/java/com/.../TestClass.java
Abra el archivo en intelliJ, tendrá secciones con
<<<<<<< HEAD
public void testMethod() {
}
=======
public void testMethod() { ...
}
>>>>>>> origin/<remotebranch>
donde HEAD es cambios en su sucursal local y origen / es cambios desde la sucursal remota. Aquí guarde las cosas que necesita y elimine las que no necesita. Después de eso, deberían seguir los pasos normales. Es decir
git add TestClass.java
git commit -m "commit message"
git push