Git Merge
El comando git merge
fusionará cualquier cambio que se haya hecho en la base de código en una rama separada de tu rama actual como un nuevo commit.
La sintaxis del comando es la siguiente:
git merge NOMBRE-DE-LA-RAMA
Por ejemplo, si estás trabajando actualmente en una rama llamada dev
y deseas fusionar los nuevos cambios que se hayan realizado en una rama llamada new-features
, ejecutarías el siguiente comando:
git merge new-features
Nota: Si hay algún cambio al que no se le ha hecho commit en la rama actual, Git no te permitirá fusionar hasta que se hayan realizado commit todos los cambios en tu rama actual. Para manejar esos cambios, puedes hacer lo siguiente:
Crear una nueva rama y realizar commit a los cambios
git checkout -b nombre-de-la-nueva-rama
git add .
git commit -m "<tu mensaje de commit>"
Guardarlos en el stash
git stash # agregarlos al stash
git merge new-features # fusionarlos
git stash pop # obtén los cambios devuelta al árbol de trabajo (working tree)
Abandonar todos los cambios
git reset --hard # remueve todos los cambios pendientes
Git Rebase
Realizar un rebase a una rama (branch) en Git es una form ade mover la totalidad de una rama a otro punto del árbol. El ejemplo más simple es mover una rama más arriba en el árbol. Digamos que tenemos una rama que se separó de la rama master
en el punto A:
/o-----o---o--o-----o--------- branch
--o-o--A--o---o---o---o----o--o-o-o--- master
Cuando se realiza rebase se puede mover así:
/o-----o---o--o-----o------ branch
--o-o--A--o---o---o---o----o--o-o-o master
Para realizar rebase, asegúrate de tener todos los commits que quieras en el rebase en tu rama master
. Revisar la rama en la que quieres hacer el rebase y escribe git rebase master
(donde master
es la rama en la que quieres hacer el rebase).
También es posible hacer rebase en una rama diferente, de modo que, por ejemplo, una rama que se basaba en otra rama (llamémosla feature
) se rebasa en master
:
/---o-o branch
/---o-o-o-o---o--o------ feature
----o--o-o-A----o---o--o-o-o--o--o- master
Después de git rebase master branch
o git rebase master
si te encuentras (checked out) en branch
, obtendrás:
/---o-o-o-o---o--o------ feature
----o--o-o-A----o---o--o-o-o--o--o- master
\---o-o branch
Git rebase interactivo en la consola
Para usar git rebase
en la consola con una lista de commits, puedes elegir, editar o soltar en el rebase:
- Introduce
git rebase -i HEAD~5
con el último número que sea cualquier número de commits del más reciente hacia atrás que quieras revisar. - En vim, presiona
esc
, luegoi
para empezar a editar la prueba. - A la izquierda puedes sobreescribir
pick
con uno de los comandos de abajo. Si quieres aplastar (squash) un commit a uno anterior y descartar el mensaje de commit, introducef
en lugar depick
en el commit. - Guarda y sal del editor de texto.
- Cuando se detiene a rebase, haz los ajustes necesarios, y luego usa
git rebase --continue
hasta que el rebase sea exitoso. - Si el rebase es exitoso, entonces necesitas forzar el push de tus cambios con
git push -f
para agregar la versión con rebase a tu repositorio remoto. - Si hay un «merge conflict» (conflicto al querer fusionar las ramas), hay varias maneras de arreglarlo, incluyendo seguir las sugerencias de esta guía. Una forma es abrir los archivos en un editor de texto y eliminar las partes del código que no quieras. Luego usa
git add <file name>
seguido degit rebase --continue
. Puedes saltarte el commit de conflicto ejecutandogit rebase --skip
, para el rebase ejecutandogit rebase --abort
en tu consola.
pick 452b159 <message for this commit>
pick 7fd4192 <message for this commit>
pick c1af3e5 <message for this commit>
pick 5f5e8d3 <message for this commit>
pick 5186a9f <message for this commit>
# Rebase 0617e63..5186a9f onto 0617e63 (30 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but stop to edit the commit message.
# e, edit = use commit, but stop to amend or add commit.
# s, squash = use commit, meld into previous commit and stop to edit the commit message.
# f, fixup = like "squash", but discard this commit's log message thus doesn't stop.
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
Merge Conflicts
Un merge conflict es cuando realizar commits en ramas separadas que alteran la misma línea de manera conflictiva. Si esto ocurre, Git no sabrá que versión del archivo guardar en un mensaje de error similar al siguiente:
CONFLICT (content): Merge conflict in resumé.txt Automatic merge failed; fix conflicts and then commit the result.
Si miras el archivo resumé.txt
en tu editor de texto, puedes ver dónde tuvo lugar el conflicto:
<<<<<<< HEAD
Address: 808 South Street
=======
Address: 505 North Street
>>>>>>> updated_address
Git agregó algunas líneas adicionales en el archivo:
<<<<<<< HEAD
=======
>>>>>>> updated_address
Piensa en =======
como la línea divisoria del conflicto. Todo lo que hay entre <<<<<<< HEAD
y =======
es el contenido de la rama actual a la que apunta HEAD ref. Por otro lado, todo lo que hay entre =======
y >>>>>>> updated_address
es el contenido de la rama que se está fusionando, updated_address
.
Git Merge vs Git Rebase
Tanto git merge
como git rebase
son comandos muy útiles, y uno no es mejor que el otro. Sin embargo, hay algunas diferencias muy importantes entre los dos comandos que tú y tu equipo deben tener en cuenta.
Cada vez que se ejecuta git merge
, se crea un merge commit extra. Siempre que trabajes en tu repositorio local, tener demasiados merge commits puede hacer que el historia del commits parezca confuso. Una forma de evitar el merge commit es usar git rebase
en su lugar.
git rebase
es una característica muy poderosa. Dicho esto, también es arriesgado si no se usa de la manera correcta. git rebase
altera el historial de commits, así que úsalo con cuidado. Si el rebase se hace en el repositorio remoto, entonces puede crear muchos problemas cuando otros desarrolladores intentan sacar los últimos cambios de código del repositorio remoto. Recuerda que sólo debes ejecutar git rebase
en un repositorio local.