Git flow no es un nuevo sistema de control de versiones basado en Git, ni un nuevo cliente para nuestro CVS preferido, es «solo» el método de trabajo estándar de facto, popularizado por Vincent Driessen a principios de 2010 en su conocido artículo «A successful Git branching model«. Este método de trabajo se puede implementar utilizando los comandos habituales de Git, o bien mediante extensiones que nos abstraen de los comandos utilizados y sirven a modo de atajos.
Si adoptamos esta forma de trabajar, tendríamos 2 ramas principales: una rama master, en la que solo tendremos versiones listas para producción, y una rama develop en la que se encuentra el código que estamos desarrollando para la próxima versión. También tendremos ramas auxiliares para añadir nuevas características (ramas feature), preparar la publicación de nuevas versiones (ramas release) y crear parches en caliente de versiones que tenemos en producción actualmente (ramas hotfix).
Inicializar un nuevo repositorio
Para inicializar un nuevo repositorio, listo para ser usado con este modelo, escribiríamos el comando:
git flow init
Esto nos preguntará por el nombre que queremos usar por defecto para las ramas principales y los prefijos a utilizar para las ramas auxiliares y las versiones (también podemos pasar el flag -d
si queremos aceptar los valores por defecto).
Este simple comando, por debajo, crea un repositorio Git vacío si no existe, es decir, ejecuta un git init
de toda la vida; actualiza el fichero .git/config
con los nombres de las ramas y los prefijos especificados, hace un commit inicial vacío, y crea y selecciona la rama develop a partir del estado actual de master (git checkout -b develop master
). Si tenemos curiosidad, podemos ver en cualquier momento los comandos git que invoca git flow pasándole el parámetro --showcommands
Ramas para features
Las ramas feature (característica) sirven para el desarrollo de características nuevas. No es necesario crear ramas feature para hacer cambios mínimos en el código que estemos seguros que pueden ir sin problemas en la próxima versión, como pequeñas correcciones o pequeñas refactorizaciones, pero en general son recomendables.
Para empezar a desarrollar una característica nueva:
git flow feature start caracteristica
Esto crea una rama con nombre feature/caracteristica
que parte de develop, y la selecciona (recordemos que checkout -b
es de por sí un atajo para crear la rama y seleccionarla en un único comando, en lugar de utiizar git branch
y git checkout
):
git checkout -b feature/caracteristica develop
Haremos commits a esta rama hasta que terminemos de desarrollarla como haríamos normalmente:
git commit -am «mi nuevo commit»
Cuando hayamos terminado de desarrollar la característica, podemos hacer un merge de vuelta a la rama de desarrollo con:
git flow feature finish caracteristica
Esto selecciona la rama develop, fusiona (hace un merge) la rama que creamos para desarrollar esa característica de vuelta a develop, y la borra:
git checkout develop
git merge –no-ff feature/caracteristica
git branch -d feature/caracteristica
Publicar/obtener el código de una feature
Si tenemos un repositorio remoto además del local, podemos querer enviar nuestros commits a este repositorio en cualquier momento antes de cerrar la característica, lo que se conoce como hacer push en Git. En Git flow utilizaríamos el comando:
git flow feature publish caracteristica
Esto salta a la rama de la característica por si no es la que estamos apuntando actualmente y hace un push:
git checkout feature/caracteristica
git push origin feature/caracteristica
Si trabajamos con otros programadores y queremos ver lo que han hecho nuestros compañeros, podemos obtener el estado actual haciendo un pull:
git flow feature pull origin caracteristica
Esto salta a esa rama y hace un pull:
git checkout feature/caracteristica
git pull –rebase origin feature/caracteristica
Comandos generales
En general, todos los comandos de Git flow a excepción del git flow init
tienen una forma similar a la que hemos visto para las ramas feature; esto es git flow
, seguido del tipo de rama auxiliar, la operación a realizar, y el identificador de la rama:
git flow [feature/release/hotfix] [start/finish/publish/pull] nombre
Ramas para una release
Estas son ramas en las que realizaremos trabajos menores para preparar la versión para publicación: pequeños commits de última hora, cambios de versiones y ficheros de configuración, etc. Se crea una rama nueva con el identificador de la versión que parte de develop:
git flow release start version
O para crear la versión desde un commit que no sea el último en develop:
git flow release start version commit
Esto se traduce en la creación de una rama con ese nombre basada en develop, y el salto a esa nueva rama:
git checkout -b release/version develop
Haremos los commits necesarios para terminar la versión y cuando hayamos terminado usaremos el comando:
git flow release finish version
Esto fusiona la rama de la release con master, le pone un tag con el número de versión a ese commit del master, fusiona con develop, y borra la rama. Para que se envíe todo al repositorio global una vez fusionada la rama release, habrá que hacer, como siempre, un git push
, con el parámetro --tags
para que se envíen también las etiquetas de las versiones.
Ramas para hotfix
Ramas para corregir errores urgentes en versiones que están en producción. Son similares a las ramas de release, pero para trabajo no planificado.
Como siempre, el comando de creación de la rama tendrá este aspecto:
git flow hotfix start version
Al cerrar el hotfix, se fusiona su rama a develop y master, añadiendo a master un tag con el nombre de la revisión:
git flow hotfix finish version
Ha renacido el blog!! 🙂
¡Esa es la intención! 😀
gracias!, buen post, siempre atento del blog!
Muchas gracias Peter! 😀