La fusión en Git suele ser bastante fácil. Dado que Git facilita la fusión de otra rama varias veces, significa que puede tener una rama de larga duración, pero puede mantenerla actualizada sobre la marcha, resolviendo pequeños conflictos a menudo, en lugar de sorprenderse por un conflicto enorme en el final de la serie.
Sin embargo, a veces ocurren conflictos engañosos. A diferencia de otros sistemas de control de versiones, Git no intenta ser demasiado listo para fusionar la resolución de conflictos. La filosofía de Git es ser inteligente para determinar cuándo una resolución de fusión no es ambigua, pero si hay un conflicto, no intenta ser inteligente para resolverlo automáticamente. Por lo tanto, si espera demasiado para fusionar dos ramas que divergen rápidamente, puede encontrarse con algunos problemas.
En esta sección, veremos cuáles podrían ser algunos de esos problemas y qué herramientas le dará Git para ayudarlo a manejar estas situaciones más engañosas. También cubriremos algunos de los diferentes tipos de fusión no estándar que puede hacer, y también veremos cómo deshacerse de las fusiones que ha realizado.
Si bien cubrimos algunos conceptos básicos para resolver conflictos de fusión en ch03-git-branching.asc, para conflictos más complejos, Git proporciona algunas herramientas para ayudarlo a descubrir qué está sucediendo y cómo lidiar mejor con el conflicto.
En primer lugar, si es posible, intente asegurarse de que su directorio de trabajo esté limpio antes de realizar una fusión que pueda tener conflictos. Si tiene un trabajo en progreso, hágale commit a una rama temporal o stash. Esto hace que pueda deshacer cualquier cosa que intente aquí. Si tiene cambios no guardados en su directorio de trabajo cuando intenta fusionarlos, algunos de estos consejos pueden ayudarlo a perder ese trabajo.
Veamos un ejemplo muy simple. Tenemos un archivo Ruby super simple que imprime 'hello world'.
#! /usr/bin/env ruby
def hello
puts 'hello world'
end
hello()
En nuestro repositorio, creamos una nueva rama llamada whitespace
y procedemos a cambiar todas las terminaciones de línea de Unix a terminaciones de línea de DOS, esencialmente cambiando cada línea del archivo, pero solo con espacios en blanco. Luego cambiamos la línea "hello world" a "hello mundo".
$ git checkout -b whitespace
Switched to a new branch 'whitespace'
$ unix2dos hello.rb
unix2dos: converting file hello.rb to DOS format ...
$ git commit -am 'converted hello.rb to DOS'
[whitespace 3270f76] converted hello.rb to DOS
1 file changed, 7 insertions(+), 7 deletions(-)
$ vim hello.rb
$ git diff -w
diff --git a/hello.rb b/hello.rb
index ac51efd..e85207e 100755
--- a/hello.rb
+++ b/hello.rb
@@ -1,7 +1,7 @@
#! /usr/bin/env ruby
def hello
- puts 'hello world'
+ puts 'hello mundo'^M
end
hello()
$ git commit -am 'hello mundo change'
[whitespace 6d338d2] hello mundo change
1 file changed, 1 insertion(+), 1 deletion(-)
Ahora volvemos a nuestra rama master
y agregamos cierta documentación para la función.
$ git checkout master
Switched to branch 'master'
$ vim hello.rb
$ git diff
diff --git a/hello.rb b/hello.rb
index ac51efd..36c06c8 100755
--- a/hello.rb
+++ b/hello.rb
@@ -1,5 +1,6 @@
#! /usr/bin/env ruby
+# prints out a greeting
def hello
puts 'hello world'
end
$ git commit -am 'document the function'
[master bec6336] document the function
1 file changed, 1 insertion(+)
Ahora tratamos de fusionarnos en nuestra rama whitespace
y tendremos conflictos debido a los cambios en el espacio en blanco.
$ git merge whitespace
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Automatic merge failed; fix conflicts and then commit the result.
Ahora tenemos algunas opciones. Primero, cubramos cómo salir de esta situación. Si tal vez no esperabas conflictos y aún no quieres lidiar con la situación, simplemente puedes salir de la fusión con git merge --abort
.
$ git status -sb
## master
UU hello.rb
$ git merge --abort
$ git status -sb
## master
La opción git merge --abort
intenta volver a su estado antes de ejecutar la fusión. Los únicos casos en los que podría no ser capaz de hacer esto a la perfección serían si hubiera realizado cambios sin stash, no confirmados en su directorio de trabajo cuando lo ejecutó, de lo contrario, debería funcionar bien.
Si por alguna razón se encuentra en un estado horrible y solo quiere comenzar de nuevo, también puede ejecutar git reset --hard HEAD
o donde quiera volver. Recuerde, una vez más, que esto hará volar su directorio de trabajo, así que asegúrese de no querer ningún cambio allí.
En este caso específico, los conflictos están relacionados con el espacio en blanco. Sabemos esto porque el caso es simple, pero también es muy fácil saberlo en casos reales, al analizar el conflicto, porque cada línea se elimina por un lado y se agrega nuevamente por el otro. De manera predeterminada, Git ve que todas estas líneas están siendo modificadas, por lo que no puede fusionar los archivos.
Sin embargo, la estrategia de combinación predeterminada puede tomar argumentos, y algunos de ellos son acerca de ignorar adecuadamente los cambios del espacio en blanco. Si ve que tiene muchos problemas con espacios en blanco en una combinación, simplemente puede cancelarla y volverla a hacer, esta vez con -Xignore-all-space
o` -Xignore-space-change`. La primera opción ignora los cambios en cualquier cantidad de espacios en blanco existentes, la segunda ignora por completo todos los cambios de espacios en blanco.
$ git merge -Xignore-all-space whitespace
Auto-merging hello.rb
Merge made by the 'recursive' strategy.
hello.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Dado que en este caso, los cambios reales del archivo no eran conflictivos, una vez que ignoramos los cambios en los espacios en blanco, todo se fusiona perfectamente.
Esto es un salvavidas si tiene a alguien en su equipo a quien le gusta ocasionalmente reformatear todo, desde espacios hasta pestañas o viceversa.
Aunque Git maneja muy bien el preprocesamiento de espacios en blanco, hay otros tipos de cambios que quizás Git no pueda manejar de manera automática, pero que son correcciones de secuencias de comandos. Como ejemplo, imaginemos que Git no pudo manejar el cambio en el espacio en blanco y que teníamos que hacerlo a mano.
Lo que realmente tenemos que hacer es ejecutar el archivo que intentamos fusionar a través de un programa dos2unix
antes de intentar fusionar el archivo. Entonces, ¿cómo haríamos eso?
Primero, entramos en el estado de conflicto de la fusión. Luego queremos obtener copias de mi versión del archivo, su versión (de la rama en la que nos estamos fusionando) y la versión común (desde donde ambos lados se bifurcaron). Entonces, queremos arreglar su lado o nuestro lado y volver a intentar la fusión sólo para este único archivo.
Obtener las tres versiones del archivo es bastante fácil. Git almacena todas estas versiones en el índice bajo etapas'', cada una de las cuales tiene números asociados. La etapa 1 es el ancestro común, la etapa 2 es su versión y la etapa 3 es de la
suya'').MERGE_HEAD
, la versión en la que se está fusionando (
Puede extraer una copia de cada una de estas versiones del archivo en conflicto con el comando git show
y una sintaxis especial.
$ git show :1:hello.rb > hello.common.rb
$ git show :2:hello.rb > hello.ours.rb
$ git show :3:hello.rb > hello.theirs.rb
Si quiere ponerse un poco más intenso, también puede usar el comando de plomería ls-files -u
para obtener el verdadero SHA-1s de las manchas de Git para cada uno de los archivos.
$ git ls-files -u
100755 ac51efdc3df4f4fd328d1a02ad05331d8e2c9111 1 hello.rb
100755 36c06c8752c78d2aff89571132f3bf7841a7b5c3 2 hello.rb
100755 e85207e04dfdd5eb0a1e9febbc67fd837c44a1cd 3 hello.rb
El :1:hello.rb
es solo una clave para buscar esa mancha SHA-1.
Ahora que tenemos el contexto de estas tres etapas en nuestro directorio de trabajo, manualmente podemos arreglarlos para solucionar los problemas de espacios en blanco y volver a fusionar el archivo con el poco conocido comando git merge-file
que hace exactamente eso.
$ dos2unix hello.theirs.rb
dos2unix: converting file hello.theirs.rb to Unix format ...
$ git merge-file -p \
hello.ours.rb hello.common.rb hello.theirs.rb > hello.rb
$ git diff -w
diff --cc hello.rb
index 36c06c8,e85207e..0000000
--- a/hello.rb
+++ b/hello.rb
@@@ -1,8 -1,7 +1,8 @@@
#! /usr/bin/env ruby
+# prints out a greeting
def hello
- puts 'hello world'
+ puts 'hello mundo'
end
hello()
En este punto hemos, agradablemente, fusionado el archivo. De hecho, esto en realidad funciona mejor que la opción de ignore-all-space
, porque realmente soluciona los cambios de los espacios en blanco antes de la fusión, en lugar de simplemente ignorarlo. En la fusión `ignore-all-space, en realidad, terminamos con unas pocas líneas con finales de línea DOS, haciendo que las cosas se mezclen.
Si quiere tener una idea antes de finalizar este compromiso sobre qué había cambiado en realidad entre un lado y el otro, puede pedirle a git diff
que compare qué hay en su directorio de trabajo que está a punto de comprometer como resultado de la fusión a cualquiera de estas etapas. Vamos a través de todas ellas.
Para comparar el resultado con lo que tenías en su rama antes de la fusión, en otras palabras, para ver lo que su fusión insertó, puede correr git diff --ours
$ git diff --ours
* Unmerged path hello.rb
diff --git a/hello.rb b/hello.rb
index 36c06c8..44d0a25 100755
--- a/hello.rb
+++ b/hello.rb
@@ -2,7 +2,7 @@
# prints out a greeting
def hello
- puts 'hello world'
+ puts 'hello mundo'
end
hello()
Así, podemos observar fácilmente lo que sucedió en nuestra rama, y si lo que en realidad estamos insertando a este archivo con esta fusión está cambiando solamente esa línea.
Si queremos ver cómo el resultado de la fusión difiere de lo que estaba del otro lado, podemos correr git diff --theirs
. En este y el siguiente ejemplo, tenemos que usar -w
para despojarlo de los espacios en blanco porque lo estamos comparando con lo que está en Git, no con nuestro archivo limpio hello.theirs.rb
$ git diff --theirs -w
* Unmerged path hello.rb
diff --git a/hello.rb b/hello.rb
index e85207e..44d0a25 100755
--- a/hello.rb
+++ b/hello.rb
@@ -1,5 +1,6 @@
#! /usr/bin/env ruby
+# prints out a greeting
def hello
puts 'hello mundo'
end
Finalmente, puede observar cómo el archivo ha cambiado desde ambos lados con git diff --base
.
$ git diff --base -w
* Unmerged path hello.rb
diff --git a/hello.rb b/hello.rb
index ac51efd..44d0a25 100755
--- a/hello.rb
+++ b/hello.rb
@@ -1,7 +1,8 @@
#! /usr/bin/env ruby
+# prints out a greeting
def hello
- puts 'hello world'
+ puts 'hello mundo'
end
hello()
En este punto podemos usar el comando git clean
para limpiar los archivos sobrantes que creamos para hacer la fusión manual, pero que ya no necesitamos.
$ git clean -f
Removing hello.common.rb
Removing hello.ours.rb
Removing hello.theirs.rb
Tal vez en este punto no estemos felices con la resolución por alguna razón, o quizás manualmente editando uno o ambos lados todavía no funciona como es debido y necesitamos más contexto.
Cambiemos el ejemplo un poco. En este caso, tenemos dos ramas de larga vida las cuales cada una tiene unos pocos ``commit'' en ella, aparte de crear un contenido de conflicto legítimo cuando es fusionado.
$ git log --graph --oneline --decorate --all
* f1270f7 (HEAD, master) update README
* 9af9d3b add a README
* 694971d update phrase to hola world
| * e3eb223 (mundo) add more tests
| * 7cff591 add testing script
| * c3ffff1 changed text to hello mundo
|/
* b7dcc89 initial hello world code
Ahora tenemos tres `commit'' únicos que viven solo en la rama `principal
y otros tres que viven en la rama mundo
. Si intentamos fusionar la rama mundo
, generaremos un conflicto.
$ git merge mundo
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Automatic merge failed; fix conflicts and then commit the result.
Nos gustaría ver cuál es el conflicto de fusión. Si abrimos el archivo, veremos algo así:
#! /usr/bin/env ruby
def hello
<<<<<<< HEAD
puts 'hola world'
=======
puts 'hello mundo'
>>>>>>> mundo
end
hello()
Ambos lados de la fusión han añadido contenido a este archivo, pero algunos de los ``commit'' han modificado el archivo en el mismo lugar que causó el conflicto.
Exploremos un par de herramientas que ahora tiene a su disposición para determinar cómo el conflicto resultó ser. Tal vez, no es tan obvio cómo exactamente debería solucionar este problema. Necesita más contexto.
Una herramienta útil es git checkout
con la opción ``--conflict''. Esto revisará el archivo de nuevo y reemplazará los marcadores de conflicto de la fusión. Esto puede ser útil si quiere reiniciar los marcadores y tratar de resolverlos de nuevo.
Puedes pasar --conflict
en lugar de diff3
o merge
(lo que es por defecto). Si pasa diff3
, Git usará una versión un poco diferente de marcadores de conflicto, no solo dándole ours'' versión y la versión de
theirs'', sino también la versión ``base'' en línea para darle más contexto.
$ git checkout --conflict=diff3 hello.rb
Una vez que corremos eso, en su lugar el archivo se verá así:
#! /usr/bin/env ruby
def hello
<<<<<<< ours
puts 'hola world'
||||||| base
puts 'hello world'
=======
puts 'hello mundo'
>>>>>>> theirs
end
hello()
Si este formato es de su agrado, puede configurarlo como `default'' para futuros conflictos de fusión al colocar el `merge.conflictstyle
configurándolo a diff3
.
$ git config --global merge.conflictstyle diff3
El comando git checkout
puede también tomar la opción de --theirs`o la `--ours
, lo cual puede ser una manera mucho más rápida de escoger un lado o el otro sin tener que fusionar las cosas en lo absoluto.
Esto puede ser particularmente útil para conflictos de archivos binarios donde simplemente puede escoger un lado, o donde solo quiere fusionar ciertos archivos desde otra rama – puede hacer la fusión y luego revisar ciertos archivos de un lado o del otro antes de comprometerlos
Otra herramienta útil al resolver conflictos de fusión es git log
. Esto puede ayudarle a tener contexto de lo que pudo haber contribuido a los conflictos. Revisar un poco el historial para recordar por qué dos líneas de desarrollo estaban tocando el mismo código de área, puede ser muy útil algunas veces.
Para obtener una lista completa de commit'' únicos que fueron incluidos en cualquiera de las ramas involucradas en esta fusión, podemos usar la sintaxis
triple dot'' (triple punto) que aprendimos en [r_triple_dot].
$ git log --oneline --left-right HEAD...MERGE_HEAD
< f1270f7 update README
< 9af9d3b add a README
< 694971d update phrase to hola world
> e3eb223 add more tests
> 7cff591 add testing script
> c3ffff1 changed text to hello mundo
Esa es una buena lista de los seis compromisos involucrados, así como en qué línea de desarrollo estuvo cada compromiso.
Sin embargo, podemos simplificar aún más esto para darnos un contexto mucho más específico. Si añadimos la opción --merge
a git log
, solo mostrará los compromisos en cualquier lado de la fusión que toque un archivo que esté actualmente en conflicto.
$ git log --oneline --left-right --merge
< 694971d update phrase to hola world
> c3ffff1 changed text to hello mundo
En su lugar, si corremos eso con la opción -p
obtendremos sólo los diffs del archivo que terminó en conflicto. Esto puede ser bastante útil, al darle rápidamente el contexto que necesita para ayudarle a entender por qué algo crea problemas y cómo resolverlo de una forma más inteligente.
Dado que las etapas de Git clasifican los resultados que tienen éxito, cuando corre git diff
mientras está en un estado de conflicto de fusión, sólo puede obtener lo que está actualmente en conflicto. Esto puede ser útil para ver lo que todavía debe resolver.
Cuando corre directamente git diff
después de un conflicto de fusión, le dará la información en un formato de salida diff bastante único.
$ git diff
diff --cc hello.rb
index 0399cd5,59727f0..0000000
--- a/hello.rb
+++ b/hello.rb
@@@ -1,7 -1,7 +1,11 @@@
#! /usr/bin/env ruby
def hello
++<<<<<<< HEAD
+ puts 'hola world'
++=======
+ puts 'hello mundo'
++>>>>>>> mundo
end
hello()
El formato es llamado Diff combinado'' y proporciona dos columnas de datos al lado de cada línea. La primera columna muestra si esa línea es diferente (añadida o removida) entre la rama
ours'' y el archivo en su directorio de trabajo, y la segunda columna hace lo mismo entre la rama ``theirs'' y la copia de su directorio de trabajo.
Así que en ese ejemplo se puede observar que las líneas <<<<<<< y >>>>>>> están en la copia de trabajo, pero no en ningún lado de la fusión. Esto tiene sentido porque la herramienta de fusión las mantiene ahí para nuestro contexto, pero se espera que las removamos.
Si resolvemos el conflicto y corremos git diff
de nuevo, veremos la misma cosa, pero es un poco más útil.
$ vim hello.rb
$ git diff
diff --cc hello.rb
index 0399cd5,59727f0..0000000
--- a/hello.rb
+++ b/hello.rb
@@@ -1,7 -1,7 +1,7 @@@
#! /usr/bin/env ruby
def hello
- puts 'hola world'
- puts 'hello mundo'
++ puts 'hola mundo'
end
hello()
Esto muestra que hola mundo'' estaba de nuestro lado, pero no en la copia de trabajo, que
hello mundo'' estaba en el lado de ellos, pero no en la copia de trabajo y finalmente que ``hola mundo'' no estaba en ningún lado, sin embargo está ahora en la copia de trabajo. Esto puede ser útil para revisar antes de comprometer la resolución.
También se puede obtener desde el git log
para cualquier fusión después de realizada, para ver cómo algo se resolvió luego de dicha fusión. Git dará salida a este formato si se puede correr git show
en un compromiso de fusión, o si se añade la opción --cc
a un git log -p
(el cual por defecto solo muestras parches para compromisos no fusionados).
$ git log --cc -p -1
commit 14f41939956d80b9e17bb8721354c33f8d5b5a79
Merge: f1270f7 e3eb223
Author: Scott Chacon <[email protected]>
Date: Fri Sep 19 18:14:49 2014 +0200
Merge branch 'mundo'
Conflicts:
hello.rb
diff --cc hello.rb
index 0399cd5,59727f0..e1d0799
--- a/hello.rb
+++ b/hello.rb
@@@ -1,7 -1,7 +1,7 @@@
#! /usr/bin/env ruby
def hello
- puts 'hola world'
- puts 'hello mundo'
++ puts 'hola mundo'
end
hello()
Ahora que ya conoce como crear un ``merge commit'' (compromiso de fusión), probablemente haya creado algunos por error. Una de las ventajas de trabajar con Git es que está bien cometer errores, porque es posible y, en muchos casos, es fácil solucionarlos.
Los compromisos de fusión no son diferentes.
Digamos que comenzó a trabajar en una rama temática accidentalmente fusionada en una rama master
, y ahora el historial de compromiso se ve así:
Existen dos formas de abordar este problema, dependiendo de cuál es el resultado que desea.
Si el compromiso de fusión no deseado solo existe en su repositorio local, la mejor y más fácil solución es mover las ramas para que así apunten a dónde quiere que lo hagan.
En la mayoría de los casos si sigue al errante git merge
con git reset --hard HEAD~
, esto restablecerá los punteros de la rama, haciendo que se vea así:
Ya vimos reset
de nuevo en [r_git_reset], así que no debería ser muy difícil averiguar lo que está sucediendo.
Aquí un repaso rápido: reset --hard
usualmente va a través de tres pasos:
-
Mover los puntos de la rama HEAD. En este caso, se quiere mover la
principal`a donde se encontraba antes el compromiso de fusión (`C6
). -
Hacer que el índice parezca HEAD.
-
Hacer que el directorio de trabajo parezca el índice.
La desventaja de este enfoque es que se reescribirá el historial, lo cual puede ser problemático con un depósito compartido.
Revise ch03-git-branching.asc para saber más de lo que puede suceder; la versión corta es que, si otras personas tienen los compromisos que está reescribiendo, probablemente debería evitar resetear
.
Este enfoque tampoco funcionará si cualquiera de los otros compromisos han sido creados desde la fusión; mover los refs efectivamente perdería esos cambios.
Si mover los punteros de la rama alrededor no funciona para su caso, Git le proporciona la opción de hacer un compromiso (commit'') nuevo que deshace todos los cambios de uno ya existente.
Git llama a esta operación un
revert'', y en este escenario en particular, ha invocado algo así:
$ git revert -m 1 HEAD
[master b1d8379] Revert "Merge branch 'topic'"
La bandera -m 1
indica cuál padre es el `mainline'' y debería ser mantenido.
Cuando se invoque la fusión en el `HEAD
(git merge topic
), el nuevo compromiso tiene dos padres: el primero es HEAD
(C6
), y el segundo es la punta de la rama siendo fusionada en (C4
).
En este caso, se quiere deshacer todos los cambios introducidos por el fusionamiento en el padre #2 (C4
), pero manteniendo todo el contenido del padre #1 (C6
).
El historial con el compromiso revertido se ve así:
El nuevo compromiso ^M
tiene exactamente los mismos contenidos que C6
, así que comenzando desde aquí es como si la fusión nunca hubiese sucedido, excepto que ahora los no fusionados compromisos están todavía en HEAD’s history.
Git se confundirá si intenta fusionar la rama `temática
en la rama master
:
$ git merge topic
Already up-to-date.
No hay nada en topic
que no sea ya alcanzable para la master
.
Que es peor, si añade trabajo a topic
y fusiona otra vez, Git solo traerá los cambios desde la fusión revertida:
La mejor forma de evitar esto es deshacer la fusión original, dado que ahora se quiere traer los cambios que fueron revertidos, luego crear un nuevo compromiso de fusión:
$ git revert ^M
[master 09f0126] Revert "Revert "Merge branch 'topic'""
$ git merge topic
En este ejemplo, M
y ^M
se cancelan.
Efectivamente ^^M
se fusiona en los cambios desde C3
y C4
, y C8
se fusiona en los cambios desde C7
, así que ahora topic
está completamente fusionado.
Hasta hora ya cubrimos la fusión normal de dos ramas, normalmente manejado con lo que es llamado la estrategia de fusión ``recursive''. Sin embargo, hay otras formas de fusionar a las ramas. Cubriremos algunas de ellas rápidamente.
Primero que nada, hay otra cosa útil que podemos hacer con el modo de fusión `recursive''. Ya vimos las opciones `ignore-all-space
e ignore-space-change
las cuales son pasadas con un -X
, pero también le podemos decir a Git que favorezca un lado u otro cuando observe un conflicto.
Por defecto, cuando Git ve un conflicto entre dos ramas siendo fusionadas, añadirá marcadores de conflicto de fusión a los códigos, marcará el archivo como conflictivo y le dejará resolverlo. Si prefiere que Git simplemente escoja un lado específico e ignore el otro, en lugar de dejarle manualmente fusionar el conflicto, puede pasar el comando de fusión, ya sea on un -Xours
o -Xtheirs
.
Si Git ve esto, no añadirá marcadores de conflicto. Cualquier diferencia que pueda ser fusionable, se fusionará. Cualquier diferencia que entre en conflicto, él simplemente escogerá el lado que especifique en su totalidad, incluyendo los archivos binarios.
Si volvemos al ejemplo de ``hello world'' que estábamos utilizando antes, podemos ver que el fusionamiento en nuestra rama causa conflicto.
$ git merge mundo
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Resolved 'hello.rb' using previous resolution.
Automatic merge failed; fix conflicts and then commit the result.
Sin embargo, si lo corremos con -Xours
o -Xtheirs
no lo causa.
$ git merge -Xours mundo
Auto-merging hello.rb
Merge made by the 'recursive' strategy.
hello.rb | 2 +-
test.sh | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
create mode 100644 test.sh
En este caso, en lugar de obtener marcadores de conflicto en el archivo con hello mundo'' en un lado y
hola world'' en el otro, simplemente escogerá ``hola world''. Sin embargo, todos los cambios no conflictivos en esa rama se fusionaron exitosamente.
Esta opción también puede ser trasmitida al comando git merge-file
que vimos antes al correr algo como esto git merge-file --ours
para archivos de fusión individuales.
Si quiere realizar algo así, pero Git no ha intentado siquiera fusionar cambios desde el otro lado, hay una opción más draconiana, la cual es la estrategia de fusión ours'' merge strategy. Esto es diferente de la opción de fusión recursiva
ours'' recursive merge _option.
Esto básicamente hace una fusión falsa. Registrará un nuevo compromiso de fusión con ambas ramas como padres, pero ni siquiera mirará a la rama que está fusionando. Simplemente registrará como el resultado de la fusión el código exacto en su rama actual.
$ git merge -s ours mundo
Merge made by the 'ours' strategy.
$ git diff HEAD HEAD~
$
Puede observar que no hay diferencia entre la rama en la que estábamos y el resultado de la fusión.
Esto a menudo puede ser útil para, básicamente, engañar a Git y que piense que una rama ya ha sido fusionada cuando se hace una fusión más adelante. Por ejemplo, decir que ha ramificado una rama de release'' y ha hecho un poco de trabajo que querrá fusionar de vuelta en su rama
master'' en algún punto.
Mientras tanto, algunos arreglos de fallos en la master'' necesitan ser adaptados en la rama de
bugfix'' en la de release
. Se puede fusionar la rama release
y también merge -s ours
, la misma rama en la principal (a pesar de que el arreglo ya se encuentre ahí). Así que, más tarde cuando fusione la de lanzamiento otra vez, no hay conflictos del ``bugfix''.