Git flow

De ChuWiki


Qué es git flow[editar]

Git Flow es una forma de trabajo con Git cuando hay varios desarrolladores implicados. Cada desarrollo específico se hace en una rama Git separada. Todos estos desarollos se integran en una rama de nombre develop donde se validan. Las versiones estables de nuestro código se etiquetan en la rama master. Veamos detalles de Git Flow.

Uno de los fuertes de git es el manejo de ramas. Es una técnica habitual que cada desarrollador cree su rama propia para desarrollar una nueva funcionalidad del código. Cuando termina y está probada, junta su rama con la principal, que habitualmente se llama develop, añadiendo su nueva funcionalidad en dicha rama develop. Ahí se valida junto con todos los demás desarrollos que hayn ido integrando otros desarrolladores en sus ramas.

De la misma forma, cuando en la rama develop tenemos una versión que queremos liberar, se puede crear una rama para esta versión liberada, para corregir bugs en ella si aparecen y mantener esa rama para esa versión, mientras la principal sigue añadiendo funcionalidades. Habitualmente la vesión liberada se lleva a la rama master y se etiqueta.

Las versiones modernas de git vienen con este flujo de trabajo ya instalado, es decir, tenemos comandos específicos de git, que suelen comenzar como git flow xxxx para facilitarnos toda esta creación y merge de ramas.

Cómo trabajar con Git Flow[editar]

El flujo de trabajo con git flow es el siguiente. Los nombres de las ramas que menciono son los estándar, pero puedes configurarlos para que sean los que quieras.

Suele haber una rama de nombre develop en la que se va desarrollando nuestra aplicación. La idea con git flow es que la rama develop siempre tenga una versión más o menos estable, a la que se añaden funcionalidades completas y no a medio desarrollar.

Cuando un desarrollador quiere añadir una funcionalidad nueva, crea una rama feature. Desarrolla ahí la nueva funcionalidad. Puede ir haciendo tantos commit como quiera, ya que esa rama es suya y puede tenerlo a medio desarrollar. Cuando el desarrollador termina su funcionalidad en su rama feature y la ha probado, lleva la rama feature a la rama develop y borra la rama feature.

Si se detecta un error en la rama develop, se crea una rama bugfix y se corrige. Las ramas bugfix y feature funcionan igual en git flow, la diferencia es sólo de nombre. feature para desarrollar nuevas funcionalidades, bugfix para corregir errores.

Con todo este proceso, deberíamos tener entonces en develop siempre una versión de desarrollo, pero más o menoes estable, sin código a medias. Es la versión que deberína probar los tester de código.

Cuando en develop están implementadas todas las funcionalidades que queremos que lleve una versión, se crea a partir de ella una rama release. La rama release se usa para probar bien la aplicación. Los desarrolladores podrían seguir añadiendo funcionalidades a develop, siempre a través de sus propias ramas feature, sin interferir con las pruebas y estabilización de la versión release.

Si durante las pruebas en release saliera algún bug, se corrige directamente en la rama release.

Una vez que la rama release está probada y funciona correctamente, se lleva a la rama master y a develop, se etiqueta con un número de versión, por ejemplo, v1.2.3. La rama release se puede borrar. El motivo de llevarla a develop también es para que los posibles bugs que se hayan corregido en release queden también corregidos en develop. Si en la última versión de la rama master se detecta algún error, se crea una rama hotfix para corregirlo. Una vez corregido, la rama hotfix se junta con master y con develop. Se borra la rama hotfix.

Si una versión en master que sea más o menos antigua de repente necesita alguna nueva funcionalidad o corregir algún bug, se crea la rama support a partir de esa versión. Sobre esa rama support se desarrolla esa nueva funcionalidad o se corrige el bug.

git flow init[editar]

Supongamos que ya tenemos una copia local de un repositorio de git donde queremos empezar a usar git flow. Supongamos que esa copia local está en el directorio git-flow-example. Nos colocamos en ese directorio y ejecutamos el comando git flow init

D:\git-flow-example>git flow init
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master]
Branch name for "next release" development: [develop]

How to name your supporting branch prefixes?
Feature branches? [feature/]
Bugfix branches? [bugfix/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []
Hooks and filters directory? [D:/git-flow-example/.git/hooks]

Nos ha ido preguntando una serie de cosas y a todas hemos dado el valor por defecto, pulsando la tecla Enter. Nos está preguntando los nombres de las ramas que queremos usar. Ya hemos mencionado todas, excepto

  • version tag prefix. Git flow creará las etiquetas de versiones automáticamente por nosotros. Nos preguntará el número de versión. Aquí está preguntando si al número de versión en la etiqueta queremos añadirle algún tipo de prefjo. Por ejemplo, la etiqueta puede ser 1.2.3, o bien v1.2.3, o bien version-1.2.3 o lo que queramos. El prefijo sería ninguno en el primer caso, "v" en el segundo o "version-" en el tercero.
  • hooks. En git un hook es un script que se ejecuta cuando ocurre algo importante en git, como un commit, se juntan determinadas ramas, etc. Existen hooks específicos para git flow y aquí pregunta en qué directorio están ubicados. Ojo, los hooks debemos crearlos nosotros o bien bajarlos de internet y ubicarlos en ese directorio.

git flow feature[editar]

Estando en la rama develop, cuando queremos desarrollar una nueva funcionalidad, ejecutamos el comendo

git flow feature start my-feature

donde my-feature es un nombre corto que represente la funcionalidad que estamos implementando. Si usamos algo como jira, puede ser buena idea usar la clave de la tarea jira donde se describe nuestra nueva funcionalidad, por ejemplo

git flow feature start MYPROJECT-234

donde MYPROJECT-234 es la clave de la tarea jira.

Esto creará en git, a partir de la rama develop, una rama feature/MYPROJECT-234 y nos moverá a esa rama. Listo, podemos empezar a trabajar en esta rama con nuestra nueva funcionalidad y hacer todos los commit parciales que queramos hasta que terminemos.

Si en cualquier momento queremos guardar nuestro trabajo en el servidor o compartir la rama para que la vean otros compañeros, ejecutamos el comento

git flow feature publish

esto creará y subirá nuestra rama feature/MYPROJECT-234 al servidor. Si seguimos trabajando en ella posteriormente, tendremos que ir haciendo el tradicional git push después de cada git commit. El comando git flow feature publish sólo se debe ejecutar para la primera subida de nuestra rama feature al servidor.

Una vez terminamos nuestra funcionalidad y probamos que funciona, podemos ejecutar el comando

git flow feature finish

Eso llevará nuestro trabajo a la rama develop y borrará la rama feature/MYPROJECT-234. Puesto que develop puede haber evolucionado con otras funcionalidades de otros desarrolladores, suele ser buena idea hacer los siguientes pasos antes

git checkout develop
git pull
git checkout feature/MYPROJECT-234
git merge develop
git flow feature finish

Básiamente, nos vamos a develop, nos aseguramos de tener lo último, volvemos a feature/MYPROJECT-234, hacemos el merge de develop hacia nuestra rama y corregimos los posibles conflictos. Si los hay, debemos hacer git add y git commit de los ficheros en conflicto una vez corregidos. Y cuando todo esté listo, ya ejecutamos el git flow feature finish con garantía de éxito y sin conflictos.

git flow bugfix[editar]

Exactamente igual que git flow feature, pero para corregir bugs en vez de para añadir nuevas funcionalidades.

git flow release[editar]

Cuando en la rama develop ya tenemos varias funcionalidades añadidas, que funcionan y queremos generar a partir de ella una versión estable, usamos el comando get flow release start. Este comando crea a partir de develop una rama release. De esta forma, los desarrolladores pueden seguir desarrollando nuevas funcionalidades y llevándolas a develop sin interferir con esta nueva versión que está ahora en la rama release.

git flow release start 1.2.3

El 1.2.3 es el número que queramos crear para la versión que vamos a generar. Esto creará una rama release/1.2.3 y nos llevará a ella. Probamos a fondo la rama release para garantizar dentro de lo posible que no se ha colado ningún bug. Si los encontramos, los vamos corrigiendo directamente en la rama release. Cuando estamos satisfechos del resultado, ejecutamos el siguiente comando

git flow release finish

Este comando hace varias cosas

  • Nos pide un nombre de versión para poner una etiqueta git y marcar el punto exacto donde está nuestra versión.
  • Se lleva los cambios de release a master, que es donde estará la versión ya estable.
  • Se lleva los cambios de release a develop, por si hubiera algún bug que hayamos corregido, de forma que quede en develop también corregido.
  • Borra la rama release.

Así que al terminar este proceso tendremos en master nuestra versión, debidamente etiquetada y en develop todos los posibles bugs que hayamos encontrado corregidos.

git flow hotfix[editar]

A veces, una vez que tenemos ya una versión estable en la rama master, desgraciadamente descubrimos un bug. Para un arreglo rápido, se usa el comando

git flow hotfix start 1.2.4

donde 1.2.4 es el nuevo número de versión que queremos para fijar el bug. Esto crea y nos mueve a una rama hotfix/1.2.4 y en ella corregimos el bug que acabamos de descubrir. Una vez corregido y hecho el commit, ejecutamos el comando

git flow hotfix finish

Esto mezcla la rama hotfix/1.2.4 en master y también en develop para que el bug quede ahí corregido. Pone una etiqueta al commit con el número de la versión y además borra la rama hotfix/1.2.4.

git flow support[editar]

Esta rama opción no está muy comentada. Sin embargo, tiene su utilidad en determinadas circunstancias.

Imagina un producto del que vas vendiendo versiones que sacas al público. En la rama master van las distintas versiones que se han ido vendiendo. Si es un producto al público, si un cliente encuentra un bug en la versión que tiene que no es la último, lo reporta de alguna manera, se corrige y en la siguiente versión estará corregido. Cuando el cliente se actualice tendrá la versión más nueva, con el bug corregido, pero también con todas las nuevs funcionalidades que se hayan ido añadiendo. Con este mecanismo, las ramas support no tienen sentido.

Pero imagina ahora que es un producto, con desarrollos a medida para clientes concretos, que te lo compran. Cada cliente a lo mejor tiene plugins específicos desarrollados para él, que no tienen otros clientes. En tu rama master vas teniendo las versiones de tu producto con sus plugins congeladas, tal cual se las has ido vendido al cliente. La versión 1 es la del cliente X con determinados desarrollos a medida, la version 2 es la del cliente Y con determinados desarrollos a medida, etc. ¿Qué pasa si un cliente encuentra un bug y se lo tienes que corregir?. No vale la opción de corregirlo en develop, llevárselo a master como una versión más nueva y entregarle la nueva versión con todos los cambios que se hayan hecho para otros clientes a este cliente. En este caso, sí tiene sentido crear a partir de master una rama específica para ese cliente donde le podamos corregir los bugs que encuentre en su versión concreta.

O imagina que en master tienes las verssiones 1.x.x, 2.x.x y 3.x.x y quieres, por el motivo que sea, mantener vivas las 3 versiones. Aquí también tiene sentido crear ramas support a partir de master en los puntos 1.x.x, 2.x.x y 3.x.x

git flow support start <version> <branch>

Esto crea una rama a partir de master, desde la etiqueta <version> y la llama support/<branch>. Ahí podemos ir realizando directamente los cambios que queramos.

Normalmente estas ramas no se cierran, no nos interesa en general borrarlas. Son nuevas ramas "develop" para versiones antiguas, donde solo se corrigen o mejoran una versión antigua concreta.

Resumen en imagen[editar]

La siguiente imagen muestra el resultado de los comandos git flow, siempre suponiendo que estamos en la rama adecuada para ejecutar el comando tal cual se ve en la imagen.

  • git flow feature y bugfix start se debe hacer estando en la rama develop.
  • git flow feature y bugfix finish se debe hacer estando en la rama feature/xxx o bugfix/xxx que queremos cerrar.
  • git flow release start se debe hacer estando sobre la rama develop
  • git flow release finish se debe hacer estando sobre la rama release/xxx

Si no es así, podemos cambiar a la rama adecuada, o bien podemos añadir más parámetros para indicar de qué rama se quiere partir o cerrar.