Fusionar una rama en Master en Git
- Prerrequisitos
- Preparación para fusionar en Git
-
Fusionar una rama en Master con el método
merge
en Git -
Fusionar una rama en la maestra con el método
rebase
- Conclusión
Una de las características más poderosas de git es la operación de creación y fusión de ramas. Git permite a los usuarios crear una nueva rama y fusionarlas en el código de desarrollo. Esta característica mejora el flujo de trabajo del proceso de desarrollo para múltiples proyectos al fomentar tareas más específicas, más pequeñas y granulares.
En este artículo del tutorial, discutiremos diferentes enfoques para fusionar la rama de características de git con master.
La principal ventaja de git es su sistema de ramificación. ¡Es en estas ramas donde descansa toda la magia de GIT! La rama maestra llevará todas las modificaciones realizadas. Por lo tanto, el objetivo no es realizar las modificaciones directamente en esta rama, sino hacerlas en otras ramas y, después de varias pruebas, integrarlas en la rama maestra.
En nuestro tutorial para simplificar, consideremos que hay dos ramas, la rama master
y la rama de características conocida como feature-1
. La rama principal es la rama maestra que contiene el código de producción, y la segunda rama es donde se ejecutarán las modificaciones o se implementarán nuevas características. Al final, si se aprueba una función o un error, se fusionará con el maestro.
Comencemos la demostración de la fusión de dos ramas con un ejemplo real. Para empezar, necesitamos lo siguiente.
Prerrequisitos
Crea un repositorio en GitHub
Se puede crear un repositorio inicial como se introdujo en Github
A continuación, agregue dos archivos en la rama Master usando el botón Agregar archivo
en la página del repositorio. Los nombres de los archivos son los siguientes.
file1.txt
file2.txt
En este ejemplo, el siguiente contenido de texto se agrega a file1.txt y file 2.txt, respectivamente.
$ cat file1.txt
This is dummy text line 1
This is dummy text line 2
$ cat file2.txt
This is dummy test in 2nd file
Repositorio de clonación
A continuación, clone su repositorio recién creado desde GitHub en su sistema para crear una copia local del código. La URL de clonación se puede recuperar desde el botón Código
como se muestra a continuación.
Utilice el siguiente comando para clonar.
$ git clone git@github.com:project/demorepo.git
Una vez clonado con éxito, use el siguiente comando para mostrar y verificar el contenido de los archivos de la rama maestra:
$ cat file1.txt
This is dummy text line 1
This is dummy text line 2
$ cat file2.txt
This is dummy test in 2nd file
Crear rama de características
$ git branch feature-1
Este comando crea una nueva rama y no crea un nuevo commit en git.
Rama de funciones de pago
Anteriormente, creamos una nueva rama usando git branch feature-1
. Pero la rama activa es la rama master
. Para activar la nueva rama, use este comando en la terminal:
$ git checkout feature-1
Switched to branch 'feature-1'
El comando anterior cambiará la rama activa de master
a feature-1
. Ahora, esta rama está lista para el desarrollo individual.
Modificar archivos en la rama de funciones
Agregaremos algunas commits o agregaremos nuevas líneas en la rama feature-1
. En este caso, file2.txt
se modificará localmente y luego se fusionará de nuevo en la rama maestra.
Para los cambios realizados hasta ahora, nuestro diagrama de commit se verá a continuación. Tanto A como E representan estados de rama master
y feature-1
. Actualmente, los commits A
y E
son las mismas, ya que no se modifican archivos durante la comprobación.
A ← master
\
E ← feature-1
Ahora, file1.txt
se actualiza con nuevo texto. Utilice este comando para actualizar el contenido.
$ echo "file update in feature branch" > file1.txt
Ahora, file2.txt
tiene el siguiente contenido.
$ cat file2.txt
This is dummy test in 2nd file
La diferencia entre el contenido antiguo y el nuevo en file1.txt
se puede verificar usando el siguiente comando.
$ git diff
diff --git a/file1.txt b/file1.txt
index 11d66d4..48c9378 100644
--- a/file1.txt
+++ b/file1.txt
@@ -1,2 +1 @@
-This is dummy text line 1
-This is dummy text line 2
+file update in feature branch
Ahora, configure este archivo y cree un commit local a través del siguiente comando.
$ git add file1.txt
$ git commit -am "update file via feature-1"
[feature-1 22b60b8] update file via feature-1
1 file changed, 1 insertion(+), 2 d
Una instantánea actual del árbol de commit se verá a continuación. Aquí F
es un nuevo commit que se crea en el paso anterior.
A ← master
\
E --- F ← feature-1
Para demostrar un ejemplo del mundo real, otros desarrolladores también cambian simultáneamente el master
remoto, y estos cambios se envían como commit C
y commit D
to master.
A --- B --- C --- D ← master
\
E --- F ← feature-1
A continuación se muestra el contenido actualizado de file1.txt
en el repositorio de Github en la rama maestra. Observe que la línea 2 se actualizó y que las líneas 3 y 4 se crearon nuevamente.
Esto también se puede validar localmente visualizando el historial de su rama en el shell de comandos en tiempo real usando el siguiente comando.
$ git fetch
$ git log --all --decorate --oneline --graph
Preparación para fusionar en Git
Con Git, tenemos dos posibilidades para fusionar nuestros cambios de rama de características con la rama remota master
:
-
El método
merge
Gitmerge
es un comando que realiza cambios en otra rama. Permite a los desarrolladores tomar sus líneas de código independientes de la rama de funciones e integrarlas en una sola rama en el maestro a través de la herramienta de combinación de git. -
El método
rebase
Gitrebase
es otro comando que se usa esencialmente para el mismo propósito, excepto que lo hace de manera muy diferente.
Entendamos ambas formas en detalle:
Fusionar una rama en Master con el método merge
en Git
La merge
tiene como objetivo consolidar las ramas feature
y master
en el commit que mantiene el contenido de todas las ramas involucradas. Git logra esto, lo que se conoce como un merge commit
. Esto también significa que merge
manipula múltiples ramas.
Cuando las ramas han divergido, es decir, una no es antepasado de otra. Git puede lograr la fusión realizando un nuevo commit adicional que tenga varios padres. En la siguiente ilustración, si tiene un commit D
y un commit F
en diferentes ramas y mezcla las ramas (a través de git merge
), el resultado es un commit G
cuyos padres son B
y E
.
A --- B --- C --- D ---
\ \
\ G ← master
E --- F --------- /
En el diagrama anterior, G
es un commit recién creada y creada completamente por git. ¡Este compromiso tiene dos padres! y tienen una orden:
- El primer padre es
D
, que anteriormente eramaster
. - El segundo padre es
F
, que anteriormente erafeature-1
.
Este tipo de compromiso se denomina compromiso de fusión.
Ahora regrese a nuestro ejemplo de repositorio y combine la rama feature-1
recién creada con master
.
Primero, revise la rama maestra.
$ git checkout master
Ahora, extraiga los cambios del maestro remoto al master
local.
$ git pull origin master
From github.com:repo/demorepo
* branch master -> FETCH_HEAD
Updating 17cc6b4..a802b6b
Fast-forward
file1.txt | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
Luego, use el siguiente comando para fusionar la rama de características, es decir, feature-1
, con la rama actualmente activa.
$ git merge feature-1
La rama feature-1
se fusionará completamente con la rama master
si este paso se completa con éxito. Sin embargo, si git no puede resolver estos conflictos de combinación automáticamente, fallará con un error de conflictos de combinación.
Este es un escenario muy típico; puede suceder cuando dos ramas modifican la misma parte del archivo y git no puede resolver qué parte usar. Es exactamente lo que sucede con nuestro ejemplo. Este caso se muestra a continuación a través de git.
Auto-merging file1.txt
CONFLICT (content): Merge conflict in file1.txt
Automatic merge failed; fix conflicts and then commit the result.
Siempre que git encuentra un conflicto, agrega <<<<<<<
y =======
para resaltar la sección que causó el conflicto y esto debe resolverse manualmente.
Una vez que se decide qué parte conservar en la versión maestra final del archivo, una persona tiene que eliminar el código irrelevante (incluidos los indicadores de conflicto). Finalmente, envíe los cambios a la rama remota como se muestra a continuación.
$ git add .
$ git commit -am "resolving the mergeconflict"
[master 1acce69] resolving the mergeconflict
$ git push
De esta manera, la rama feature-1
se fusiona con éxito con el master
remoto.
A continuación, verificaremos el historial de la rama nuevamente con el siguiente comando.
git log --all --decorate --oneline --graph
Podemos verificar que git merge
ha creado un Merge Commit
con commit-id como 1acce69
para fusionar la rama feature-1
con origin/master
.
Fusionar una rama en la maestra con el método rebase
Una vez más, considere la situación en la que nuestras ramas principales y de funciones no están sincronizadas y deben fusionarse. Recordemos también la ilustración que muestra esta situación anteriormente.
A --- B --- C --- D ← master
\
E --- F ← feature-1
Como una forma alternativa de fusionar, puede fusionar la rama feature-1
en la rama master
con la opción de rebase. La rebase
unifica las ramas involucradas simplemente colocando los commits de la rama de características delante de la rama maestra.
Esto se logrará a través de los siguientes comandos,
git checkout master
git pull
git checkout feature-1
git rebase master
Podemos tener la siguiente ilustración después de ejecutar rebase.
A --- B --- C --- D----(operation rebase)----- E--------F ← master
En la ilustración de arriba, es visible que algo bueno que hace rebase
es producir un historial de commits lineal, más limpio y más fácil de leer. Al fusionar, tampoco genera ese extraño merge commit
adicional.
La desventaja de este enfoque es que rebase cambia la estructura completa de las ramas involucradas, incluida la reescritura del historial de commit de estas ramas. Como rebase
no crea un merge commit
, no obtiene la trazabilidad de cuándo se fusionaron dos ramas, ya que rebase genera una rama lineal al final del proceso.
Conclusión
Ambos comandos son muy útiles; sin embargo, en diferentes situaciones, cada lado tiene las siguientes ventajas.
Git rebase
- Optimice una historia compleja.
- Evite fusionar el ruido de commit en repositorios con ramas ocupadas.
- Es arriesgado si no se usa correctamente, ya que no conserva la historia.
Git merge
- Fácil de usar.
- Como se crea un commit de fusión adicional cada vez, hace que el historial de commits se vea confuso y sucio.
- Conserva la historia completa y el orden cronológico.