Ce qui se passe
maiao est un outil en Go qui ajoute une commande git review et transforme
chaque commit d'une branche en pull request distincte, empilée sur la
précédente — le modèle de relecture de Gerrit, porté sur GitHub, GitLab, Gitea,
Forgejo, Bitbucket Cloud et Cursor Origin.
git commit -m "Add user authentication"
git commit -m "Add authorization middleware"
git commit -m "Add admin endpoints"
git reviewRésultat : trois pull requests, chacune ciblant la précédente plutôt que la branche principale.
- PR #1 :
Add user authentication→main - PR #2 :
Add authorization middleware→ PR #1 - PR #3 :
Add admin endpoints→ PR #2
Pourquoi ça compte
Le problème est connu : une pull request de mille lignes n'est pas relue, elle est approuvée. Le découpage manuel, lui, coûte cher — une branche par morceau, des rebases en cascade dès qu'un morceau est fusionné, et des dépendances à tenir à jour à la main.
L'intérêt du modèle empilé est de rendre ce découpage mécanique : on continue à travailler en commits successifs, et l'outil se charge de la topologie.
Le mécanisme : le Change-Id
Tout repose sur un identifiant emprunté à Gerrit. Un hook commit-msg ajoute à
chaque message de commit une ligne :
Add user authentication
Implements JWT-based authentication for API endpoints
Change-Id: I8f3c2a1b5e9d7f6a4c3b2a1d0e9f8c7b6a5d4e3fL'astuce tient à la stabilité de cet identifiant. Le SHA d'un commit change à
chaque rebase ; le Change-Id, non. À partir de lui, maiao :
- dérive un nom de branche distante déterministe —
maiao.<Change-Id>—, éphémère, recréée et forcée à chaquegit review; - rattache un
git commit --fixupau bon changement, même après réécriture de l'historique ; - détecte les commits déjà présents dans la branche cible ;
- rebase automatiquement le reste de la pile quand une pull request est fusionnée.
C'est exactement le problème que le SHA seul ne peut pas résoudre : il faut une identité de changement, indépendante de l'identité de commit.
Deux limites à connaître
La maturité. C'est un fork communautaire du projet adevinta/maiao,
dont les mainteneurs d'origine ont quitté l'entreprise et dont le dépôt amont
n'est plus suivi. Environ 70 étoiles au moment de l'écriture. C'est un outil à
essayer sur un dépôt personnel avant de l'imposer à une équipe.
Le support inégal selon la forge. L'empilement natif n'existe que là où la plateforme le propose :
| Forge | Brouillon | Piles natives |
|---|---|---|
| GitHub | champ d'API | oui, enregistrement explicite |
| GitLab | préfixe Draft: |
oui, détectées automatiquement, jusqu'à 20 MR |
| Gitea, Forgejo | préfixe WIP: |
non |
| Bitbucket Cloud | non supporté | non |
Sans piles natives, les PR restent correctement chaînées par leur branche cible, mais l'interface ne les présente pas comme un ensemble.
La détection du fournisseur se fait sur l'URL du dépôt distant pour les hôtes
connus ; pour une instance auto-hébergée, l'outil demande une fois et
enregistre le choix dans git config maiao.provider.
À retenir
Le découpage en petites relectures ne tient pas à la discipline des développeurs
mais à l'outillage : tant que découper coûte des rebases manuels, personne ne
découpe. Que vous adoptiez maiao ou non, le Change-Id reste l'idée à retenir —
un identifiant de changement qui survit à la réécriture d'historique.
Source : runetes/maiao