¿Qué versión del archivo git se usará finalmente: LOCAL, BASE o REMOTE?

174

Cuando hay una colisión durante git merge, abro una herramienta de combinación llamada Meld . Abre tres archivos LOCAL, BASE y REMOTE. Como he leído LOCAL es mi rama local, BASE es un ancestro común y REMOTE es la rama que se fusionará.

Ahora a mi pregunta: ¿qué versión del archivo se usará finalmente? ¿Es a distancia? Si es así, ¿puedo editarlo como quiera, independientemente de lo que haya en la rama BASE, por ejemplo?

tsusanka
fuente

Respuestas:

142

Es el uno en el medio: BASE.

De hecho, BASEno es el ancestro común, sino la fusión a medio terminar donde los conflictos están marcados con >>>>y <<<<.

Puede ver los nombres de los archivos en la parte superior de la ventana de edición de fusión.

Mira la captura de pantalla aquí

base de fusión

Puede editar el BASEarchivo como desee con o sin usar los comandos de fusión.
También puede deshacerse de la fusión y simplemente editar el archivo con su editor de texto favorito.

  • El código entre <<<< HEADy los =====marcadores es el de su archivo local antes de la fusión.
  • El código entre ====y >>>> <branch name>es el del archivo remoto.
Fabien Quatravaux
fuente
3
Algunas personas obtienen una mejor comprensión de los fragmentos en conflicto en un archivo que falló la fusión automática si tienen la merge.conflictstyleopción de configuración establecida en diff3lugar de la predeterminada merge.
kostix
3
En realidad no veo el HEAD, <<< y === canta. En el caso de que haya proporcionado la ventana del medio estaría vacía. Pero eso es solo una nota para los demás, gracias por su respuesta.
tsusanka
Si no ve los HEAD, <<<<<y =====señales, significa que no hay conflicto en absoluto. En este caso, la ventana central no estará vacía, mostrará el resultado de la fusión, pero no habrá una parte "roja"
Fabien Quatravaux
10
Cuando hago fusiones con Meld, tampoco veo ninguno <<<<<<, ======ni >>>>>>marcadores en el panel central (es decir, la versión BASE); y, a veces, el panel central estará vacío, como informó aGr. Tal vez esta diferencia se deba a diferentes configuraciones. Cuando comienzo a la herramienta Meld, existirán los siguientes archivos, suponiendo que el nombre del archivo en el repositorio es X.java: X.java, X.java.orig, X.java.BACKUP.#, X.java.BASE.#, X.java.LOCAL.#, X.java.REMOTE.#,, donde #es un número. Al llamar al resultado de fusión, la versión BASE es confusa; FUSIONADO sería mejor.
Teemu Leisti
3
BASE es, de hecho, el ancestro común, MERGED es el nombre del archivo con la información de fusión parcial. Consulte mi pregunta y respuesta Configuración y uso de Meld como git difftool y mergetool, que explica exactamente cómo funciona. HTH
Mattst
107

Meld tiene una función de fusión de 3 vías oculta activada al pasar el cuarto parámetro:

meld $LOCAL $BASE $REMOTE $MERGED

Los paneles derecho e izquierdo se abren en modo de solo lectura, por lo que no puede fusionarse accidentalmente al revés. El panel central muestra el resultado de la fusión. Para los conflictos, muestra la versión base para que pueda ver todos los bits importantes: texto original en el medio y modificaciones conflictivas en ambos lados. Finalmente, cuando presiona el botón "Guardar", se escribe el archivo $ MERGED, exactamente como lo esperaba git.

El archivo ~ / .gitconfig que uso contiene la siguiente configuración:

[merge]
tool = mymeld
conflictstyle = diff3
[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE $MERGED

esto abre meld con 3 pestañas, la 1ra y 2da pestaña que contiene los diferenciales simples que estoy tratando de fusionar, y la 3ra pestaña, abierta por defecto, muestra la vista de fusión de 3 vías.

Ahora, la razón por la cual la función está oculta es que aún no está lo suficientemente pulida. Es muy útil como lo es ahora, pero Kai Willadsen, el autor de la fusión, señaló algunas arrugas que necesitan ser eliminadas. Por ejemplo, no hay GUI para iniciar el modo de fusión de 3 vías, la sintaxis de la línea de comandos es un poco arcana, y tal. Si hablas python y tienes algo de tiempo libre, ya sabes qué hacer.

Editar: en las versiones más nuevas de Meld, la sinax ha cambiado ligeramente. Esto estaba en los comentarios, pero pertenece a la respuesta.

El comando meld ahora usa la opción --output, por lo que la última línea del fragmento anterior debería ser:

cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED
Tomek Bury
fuente
77
@Jesse, @lumbric, parece que las versiones más nuevas de meld usan la bandera --outputpara el resultado $ MERGED. Descubrí esto mientras miraba el script de lanzamiento de fusión que venía con mi versión de git: github.com/git/git/blob/master/mergetools/meld
Johann
1
@lumbric Creo que sí, para Meld 1.7.x + con el --output option. Vea esta línea en el script de lanzamiento:"$merge_tool_path" --output "$MERGED" "$LOCAL" "$BASE" "$REMOTE"
Johann
12
En la última fusión (versión> 1.8.4), tenemos que usar la opción --auto-merge. cmd = meld --diff $ BASE $ LOCAL --diff $ BASE $ REMOTO - fusión automática $ LOCAL $ BASE $ REMOTO - salida $ MERGED
RoboAlex
77
Tuve el mismo problema que @pingpongboss usando Meld 1.8.4: Meld estaba abriendo cosas en un panel separado, en lugar de abrir la tercera pestaña. El comando de la multa finalmente trabajado es: cmd = meld $LOCAL $BASE $REMOTE --auto-merge --output $MERGED. Por lo tanto, esto abre 3 pestañas (a la antigua usanza), combina automáticamente fusiones no conflictivas en el medio, donde el medio es $ MERGED, y se usará como salida de resolución de conflictos.
farmir
2
La sintaxis para la salida puede ser --output=<file>o -o <file>, veameld --help
levsa
57

Hay 4 archivos involucrados:

  1. $LOCALEl archivo en la rama donde se está fusionando; intacto por el proceso de fusión cuando se le muestra

  2. $REMOTEEl archivo en la rama desde donde se está fusionando; intacto por el proceso de fusión cuando se le muestra

  3. $BASEEl ancestro común de $ LOCAL y $ REMOTE, es decir. el punto donde las dos ramas comenzaron a desviar el archivo considerado; intacto por el proceso de fusión cuando se le muestra

  4. $MERGEDEl archivo parcialmente fusionado, con conflictos; este es el único archivo tocado por el proceso de fusión y, en realidad, nunca se muestra enmeld


El $MERGEDarchivo es el que contiene las <<<<<<, >>>>>>, =====(y, tal vez, ||||||marcadores) (que entra en conflicto delimitan). Este es el archivo que edita manualmente para corregir conflictos.

La edición manual de conflictos y la edición visual de conflictos se realizan en diferentes archivos y presentan diferentes informaciones.

Cuando se utiliza el mergetool (asumir meld), los archivos que están viendo el mismo son: $LOCAL, $BASE, $REMOTE. Tenga en cuenta que no ve el $MERGEDarchivo, aunque esto se pasa como un parámetro oculto parameld para escribir el resultado de la edición allí.

En otras palabras, en meld, está editando el archivo en el medio, el $BASEarchivo, y selecciona todos los cambios de la izquierda o de la derecha manualmente . Es un archivo limpio, no tocado por el proceso de fusión. La única falla es que, cuando guarda, no guarda en el $BASEarchivo, pero en el cuarto parámetro oculto de meld, ese es el $MERGEDarchivo (que ni siquiera ve). El $BASEarchivo no contiene conflictos ni fusiones parciales exitosas porque no es el $MERGEDarchivo .

En la edición visual, al presentarle el $BASEarchivo (en lugar del $MERGEDarchivo) gitbásicamente descarta todos sus intentos de hacer la fusión (esos intentos son visibles, si lo desea, en el archivo $ MERGED) y le permite hacer la fusión por completo a partir de cero .

La conclusión es que en los conflictos de fusión manual y visual no está mirando los mismos archivos, pero el resultado final está escrito en el mismo archivo (ese es el $MERGEDarchivo).

La corrección manual de los conflictos se realiza en $MERGEDporque git no tiene medio de presentarle tres archivos, por lo que aplasta a la información de los tres archivos ( $LOCAL, $BASE, $REMOTE) en ese $MERGEDarchivo.

Pero las herramientas visuales tienen los medios para mostrarles tres archivos: te muestran los $LOCAL, $BASE, $REMOTEarchivos. Usted va a recoger los cambios de las $LOCALy los $REMOTEarchivos y usted está trayendo a los que en el $BASEarchivo, completamente re-construcción e incluso sobrescribir el fallido intento de fusionar ese es el $MERGEDarchivo.

usuario1284631
fuente
Solo quería que haya herramientas (por ejemplo, más allá de comparar) que muestren los 4 archivos
yoniLavi
@yoniYalovitsky: sí, o p4merge
usuario1284631
Solía ​​usar la herramienta de fusión del paquete ClearCase
mishmashru el
@yoniLavi: bueno, estas herramientas muestran 4 paneles , pero no necesariamente los cuatro archivos como se describe en esta respuesta. En particular, se puede configurar estas herramientas 4-panel para mostrar que $LOCAL, $REMOTE, $BASEy la salida inicialmente igual a $BASE, pero que es diferente de $MERGEDen que no tiene el intento de git para combinar los archivos y las marcas de conflicto y así sucesivamente. De hecho, esa sería la forma de usar estas herramientas que es más similar al enfoque de 3 paneles de LOCAL / REMOTE / BASE + OUTPUT, que no se muestra combinado. El cuarto panel simplemente le permite separar la base de la salida.
BeeOnRope
16

La solución de Cosmin funciona, pero el archivo $ BASE se actualiza, no $ MERGED . Esto actualizará el archivo $ MERGED :

Fusión: v1.8.4

[merge]
  conflictstyle = diff3
  tool = mymeld
[mergetool "mymeld"]
  cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE --diff $BASE $LOCAL --diff $BASE $REMOTE
Saad Malik
fuente
Puedo confirmar esto. La solución de Saad funciona para mí en Ubuntu. En cuanto a la pregunta original, esta es la respuesta correcta actual.
cosmin
3
En mi versión de meld - 3.11, este comando funciona muy bien:cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE
MartinM
¿Por qué necesitarías --diff $BASE $LOCAL --diff $BASE $REMOTEal final? para mí en 1.8.4, esto funciona bien (hasta donde puedo ver):cmd = meld --auto-merge --output $MERGED $LOCAL $BASE $REMOTE
farmir
1
@farmir: no es necesario. Abre dos pestañas más en fusión para que pueda ver LOCAL y REMOTO en comparación con BASE individualmente.
Sam Kauffman
1
No importa en qué orden intente con esos argumentos, la pestaña de tres vías siempre es la tercera pestaña, mientras que la primera pestaña siempre está seleccionada de forma predeterminada. ¿Hay alguna manera de hacer que la pestaña de tres vías esté seleccionada de forma predeterminada?
Sam Kauffman
13

Con Meld 1.7, la solución de Tomek Bury ya no funciona.

La configuración predeterminada no me satisfizo:

Configuración por defecto

En cambio para Meld> = 1.7 sugiero una de las otras dos soluciones.

Primera solución :

 meld $LOCAL $BASE $REMOTE --auto-merge

primera solución

Segunda solución :

 meld $LOCAL $MERGED $REMOTE

segunda solución

.gitconfig

Copie y pegue esto en su .gitconfigarchivo para obtener las soluciones como se describe anteriormente:

[merge]
    tool = meld16
[mergetool "meld17"]
    # use this for Meld >=1.7
    # see http://stackoverflow.com/a/22911793/859591
    # second solution:
    cmd = meld $LOCAL $MERGED $REMOTE
    # first solution:
    #cmd = meld $LOCAL $BASE $REMOTE --auto-merge
[mergetool "meld16"]
    cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED

[include]
    # requires git v1.7.10+
    path = .gitconfig.local

Copie y pegue esto en un .gitconfig.localarchivo para configurar meld17 o meld16 solo para esta máquina en caso de que use su .gitconfig en varias máquinas:

# This is a host specific config file!
# Note that git 1.7.10+ is needed
# http://stackoverflow.com/a/9733277/859591
[merge]
    tool = meld17
lumbric
fuente
Esto no funciona en Meld 1.8.4. Si ejecuta cmd = meld $LOCAL $BASE $REMOTE --auto-merge, el panel central será el $ BASE, y no el $ MERGE que realmente se utiliza como salida de resolución de conflictos.
farmir
1
@farmir Usted eligió $ BASE como la segunda pestaña.
Alex78191
11

Descubrí que ninguno de los archivos predeterminados mostrados se estaba guardando. meld se mostraba $LOCAL, $REMOTEy $BASEpor defecto. Para que funcione, necesitaba hacer meld show en $MERGEDlugar de $BASE. Poniendo esto en mi lo ~/.gitconfigarregló para mí:

[merge]
        tool = mymeld
[mergetool "mymeld"]
        cmd = meld "$LOCAL" "$MERGED" "$REMOTE"

Estoy usando Arch, con:

$ git --version
git version 1.8.2
$ meld --version
meld 1.7.1
Thomas Leonard
fuente
Disculpe, ¿esta configuración es compatible con Linux?
MadMad666
2

Por alguna razón, las versiones más nuevas de fusión no muestran líneas de marcador agregadas para conflictos (<<<<<<<, =======, >>>>>>>). Si desea ver esas líneas, debe instalar meld v 1.3.3 o anterior.

wnasich
fuente
Encontré útil la respuesta de @lumbric stackoverflow.com/a/22911793/641892
wnasich
2

Consulte la respuesta de Saad para obtener la respuesta correcta.

Con meld 1.8.1 en Ubuntu estaba obteniendo el

número incorrecto de argumentos suministrados a --diff

y agregando la salida - antes de que $ MERGED me lo arreglara:

[mergetool "mymeld"]
cmd = meld --diff $BASE $LOCAL --diff $BASE $REMOTE --diff $LOCAL $BASE $REMOTE --output $MERGED
cosmin
fuente