☕ Git-Flow: Lo Esencial
Tags: git, beginners, gitflow, versioning
Published: 2020-06-08 09:47:40

🇬🇧 [English version](https://dev.to/fernando_ayon/git-flow-an-introduction-430m)
🇫🇷 [Version française](https://dev.to/fernando_ayon/git-flow-premiers-pas-e93)

¿Tienes un nuevo empleo o en tu trabajo actual están planeando implementar Git-Flow y no sabes de qué se trata?

Has venido al lugar indicado. En este post te lo explico, pero si ya lo conoces un poco y solo quieres indicaciones sobre su uso, [salta al tutorial](#tutorial).

# 🧐 Contexto

En pocas palabras, [Git](https://git-scm.com/) es un sistema de gestión de versiones, es una herramienta indispensable para controlar el ciclo de vida del desarrollo de una aplicación.

Hasta aquí todo bien, pero los problemas empiezan a aparecer cuando se trabaja en equipo: tú y tu equipo podrían decidir de simplemente trabajar en la rama principal del proyecto y crear algunas ramas secundarias en ocasiones especiales, pero ¿qué pasa cuando hay mucho trabajo o varias personas deben trabajar en la misma función al mismo tiempo?

## 📓 [Git-Flow](https://nvie.com/posts/a-successful-git-branching-model/)

Al trabajar en equipo, es necesario definir convenciones o buenas practicas para que todos sepan como trabajar juntos. Git-Flow es uno de muchos de los llamados *flujos de trabajo*, bastante popular por su practicidad y aprendizaje relativamente rápido, es una manera de organizar las ramas del repositorio del proyecto.

Probablemente ya has visto esta imagen o una parecida al buscar el término Git-Flow en Internet:
![*Visible confusion*](https://dev-to-uploads.s3.amazonaws.com/i/8uwtwsr8ktejnuh4rad6.jpg) *Git-Flow en una imagen*

Parece y es complicado a primera vista, pero al conocer las diferentes ramas utilizadas y el por qué de su existencia veras que su funcionamiento es bastante lógico.

### 🌳 Ramas

Como ya vimos en la imagen, Git-Flow utiliza varias ramas para organizar el desarrollo:

- master
- develop
- feature
- release
- hotfix

#### 🌴 master y develop

Si ya has utilizado Git antes, estarás familiarizado con la rama `master`. En este nuevo contexto, esta rama es "intocable", nadie del equipo debe hacer ningún cambio directamente en ella, ni crear nuevas ramas a partir de ella, con una excepción que veremos más adelante.

Al crear un nuevo proyecto, o al momento de comenzar a utilizar Git-Flow, la rama `develop` debe ser creada a partir de `master`, y al igual que `master`, sera una rama de "larga duración de vida", es decir, nunca sera borrada y vivirá paralelamente a `master`.

Como su nombre lo indica, la rama `develop` sirve como base para desarrollar todas las nuevas funciones y correcciones del proyecto, por eso es considerada como la rama principal. 

Una vez que todas las nuevas funciones del proyecto han sido completadas y `develop` es estable, debemos hacer un `merge` de develop en `master`. 

La rama `master` debe reflejar siempre un estado 'en producción', por eso es importante que no realicemos cambios directamente en ella, ya que cada vez que hay un nuevo `commit`, deberíamos hacer un `tag` para definir la nueva versión y publicarla. 


#### 💯 feature

Las ramas `feature` son aquellas que dedicamos completamente al desarrollo de cada una de las nuevas funciones que agregaremos al proyecto en la versión siguiente. Siempre parten de `develop` y debemos hacer el `merge` de regreso a `develop`. 

Si seguimos las buenas practicas de Git-Flow, al crear una nueva rama `feature`, siempre debemos agregar el prefijo `feature/`, de esta manera podemos mantener una buena organización y al ver las ramas activas podremos identificar rápidamente el trabajo en curso. 

Al mismo tiempo, es importante nombrar las ramas `feature` de una forma descriptiva que permita identificar la finalidad de la rama:
```
❌ feature/new-method
✔️ feature/add-support-for-json-parsing
```

Lo importante de las ramas feature es que vivan solamente durante el desarrollo y que desaparezcan una vez que hayamos realizado el `merge` en `develop` o que sean descartadas si la función ya no es necesaria.

NOTA: el prefijo `feature/*` es la practica por defecto, pero si tu o tu equipo lo estiman necesario, pueden adaptar el prefijo a cualquier otra cosa, por ejemplo `funcionalidad/...`


#### ⭐ release

La rama `release` sirve para reagrupar las funcionalidades y correcciones efectuadas para poder preparar el lanzamiento de la versión en desarrollo. Esta rama parte de `develop` y el `merge` se hace tanto en `develop` como en `master`.

El momento perfecto para crear las ramas `release` es cuando la rama `develop` se asemeja lo mas posible a lo que queremos tener en producción, es una manera para poder hacer las correcciones de ultimo minuto que pudimos haber olvidado, o para realizar cambios del proyecto que no necesariamente necesitan toda una rama para ser realizados, por ejemplo para aumentar el numero de versión.

Siguiendo las practicas de Git-Flow, las ramas `release` también tienen un prefijo, `release/*` o `release-*`, normalmente seguido del numero o nombre de la versión que representan, por ejemplo: `release/1.2.0` o `release/5.0` o `release/1.0.0-rc.1+build.123`.

La ventaja de tener una rama release es que el trabajo puede continuar en `develop` y otras nuevas ramas `feature`, ya que el trabajo planeado ya se encuentra en la release y no va a tener cambios importantes.


#### 🛠️ hotfix

Las ramas `hotfix` parten de `master` y debemos realizar el `merge` de vuelta en `master` y `develop`. Son utilizadas para realizar correcciones rápidas al proyecto, para poder publicar una nueva version lo antes posible. 

NOTA: Si creamos una rama `hotfix` pero ya existe una rama `release`, en lugar de hacer el `merge` en `develop`, debemos hacer el `merge` en `master` y `release`.


#### ⚔️ hotfix vs bugfix

En algunos proyectos podemos ver que ademas de las ramas `hotfix`, a veces tenemos algunas con el prefijo `bugfix`. La diferencia entre estos dos tipos de ramas es que las `bugfix` se comportan como las `feature` y las `hotfix` se comportan como las `release`.

Visto de otra manera, podemos utilizar las `bugfix` para realizar correcciones de bugs no muy importantes que pueden esperar al lanzamiento de la versión en desarrollo, mientras que las `hotfix` no pueden esperar y deben ser publicadas en cuanto el desarrollo haya sido aprobado.

```
✔️ bugfix/fix-some-thingy-that-almost-nobody-uses-and-its-not-really-important
✔️ hotfix/fix-clic-on-top-right-corner-of-login-button-sets-the-users-computer-on-fire
```


### ✏️ Tutorial <a name="tutorial"></a>

Para este tutorial y con el fin de simplificarlo al maximo, utilizaré el plugin para consola de Git-Flow de [Peter van der Does](https://github.com/petervanderdoes/gitflow-avh), pero aquí te dejo los [comandos clásicos Git equivalentes](https://gist.github.com/JamesMGreene/cdd0ac49f90c987e45ac) a los comandos de Git-Flow.

1. Habilitar Git-Flow en el proyecto

    ```
    # Inicia Git en el proyecto, crea la rama develop y 
    # configura los prefijos de las otras ramas.
    # Finalmente, cambia a la rama develop
    git flow init
    ```
    ![git flow init](https://dev-to-uploads.s3.amazonaws.com/i/5ush55zzd9oaqorna9pf.gif)

2. Comenzar a trabajar en una nueva funcionalidad

    ```
    # Crear una nueva rama feature/* y cambiarse a ella
    git flow feature start <feature-name>
    ```
    ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dw1ll43xgdzzncqpxxt2.gif)
    Podemos ver como la consola nos dice las acciones efectuadas y que podemos comenzar a trabajar en la nueva rama.

3. Terminar una funcionalidad

    ```
    # El nombre de la feature es opcional, no es necesario si
    # ya nos encontramos en la rama.
    # Cambia a develop, hace un merge de la feature hacia develop
    # Y elimina la rama feature
    git flow feature finish <feature-name>
    ```
    ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7twy4bwoq6r4m2dr7edc.gif)

    NOTA: Todas estas acciones son realizadas en tu repositorio local, nada en el distante, a menos que realices un `push`. Recuerda hacerlo al terminar tus features, para actualizar `develop`.

4. Preparar la nueva versión 

    ```
    # Crea una nueva rama release/* desde develop y cambia a ella.
    git flow release start <version-name>
    ```
    ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xa9tsuaqyghc0lzxzya4.gif)

    NOTA: Justo después de actualizar el numero de versión de tu proyecto es un buen momento para publicar la rama release en `origin`.

5. Terminar la versión 

    ```
    # Cambia a la rama master
    # Hace un merge de la release
    # Crea el tag de la versión utilizando el nombre de la rama
    # Cambia a la rama develop
    # Hace un merge de la release
    # Elimina la rama release
    git flow release finish
    
    # No olvides enviar los últimos cambios a `origin` utilizando los comandos clásicos de Git
    git push origin master
    git push origin develop
    git push --tags
    git push origin :release/1.2.0 (si la release estaba en el repo distante)
    ```
    ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9wnd7eyv1kd44hrtgkkl.gif)

6. Crear un hotfix

    ```
    # Puede ser creada a partir de un commit específico o simplemente del ultimo existente.
    # Crea una rama hotfix y cambia a ella
    git flow hotfix start <hotfix-name> [<commit>]
    ```
    ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/zk7rio07c4kouvbfkxej.gif)

7. Finalizar un hotfix

    ```
    # Ocurre lo mismo que en una release
    # No olvides especificar el argumento -T o --tagname
    # para crear un tag correctamente si el nombre de tu
    # rama hotfix no es un numero de versión.
    git flow hotfix finish [<-T version-name>]
    ```
    ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/foisegiro6knb6bse4ag.gif)


## Siguientes pasos

En un siguiente articulo, hablaremos de otras estrategias, pero si por el momento quieres aprender mas sobre Git-Flow, aquí te dejo algunas fuentes que utilicé para este articulo.

[A successul Git branching model](https://nvie.com/posts/a-successful-git-branching-model/): El articulo original del creador de Git-Flow
[Git-Flow cheat sheet](https://danielkummer.github.io/git-flow-cheatsheet/): Un vistazo rápido sobre los comandos de Git-Flow
[GitFlow considered harmful](https://www.endoflineblog.com/gitflow-considered-harmful): Una alternativa mas simple a Git-Flow y una probada de lo que vamos a ver en el próximo articulo.