Una de las preguntas más habituales que se hacen en los cursos de git que imparto regularmente, y que también se me ha planteado en algunas de las reuniones de desarrolladores en las que participo es la siguiente: ¿Cómo evito un fast-forward para dejar constancia en el repositorio de dónde empieza y termina una rama?
Forzar merge commits
Lo más claro, como siempre, es verlo con un ejemplo. Imaginad que llegáis por la mañana al trabajo y empezáis como siempre a picar código como locos en la rama devel. De repente surge la necesidad de atender un bug. Siguiendo las buenas prácticas, lo que haremos será crear una rama HotFix, arreglar el problema haciendo cuantos commits necesitemos a esa rama y finalmente hacer un merge a la rama que corresponda cuando terminemos de corregir el bug.
En la siguiente captura se muestra el estado del repositorio justo después de haber hecho el último commit a la rama hotfix_14523 que arregla el problema en cuestión:
Si en este momento se hace un merge de la rama hotfix_15423 a la rama devel, se hará un fast-forward:
$ git checkout devel
$ git merge hotfix_15423
Updating 2d1d1c4..2b9d126
Fast-forward
Gemfile | 2 ++
app/views/home/.erb | 1 +
2 files changed, 3 insertions(+)
Así queda el grafo después de hacer el merge:
Como vemos, mirando la historia del repositorio, no queda constancia de cuándo se empezó el desarrollo de la rama hotfix_15423 y cuándo se incorporó a la rama devel. Una solución podría ser etiquetar los commits correspondientes, como se muestra en la siguiente captura:
Esta solución es válida cuando tenemos pocas ramas. Si tenemos muchas ramas de las que queramos saber su inicio y final, podemos acabar con un número de etiquetas difícil de gestionar.
Forzar un merge commit
Volvamos a la situación inicial:
$ git reset --hard 2d1d1c4 HEAD is now at 2d1d1c4 Update README.rdoc
En esta situación, volvemos a ejecutar el merge de la siguiente forma:
$ git merge --no-ff hotfix_15423 -m'Incorporando rama hotfix_15423'
Merge made by the 'recursive' strategy.
Gemfile | 2 ++
app/views/home/.erb | 1 +
2 files changed, 3 insertions(+)
Después de ejecutar el comando, este es el estado del repositorio:
Haciéndolo de esta forma, en lugar de hacerse un fast-forward, vemos que se crea un merge-commit, lo que resulta en una bifurcación que indica claramente el fin y el inicio de la rama hotfix_15423.
Si sois de los que os gusta ver claramente dónde empiezan y terminan vuestras ramas, este pequeño truco es resultará de utilidad.