☕ Git-Flow : premiers pas
Tags: git, beginners, gitflow, versioning
Published: 2020-06-08 20:16:36

🇬🇧 [English version](https://dev.to/fernando_ayon/git-flow-an-introduction-430m)
🇪🇸 [Version en español](https://dev.to/fernando_ayon/git-flow-lo-esencial-3bgf)

Tu as un nouveau job ou tu prévois de mettre en place Git-Flow dans tes projets, mais tu ne sais pas trop ce que c'est ? Tu es au bon endroit. 

Dans cet article, je vais te l'expliquer, mais si tu connais déjà un peu le principe ou alors si tu veux uniquement des indications sur son utilisation, [passe directement au tutoriel](#tutorial).


# 🧐 Le Contexte

En quelques mots, [Git](https://git-scm.com/) est un système de gestion de versions pour software, c'est un outil indispensable pour contrôler le cycle de vie du développement d'une application.

Jusqu'ici tout va bien, mais les problèmes commencent à apparaître lorsque l'on travaille en équipe : vous pouvez décider de travailler uniquement sur la branche principale du projet et de créer des branches secondaires lors d'occasions spéciales. Mais que se passe-t-il lorsqu'il y a beaucoup de travail ou lorsque plusieurs personnes doivent travailler sur la même chose en même temps ?

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

Dès que nous travaillons en équipe, il est nécessaire de définir des conventions ou des bonnes pratiques pour que nous puissions travailler ensemble. Git-Flow est l'un des nombreux outils que nous qualifions de *workflows*. C'est un moyen d'organiser les branches du projet, assez populaire de part sa praticité et son apprentissage relativement rapide.

Tu as probablement déjà vu cette image ou une image similaire lors d'une recherche du terme Git-Flow sur Internet:
![*Visible confusion*](https://dev-to-uploads.s3.amazonaws.com/i/8uwtwsr8ktejnuh4rad6.jpg) *Git-Flow*

Cela semble et est compliqué à première vue, mais dès que nous connaissons les différentes branches utilisées et la raison de leur existence, tu verras que leur fonctionnement est assez logique.


### 🌳 Branches

Comme nous l'avons vu dans l'image, Git-Flow utilise plusieurs branches pour organiser le développement:

- master
- develop
- feature
- release
- hotfix

#### 🌴 master et develop

Si tu as déjà utilisé Git, tu connais forcément la branche `master`. Dans ce nouveau contexte, cette branche est "intouchable", aucun membre de l'équipe ne doit y apporter de modifications directement, ni en créer de nouvelles, à une exception que nous verrons plus tard.

Lors de la création d'un nouveau projet, ou lorsque tu commences à utiliser Git-Flow, la branche `develop` doit être créée à partir de `master`, et comme `master`, la branche `develop` ne sera jamais supprimée et vivra en parallèle.

Comme son nom l'indique, la branche `develop` sert de base au développement de toutes les nouvelles fonctionnalités et corrections du projet, c'est pourquoi elle est considérée comme la branche principale.

Une fois que toutes les nouvelles fonctions et corrections prévues du projet sont terminées et que `develop` est stable, on peut faire un `merge` de `develop` dans `master`.

La branche `master` doit toujours refléter un état 'en production', il est donc important de ne pas y apporter de modifications directement, car chaque fois qu'il y a un nouveau `commit`, on doit faire un `tag` pour définir la nouvelle version et la publier. C'est pourquoi on appellera la branche `master` comme la 'branche d'intégration'.


#### 💯 feature

Les branches `feature` sont celles que nous devons consacrer entièrement au développement de chacune des nouvelles fonctionnalités du projet dans sa prochaine version. Elles partent toujours de `develop` et à la fin du développement on doit les `merger` de retour sur `develop`.

Si nous suivons les bonnes pratiques de Git-Flow, lors de la création d'une nouvelle branche `feature`, nous devons toujours ajouter le préfixe `feature/*`, de cette façon nous pouvons maintenir une bonne organisation et si nous regardons les branches actives nous pouvons rapidement identifier le travail en cours.

Il est très important de nommer les branches `feature` de manière descriptive pour identifier le but de la branche :
```
❌ feature/new-method
✔️ feature/add-support-for-json-parsing
```

Ce qu'il faut retenir est que les branches `feature` ne vivent que pendant le développement et qu'elles disparaissent une fois qu'on fait le `merge` du développement ou alors nous pouvons les supprimer si la fonction en développement n'est plus nécessaire, par exemple dans le cas des fonctions expérimentales.

NOTE: le préfixe `feature/*` est la pratique par défaut, mais si ton équipe et toi le jugent nécessaire, vous pouvez adapter le préfixe à une autre chose, par exemple : `fonction/*`

#### ⭐ release

Les branches `release` sont utilisées pour regrouper les fonctionnalités et les corrections apportées pour préparer la sortie de la version en développement. Elles partent de `develop` et le `merge` doit se faire à la fois dans `develop` et dans `master`.

Le moment idéal pour créer les branches `release` est lorsque la branche `develop` est aussi similaire que possible à ce que nous voulons avoir en production, c'est un moyen de faire des petites corrections oubliées de dernière minute, ou de faire des méta-changements au projet qui n'ont pas lieu sur une branche feature, par exemple, pour augmenter le numéro de version.

Si nous suivons les bonnes pratiques de Git-Flow, les branches `release` ont également un préfixe, `release/*` ou `release-*`, généralement suivi du numéro de version ou du nom qu'elles représentent, par exemple, `release/1.2.0` ou `release/5.0` ou encore `release/1.0.0-rc.1+build.123`.

L'avantage des branches `release` est que le travail peut se poursuivre sur la branche `develop` et d'autres nouvelles `features`, car le travail prévu pour la nouvelle version est déjà présent dans la branche `release` et n'aura pas de changements majeurs.


#### 🛠️ hotfix

Les branches `hotfix` partent de `master` et nous devons faire le `merge` de retour dans `master` et `develop`. Elles sont utilisées pour apporter des corrections rapides au projet, afin de publier une nouvelle version dès que possible.

NOTE: Si nous créons une branche `hotfix` mais qu'il y a déjà une branche `release`, au lieu de faire le `merge` dans `develop`, nous devons le faire dans `master` et dans la `release`.


#### ⚔️ hotfix vs bugfix

Dans certains projets, tu pourras trouver qu'en plus des branches `hotfix`, il y en a parfois quelques-unes avec le préfixe `bugfix`. La différence entre ces deux types de branches est que les `bugfix` se comportent comme les branches `feature` et les `hotfix` se comportent comme les branches `release`.

Autrement dit, tu peux utiliser les `bugfix` pour apporter des corrections de bugs mineurs qui peuvent attendre la sortie de la version en développement, tandis que les `hotfix` ne peuvent pas attendre et doivent être publiées dès que le développement soit approuvé.

```
✔️ 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
```


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

Pour ce tuto et afin de le simplifier au maximum, j'utiliserai le plugin de console Git-Flow de [Peter van der Does](https://github.com/petervanderdoes/gitflow-avh), mais je te laisse ici les [commandes Git classiques équivalentes](https://gist.github.com/JamesMGreene/cdd0ac49f90c987e45ac) aux commandes Git-Flow.

1. Activer Git-Flow sur le projet

    ```bash
    # Cette commande active Git sur le projet, elle crée aussi la branche develop et 
    # permet de configurer les préfixes des autres branches.
    # Enfin, elle fait un check out de la branche develop
    git flow init
    ```
    ![git flow init](https://dev-to-uploads.s3.amazonaws.com/i/5ush55zzd9oaqorna9pf.gif)

2. Commencer à travailler sur une nouvelle fonctionnalité

    ```bash
    # Cette commande crée une nouvelle branche feature/* et fait un check out sur la branche
    git flow feature start <feature-name>
    ```
    ![git flow feature start](https://dev-to-uploads.s3.amazonaws.com/i/dw1ll43xgdzzncqpxxt2.gif)
    Tu peux voir comment la console nous indique les actions effectuées et que nous pouvons commencer à travailler sur la nouvelle branche.

3. Terminer une fonctionnalité

    ```bash
     # Le nom de la feature est optionnel, il n'est pas nécessaire de le préciser si
     # on est déjà positionnés sur la branche.
     # La commande fait un check out de develop et fait un merge vers develop
     # Enfin, elle supprime la branche feature
     git flow feature finish <feature-name>
    ```
    ![git flow feature finish](https://dev-to-uploads.s3.amazonaws.com/i/7twy4bwoq6r4m2dr7edc.gif)

    NOTE: Toutes ces actions sont effectuées dans votre dépôt local, rien n'est fait dans le dépôt distant, sauf si tu fais un `push`. Alors n'oublie pas de faire un push lors de la finalisation de ton travail local sur tes `feature`s, pour mettre à jour `develop`.

4. Préparation de la nouvelle version 

    ```bash
    # Cette commande crée une nouvelle branche release/* à partir de develop et fait un check out de la branche.
    git flow release start <version-name>
    ```
    ![git flow release start](https://dev-to-uploads.s3.amazonaws.com/i/xa9tsuaqyghc0lzxzya4.gif)

    NOTE: Le moment parfait pour publier la branche `release` dans le dépôt distant c'est juste après la mise à jour du numéro de version de ton projet (et la validation du code, évidemment).

5. Finaliser la version 

    ```bash
    # Cette commande fait un check out de la branche master
    # Ensuite, fait un merge de la branche release
    # Elle crée le tag de la version sur master avec le nom de la branche release
    # Elle fait un check out de la branche develop
    # Ensuite un merge de la release sur develop
    # Enfin, la branche release est supprimée
    git flow release finish
    
    # N'oublie pas d'envoyer ces derniers changements vers le dépôt distant avec les commandes classiques de Git :
    git push origin master
    git push origin develop
    git push --tags
    git push origin :release/<version> (seulement si la release existait déjà dans le dépôt distant)
    ```
    ![git flow release finish](https://dev-to-uploads.s3.amazonaws.com/i/9wnd7eyv1kd44hrtgkkl.gif)

6. Création d'un hotfix

    ```bash
    # Cette branche peut être créée à partir d'un commit spécifique ou alors du dernier commit.
    # Cette commande crée une branche hotfix et fait un check out sur la nouvelle branche
    git flow hotfix start <hotfix-name> [<commit>]
    ```
    ![git flow hotfix start](https://dev-to-uploads.s3.amazonaws.com/i/zk7rio07c4kouvbfkxej.gif)

7. Finalisation d'un hotfix

    ```bash
    # Cette commande effectue les mêmes actions que pour une release
    # N'oublie pas de spécifier l'option -T ou --tagname
    # pour créer un tag correctement si le nom de ta
    # branche hotfix n'est pas un numéro de version.
    git flow hotfix finish [<-T version-name>]
    ```
    ![git flow hotfix finish](https://dev-to-uploads.s3.amazonaws.com/i/foisegiro6knb6bse4ag.gif)


## Et pour la suite...

Dans un prochain article, nous parlerons d'autres stratégies, mais si tu veux approfondir le sujet de Git-Flow, voici quelques sources que j'ai utilisées pour cet article.

[A successul Git branching model](https://nvie.com/posts/a-successful-git-branching-model/): L'article d'origine de Git-Flow
[Git-Flow cheat sheet](https://danielkummer.github.io/git-flow-cheatsheet/): Un coup d’œil sur les commandes Git-Flow.
[GitFlow considered harmful](https://www.endoflineblog.com/gitflow-considered-harmful): Une alternative plus simple à Git-Flow et un avant-goût du sujet de mon prochain article.