Saltar al contenido

git merge

Definición

El comando git merge integra líneas independientes de desarrollo en una sola rama. Funciona junto con git checkout para seleccionar la rama actual y git branch con la opción -d para eliminar ramas obsoletas. Lee sobre estos comandos en nuestros capítulos anteriores.

Cómo funciona

El uso principal de git merge es combinar dos ramas. También se usa para integrar varios commits de una rama en otra. En la siguiente ilustración, git merge toma dos puntas de rama y encuentra un commit ancestro común entre ellas. El commit base común se usa para crear un nuevo commit de merge que combina los cambios de ambas ramas. Aquí tenemos dos ramas: master y stage. Debemos fusionar la rama stage en la rama master.

gitmerge

Los commits de merge son únicos porque tienen dos commits padre. Git combina automáticamente historiales separados al crear un nuevo commit de merge. Sin embargo, si ambas ramas modifican las mismas líneas, Git no puede combinarlas automáticamente, lo que da como resultado un conflicto de merge.

gitmerge1

Proceso de fusión

Antes de iniciar el proceso de fusión, sigue estos pasos:

  • Asegúrate de estar en la rama correcta que recibirá la fusión. Ejecuta git checkout <receiving branch> para cambiar a ella.
  • Actualiza la rama de destino con los últimos cambios remotos. Ejecuta git pull para obtener e integrar los últimos commits remotos.
  • El paso final es ejecutar git merge <branch name>, que especifica la rama que se fusionará en la rama receptora.

Fusión fast-forward

Una fusión fast-forward ocurre cuando la ruta desde la rama actual hasta la rama de destino es lineal. La fusión fast-forward combina los historiales, ya que todos los commits alcanzables desde la rama de destino están disponibles a través de la rama actual. Aquí tienes un ejemplo de una fusión fast-forward:

gitmerge2

Cuando los dos historiales divergen, Git usa la fusión de 3 vías como alternativa. La fusión de 3 vías usa un commit dedicado para combinar dos historiales.

gitmerge3

Las fusiones fast-forward suelen usarse para funciones pequeñas o correcciones de errores, mientras que las fusiones de 3 vías se usan para integrar funciones de larga duración. Los siguientes ejemplos usan una fusión fast-forward:

git merge

bash
# Start the stage
git checkout -b stage master
# Edit some files
git add <file>
git commit -m "Start with the stage"
# Edit some files
git add <file>
git commit -m "Finish with the stage"
# Merge in the stage branch
git checkout master
git merge stage
git branch -d stage

Ejecutamos git branch -d para eliminar la rama stage, ya que stage ahora es accesible desde la rama master.

El comando git merge con la opción --no-ff se ejecuta si necesitas un commit de merge durante una fusión fast-forward para fusionar la rama especificada en la rama actual, generando siempre un commit de merge (incluso en el caso de una fusión fast-forward):

git merge --no-ff

bash
git merge --no-ff <branch>

Fusión de 3 vías

Este escenario requiere una fusión de 3 vías cuando la rama master avanza mientras la rama stage aún está en desarrollo. Esto se usa cuando los miembros del equipo trabajan simultáneamente en una función grande:

the git merge command

bash
# Start the stage
git checkout -b stage master
# Edit some files
git add <file>
git commit -m "Start with the stage"
# Edit some files
git add <file>
git commit -m "Finish with the stage"
# Develop the master branch
git checkout master
# Edit some files
git add <file>
git commit -m "Make some super-stable changes to master"
# Merge in the stage branch
git merge stage
git branch -d stage

En el ejemplo anterior, stage sería una función más grande que llevaría mucho tiempo desarrollar, por eso usamos una fusión de 3 vías. Si tu función es pequeña, es mejor usar una fusión fast-forward para evitar que commits innecesarios desordenen el historial del proyecto.

Resolución de conflictos

Al fusionar dos ramas, si se cambia la misma parte del mismo archivo, se producen conflictos de merge porque Git no puede determinar qué versión usar. Cuando esto sucede, Git se detiene antes de crear el commit de merge para permitirte resolver el conflicto. El proceso de fusión de Git usa un flujo de trabajo editar/etiquetar/confirmar para resolver conflictos de merge. Cuando ocurre un conflicto, ejecutar git status mostrará los archivos que necesitan ser resueltos. La siguiente imagen aparecerá cuando se hayan cambiado las mismas partes del archivo example.txt:

git status

bash
On branch master
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both modified: example.txt

Si decides no continuar con la fusión, puedes cancelarla en cualquier momento ejecutando git merge --abort.

Cómo se presentan los conflictos

En caso de conflictos, Git edita el contenido de los archivos afectados con marcas visuales en ambos lados del contenido en conflicto. Los conflictos de merge solo ocurren en el caso de una fusión de 3 vías.

Los marcadores principales son <<<<<<<, ======= y >>>>>>>. Te ayudan a localizar las secciones en conflicto en tus archivos.

git conflicts

bash
here is some content not affected by the conflict
<<<<<<< master
this is conflicted text from master
=======
this is conflicted text from stage branch
>>>>>>> stage

Después de resolver los conflictos, ejecuta git add <file> en el archivo en conflicto para marcarlo como resuelto. A continuación, ejecuta git commit para crear el commit de merge.

Práctica

¿Cuáles son las características y procesos clave involucrados en el comando 'git merge'?

¿Te resulta útil?

Vista previa dual-run — compárala con las rutas Symfony en producción.