Git-Flow es un conjunto de extensiones para Git que proveen comandos de alto nivel para operar repositorios basados en el modelo de ramificaciones de Vincent Driessen.
Si queremos implementar este flujo de trabajo, cada vez que queramos hacer algo en el código, tendremos que crear la rama que corresponda, trabajar en el código, incorporar el código donde corresponda y cerrar la rama. A lo largo de nuestra jornada de trabajo necesitaremos ejecutar varias veces al día los comandos git, merge, push y pull así como hacer checkouts de diferentes ramas, borrarlas, etc. Git-flow son un conjunto de extensiones que nos ahorran bastante trabajo a la hora de ejecutar todos estos comandos, simplificando la gestión de las ramas de nuestro repositorio.
Las "reglas" que Vincent plantea en su blog son un ejemplo de cómo git nos permite implementar un flujo de trabajo para nuestro equipo. Estas no son reglas absolutas, bien es cierto que pueden funcionar en un gran número de proyectos, aunque no siempre será así. Por ejemplo ¿qué pasa si tenemos que mantener dos o tres versiones diferentes de una misma aplicación? Digamos que tenemos que mantener la versión 1.x, la 2.x y la 3.x. El tablero de juego es diferente así que necesitaremos ampliar y adaptar estas reglas para poder seguir jugando.
Git es una herramienta que nos permite modificar estas reglas y, lo que es más importante, cambiando y adaptándolas a medida que el proyecto avanza y el equipo madura. Una vez más, una buena dosis de sentido común será nuestra mejor aliada para responder las preguntas que nos surjan durante el camino.
Un pre-requisito es una instalación de Git en funcionamiento. Git Flow funciona en OSX, Linux y Windows.
El cliente gráfico para OSX y Windows Sourcetree es una excelente GUI para git y tiene soporte para git-flow nativo. GitKraken es una opción para los que quieren trabajar con Git Flow y un cliente gráfico que también soporte Linux.
brew install git-flow-avh
port install git-flow-avh
apt-get install git-flow
$ wget -q -O - --no-check-certificate
https://raw.github.com/petervanderdoes/gitflow-avh/develop/contrib/gitflow-installer.sh
install stable | bash
Git-flow parte de la idea de un repositorio central remoto (que por defecto es origin). Se puede trabajar localmente con esta idea también pero la potencia la va a dar trabajar con un repo remoto.
Git-flow funciona basándose en merges o fusiones de ramas. No reorganiza (branch rebase) las features branches o ramas de características.
Git Flow, la mayoría de las veces que hace merges a master o develop, lo hace con la opción --no-ff
no fast-forward para asegurar que Git no haga la construcción de un avance rápido sino que mantenga la de una fusión, así se mantiene una topología de bifurcación, como lo muestra la figura de abajo. Y digo, "la mayoría", porque como bien lo explica el autor en el issue 100 del repositorio de GitFlow:
Por diseño, git-flow usa la opción
--no-ff
cuando se fusiona para registrar que los commits pertenecen juntos históricamente. Sin embargo, cuando la rama defeatures
contiene solo un commit, la confirmación de fusión adicional no agrega nada y solo complica innecesariamente el árbol de las ramas. Por lo tanto, para las ramas con un solo commit, las fusiones de avance rápido se realizan como si la confirmación se hubiera realizado endevelop
directamente. - Vincent Driessen
Un avance rápido es cuando, en lugar de construir un commit de fusión, git simplemente mueve su puntero de la rama para apuntar a la confirmación entrante. Esto ocurre comúnmente al hacer un git pull sin ningún cambio local.
El trabajo se organiza en dos ramas principales:
- Master
- Develop
Cualquier commit que pongamos en esta rama debe estar preparado para subir a producción. Es la rama donde iniciamos nuestro proyecto y desde donde se clonará siempre nuestro proyecto. No se hacen commit aquí (salvo raras excepciones de correcciones muy tontas)
Rama en la que está el código que conformará la siguiente versión planificada del proyecto. No se suelen hacer commits aquí. Solo merges.
- Feature
- Realese
- Hotfix
Estas ramas se utilizan para desarrollar nuevas características de la aplicación que, una vez terminadas, se incorporan a la rama develop. Es donde trabajaremos en el día a día y donde haremos nuestro commits.
- Se originan a partir de la rama Develop.
- Se incorporan siempre a la rama Develop.
- Nombre: cualquiera que no sea master, develop, hotfix-* o release-*
Estas ramas se utilizan para preparar el siguiente código en producción. En estas ramas se hacen los últimos ajustes y se corrigen los últimos bugs antes de pasar el código a producción incorporándolo a la rama Master. Esta rama "congela" la rama Develop. Parte de ella, a diferencia de Hotfix que, como veremos, parte de Master ("congela" a master como se dice habitualmente)
En la rama de versionado, se pueden hacer cambios menores referentes a configuraciones de la release como ser: archivos de configuraciones, archivos de librerías de la versión, correcciones muy menores para salir a producción, pero solo eso. No hay desarrollo de características aquí ni correcciones de bugs.
- Se originan a partir de la rama Develop
- Se incorporan a Master y Develop.
- Cuando se incorpora a Master se hace un tag con un versionado semántico (tres cifras: mayor-version.menor-version.patch-version)
- Nombre: release-*
Esas ramas se utilizan para corregir errores y bugs en el código en producción. Funcionan de forma parecida a las Releases Branches, siendo la principal diferencia que los hotfixes no se planifican. Parten de Master. Los cambios que se hagan aquí irán a producción.
- Se origina a partir de la rama Master
- Se incorporan a la Master y Develop
- Nombre: hotfix-*
Las ramas de Realese y Hotfix son las únicas permitidas para incorporar cambios (commits) a la rama master. Para decirlo de otro modo: Master solo puede recibir merges de Realise y/o Hotfix
Mientras que las Features siempre irán a Develop.