GitButler : un client git avec trop de hype ?
Tags: gitbutler, gitflow, git, trunkbaseddevelopment
Published: 2024-03-18 19:48:37

Vous maitrisez git ? Vous êtes un·e expert·e des *features* branches, vous aimez tester le travail de vos collègues et vous aimez attendre que quelqu'un relise votre travail ? Votre fusions de travail marchent systématiquement ?

Moi non ! (humour) Et maintenant que GitButler existe, je m'interroge comment on peut faire mieux.

## Comment travailler en équipe ?

Le standard moderne de collaboration d'équipe est git. C'est un programme qui permet de créer des "*branches*" sur lesquels les collaborateurs d'un projet travaillent. Ces branches permettent de fusionner les contributions de chacun et de fluidifier le développement parallèle, et à terme tout le monde développe une  application commun qui peut être envoyée à des utilisateurs.

Il y a plusieurs "standards" qui sont apparus pour utiliser git, mais les principaux que je vois le plus sont :

1. Une organisation en *gitflow* [git.flow.readthedocs.io](https://git-flow.readthedocs.io/fr)
2. Le *trunk based development* [Trunk based development](https://trunkbaseddevelopment.com/)

Ces standards permettent d'organiser la répartition du travail et leur intégration, mais ils ne répondent pas à la question de comment vérifier que l'appli finale marche. Comment ça se passe après-tout ?

La réponse va vous surprendre : l'appli finale fini par marcher **avec beaucoup de larmes et de sang.**

## Comment s'assurer qu'une appli fonctionne ?

Dans un environnement de travail moderne, lorsqu'un développeur fait une contribution à un projet, il ou elle soumet une demande de merge de sa branche (PR ou MR) et ses collaborateur·ices relisent le travail et font le travail sur la branche de la personne.

Si le travail est approuvé, et qu'il est fusionné sur la branche de travail principale, les collaborateur·ices relancent à nouveau toute une batterie de tests pour s'assurer que l'application continue de tourner. 

S'il y a des problèmes à une seule de ces étapes, on annule toutes les fusions et on revient à l'étape développement sur une branche à part, avec potentiellement un `rebase`.

Et s'il n'y a pas de problème, tout le monde doit récupérer la modification et à nouveau vérifier que sa demande de merge fonctionne encore, et refaire des tests, et *bis repetita*.

> Mais pourquoi le travail de l'un sur sa machine ne marcherait pas sur celle des autres ? Et pourquoi faut-il revérifier tout le travail une fois qu'il a été approuvé ?

![Meme du "It works on my machine"](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n7bdl80gedluhka5c3ld.png)

La raison simple, c'est que chaque demande de merge crée une distance entre le développement réalisé et l'existant. Cette distance crée un risque et fait que la fusion du travail peut mal se passer. On travaille donc en réduction de risque et je ne suis pas sûr que ce soit un état d'esprit à adopter dans un travail collaboratif.

> D'une certaine façon, on ne vérifie pas que l'appli fonctionne lors d'une fusion de travail, mais plutôt, on vérifie que la fusion ne casse pas l'appli.

Serait-il possible de changer le paradigme de pensée ? Est-il possible de s'assurer que la contribution réalisée soit intégrée au plus vite sur l'application finale ? De réellement tester que l'appli fonctionne, plutôt que personne ne casse le build ? Analysons pourquoi cela est difficile.

## Loin des yeux, loin du coeur ; loin de `main`, loin de `merge`

Pour réaliser une quelconque contribution avec l'aide de git, on part en général de la branche principale, ici `main`. La personne fait son travail, et ensuite fait sa demande de `merge` et rattrape éventuellement avec un `rebase` les développements faits sur `main`.

Les autres contributeurs du projet relisent la demande de merge, et font éventuellement des tests de la contribution en se plaçant dans la branche avec la commande `switch` ou `checkout`.

Mais le changement de branche peut-être terrible. Par exemple, voici les commandes que je dois lancer à chaque fois que je change de contexte sur un projet javascript : 

```sh
# changer de branche
git checkout feature/whatever
git pull --rebase
# Installer le projet en espérant avoir le bon package manager
# Merci https://github.com/antfu/ni
ni
# faire des tests de lint et de type et de format
nr build
# faire des tests unitaires variés (avec parfois de la mesure de coverage)
nr test
# faire des tests E2E et d'intégration (facultatif)
nr test:e2e
# faire des tests manuels divers et variés sur l'application
nr dev
# faire de potentiels tests divers et variés sur l'application un peu plus "finale"
nr start
```
Et chacune de ces commandes peut prendre entre une seconde à une minute, et cela pour chaque feature qui souhaite être apportée.

Avec un peu de chance toutes ces commandes sont exécutées automatiquement avec une pipeline, ce qui diminue le risque d'un problème durant une fusion de travail.

Mais ce n'est pas parfait, car une fois le travail approuvé et fusionné, il faut refaire toutes ces étapes en local sur son propre environnement et sa propre branche avec la modification intégré.

Les manipulations de branches sont relativement simples dans git, jusqu'à ce qu'il y ait besoin de rebase plusieurs branches, de gérer les conflits, de sélectionner de façon spécifique les commits que l'on veut intégrer... Et chacun de ces modifications créent des manipulations parfois complexes, qui nécessitent encore des tests, de l'intégration, des installations. Et en cas d'erreur, c'est difficile de savoir à quelle étape on s'est planté.

Voyons comment on peut simplifier tout cela avec GitButler.

## Comment intégrer le travail de tous, passé, présent, et futur, de façon continue ?

GitButler est un workflow de git qui permet de se passer du contexte de branches et le remplace par celui de branches virtuelles.

Regardez cette vidéo qui expliquera à quel point c'est renversant 🙃 :
{% embed https://youtu.be/PWc4meBj4jo?si=fCl-pobI6i4mZM1C %}

Avec GitButler, sur un ordinateur local, il n'y a qu'une seule branche qu'on va nommer `workflow`. Quand je dois travailler sur ma feature, je fais mon travail dans `workflow`, je `commit` sur `workflow`. 

Si on était en git classique, il suffit de `push` ma modif... Mais je ne peux pas, car la branche `workflow` n'est pas ma branche... C'est comme si je poussais sur `main`... Comment créer ma branche ? Comment faire ? 😨

> L'idée de GitButler, c'est qu'il n'y a pas besoin de se poser ces questions. 

On peut automatiquement depuis GitButler créer une branche virtuelle à partir d'un commit (imaginez un `git rebase -i` *user-friendly*), mais le travail reste sur la vraie branche `workflow`.

Pour demander une relecture, GitButler transforme la branche virtuelle en une vraie branche (pour permettre par exemple à une CI ou à des collègues de récupérer le travail), et lorsque la modification est approuvée par ses collègues, la branche est branchée dans `main` du projet.

La magie de GitButler, c'est qu'une fois la modification mergée sur `main`, et même avant, les contributions de tous les autres peuvent être déjà appliquées sur notre branche locale `workflow`. On peut même directement récupérer `main` distant sur notre `workflow` local, sans avoir besoin de `pull` ou `rebase` ou `merge`.

L'interface est très simple et permet de fusionner beaucoup de commits de façon simple, et de façon revenir sur les modifications vu qu'on a pas besoin de changer de branche, tout simplement.

La panoplie de tests que l'on réalisait auparavant sur chaque branche peut-être exécuté sur une seule branche, en prenant en compte facilement le travail passé, présent et futur du projet.

Vous me direz, on peut déjà faire cela avec des `cherry-pick`, des `rebase` et autres joies. Mais dès lors que vous avez beaucoup de contributions, c'est difficile à gérer simplement.

Dans l'autre sens, si on veut pousser beaucoup de modifications, et éventuellement en beaucoup de MR ou PR, c'est difficile à faire avec chaque branche qui sont potentiellement liées entre elles.

## Il y a bien des inconvénients ??

Pour l'instant je vois plusieurs arnaques, car le projet est bien récent :

1. Pour être franc, je me sens toujours un peu perdu dans GitButler tellement c'est différent
2. Le projet est très récent et il se pose encore des questions **fondamentales** non résolues dans GitButler (comment fusionner de vraies branches ?)
3. Pas d'invite de commande à ma connaissance, tout se fait par leur GUI (et je déteste ça)
4. C'est un peu difficile de savoir ce qui est sur notre branche `workflow`, et si elle correspond bien à l'appli finale...
5. Les gens ne semblent pas comprendre à quoi sert réellement GitButler ? Sur les internets je vois beaucoup de commentaires de gens pour qui ça va leur permettre de mieux gérer leurs 40 stashs ou leur rebase à 70 commits, mais pour moi c'est plutôt un problème d'organisation qui peut déjà être corrigé sans GitButler...

Les "arnaques" que je présente sont surtout de la méfiance par rapport à une technologie nouvelle. Cela ne m'empêche pas d'être **hyped**.

Il y a aussi une quantité d'enablers que pas tout le monde est prêt à entendre ou à mettre en place :

1. Avoir des CI/CD très robustes
2. Avoir la culture de la qualité, car on ne peut pas s'amuser à planter la branche principale pour tout le monde.
3. Avoir une séparation du travail claire pour éviter de faire exploser le nombre de merge conflicts
4. Avoir une *definition of done* claire et partagée auprès de toute l'équipe, en lien avec la culture de qualité de l'équipe.

Ces enablers sont de mon point de vue fortement similaires à ceux pour réaliser du Trunk Based Development.

## La suite de GitButler ?

De mon côté, j'ai essayé d'intégrer GitButler dans un de mes projets où je suis le seul à l'utiliser pendant que le reste de l'équipe reste sur un schéma GitFlow. J'avoue que j'ai eu marre de lire des issues github et de suivre leur discord pour comprendre pourquoi des fonctions de base étaient manquantes.

D'une façon plus générale, utiliser GitButler nécessite à tous les contributeurs d'un projet d'augmenter leur attention à la qualité, car avec ce workflow, on n'est plus seulement responsable de sa branche, on est responsable de l'ensemble du projet. À voir si l'industrie est prête à l'entendre...

-------------
Je m'appelle Nirina, je suis développeur front chez [Zenika](https://www.zenika.com/en-US), et merci pour cette lecture 🌻

Et vous, que pensez-vous de GitButler ? Êtes-vous prêt à faire le saut ? Jetez-y un coup d'oeil : https://gitbutler.com/