Retour au blog
ai

40 développeurs sur une app. Ce que j'ai appris va changer mes agents IA.

Par Youcef EL KAMEL
9 min de lecture

Git stacking, de la forêt au candélabre

J’ai un aveu : mon repo Git était un plat de spaghetti. Trois agents IA et moi qui poussions des features en même temps, et l’historique ressemblait à une carte météo après un ouragan.

Puis j’ai fait une prestation chez un client. 40 développeurs. Deux repos (longue histoire…). Et leur arbre Git ressemblait à un chandelier, propre, lisible, chaque commit sur une seule ligne droite.

J’ai tout pompé. Pas les outils. La méthode. Et aujourd’hui, c’est ce qui permet à mes agents IA de travailler en autonomie sur la même app sans se marcher sur les pieds.

Voici le chemin complet.

Le chaos d’avant

Quand tu bosses seul ou avec 2-3 agents, Git c’est gérable. Tu commit, tu push, tu vis ta vie.

Mais quand les features s’accumulent et que chacun travaille dans son coin, tout change. Chaque feature vit dans sa branche. Chaque branche dérive de develop. Et au moment de merger…

  • Merges croisés : la feature A merge develop, la feature B aussi, chaque merge crée un nœud dans l’historique
  • Conflits en cascade : résoudre le même conflit 3 fois parce que 3 branches divergent
  • Arbre illisible : impossible de comprendre qui a fait quoi
  • Travail dupliqué : le merge déplace le problème vers celui qui merge, c’est-à-dire moi

À un moment, j’ai regardé l’historique Git et j’ai vu un plat de spaghetti. Pas un DAG. Un plat de spaghetti.

La leçon des 40 développeurs

En arrivant chez ce client, je m’attendais au pire. 40 devs sur deux repos, ça devrait être le chaos total, non ?

Non. Leur secret : une discipline de Git que personne m’avait jamais enseignée. Pas un outil magique, un ensemble de règles que tout le monde suit, religieusement.

Règle 1 : toujours partir de la bonne base

Chaque nouvelle feature démarre toujours du dernier develop à jour. Pas d’une autre branche feature, pas d’un snapshot local. develop est la source de vérité.

Règle 2 : Rebase systématique, jamais de merge

La règle d’or : on ne merge jamais develop dans sa branche. On rebase systématiquement avant chaque push et chaque PR. Le rebase rejoue les commits par-dessus les derniers changements. L’historique reste linéaire.

Règle 3 : Squash d’abord, rebase ensuite

Si un dev a 15 commits WIP, il squash d’abord. Pourquoi ? Résoudre un conflit sur 1 commit squashé = une fois. Le même conflit sur 15 commits = 15 fois. Le squash avant rebase est non-négociable.

Règle 4 : force push, mais safe

Après un rebase, un push normal est refusé. La seule option autorisée : --force-with-lease. Jamais --force nu, ça écraserait le travail de quelqu’un d’autre. --force-with-lease refuse le push si quelqu’un a poussé entre-temps.

Règle 5 : une branche = un développeur

Jamais deux personnes sur la même branche. Sinon, le squash + force-push de l’un efface le travail de l’autre. C’est une règle culturelle, pas technique.

Le résultat : git log --graph affiche une ligne droite. Chaque commit = un ticket. git bisect fonctionne en 30 secondes. Les reviews sont propres.

Le Git stacking : empiler au lieu de fusionner

Mais la vraie révélation, c’est le stacking. Au lieu de branches parallèles qui finissent par être mergées, les devs empilent leurs changements séquentiellement.

Avant (branches parallèles + merges) :

develop: A → B ──────────── M1 ────── M2 → C
              ↘              ↗    ↗
feature-x:    X1 → X2 ─────┘   /
feature-y:    Y1 → Y2 ─────────┘

Après (stacking + rebase) :

develop: A → B → X1' → X2' → Y1' → Y2' → C

Chaque couche du stack est un PR distinct. Le premier pose les fondations, le deuxième construit dessus. Les reviews se font en parallèle, mais l’historique reste linéaire.

C’est ce concept, popularisé par Stacking.dev, qui a tout changé pour moi. Pas besoin d’outils complexes. Juste une discipline.

De 40 développeurs à mes agents IA

C’est là que ça devient intéressant. J’ai réalisé que les mêmes principes qui permettent à 40 humains de collaborer sans chaos s’appliquent exactement à mes agents IA autonomes.

Aujourd’hui, quand je lance un agent sur une feature :

  1. Il part toujours de develop, jamais d’une base stale
  2. Il rebase avant chaque push, l’historique reste propre
  3. Il squash ses commits WIP, un conflit résolu une fois, pas quinze
  4. Il pousse avec --force-with-lease, sécurité intégrée
  5. Un agent = une branche, jamais deux agents sur la même branche

Le résultat ? Mes agents travaillent en parallèle sur la même app. Chacun dans sa branche. Chacun rebasant régulièrement. Et quand c’est le moment de review, je valide du code toujours à jour, pas des diffs sur une base qui a 3 jours de retard. Chaque PR est rebasée sur le dernier develop, donc je review exactement ce qui sera mergé.

Point important : le rebase, surtout quand il y a des conflits à résoudre, nécessite un agent avec un modèle en mode thinking (raisonnement). Un modèle classique va galérer à résoudre les conflits intelligemment. Un modèle thinking analyse le contexte, comprend l’intention du code, et produit un rebase propre. Pas question de confier ça à un modèle basique.

La review facilitée : code à jour, preview propre, tests E2E ciblés

C’est là que la méthode paie vraiment. Parce que chaque agent rebase systématiquement avant de demander une review, j’ai toujours :

  • Un diff propre sur la dernière version de develop, pas un diff pollué par des centaines de lignes qui n’ont rien à voir
  • Un historique lisible, facile de cibler exactement quel commit a introduit quoi
  • Une preview web de la feature, l’agent peut builder une version preview de la branche, je la teste directement dans le navigateur

Et voici le truc qui me fait le plus gagner du temps : à partir de cette preview propre, je peux lancer un agent testeur E2E autonome qui connaît la sémantique de chaque widget de l’app. Il teste la version spécifique de la branche, pas la prod, pas develop, mais exactement la feature qui est en review. Ça change tout.

L’agent testeur :

  • Connaît les Semantics de chaque widget Flutter
  • Parcourt les parcours utilisateur critiques
  • Vérifie que la feature ne casse rien d’existant
  • Me remonte un rapport avant même que je regarde le code

Le cycle complet : agent dev → rebase → preview → agent testeur E2E → review IA → je valide. Ça fait l’objet d’un autre article à venir, abonne-toi pour ne pas le rater

Git worktree : le multi-tâche sans perte de contexte

Un autre concept que j’ai ramené de cette prestation : les worktrees. Quand tu dois switcher entre deux features urgentes, git stash + git checkout = perte de contexte.

Les worktrees permettent d’avoir deux dossiers de travail en parallèle, chacun sur sa branche. Un worktree par feature active. Chacun a son propre état de fichiers, son propre index.

Pour mes agents, c’est encore plus puissant : chaque agent peut avoir son propre worktree, travailler dans son coin sans jamais interférer avec les autres. Et on cleanup quand c’est mergé.

Pourquoi le merge déplace le problème

La question classique : merge ou rebase ? Après avoir vu les 40 devs en action, le choix est clair.

MergeRebase
HistoriqueNœuds de merge → arbre illisibleLinéaire → candélabre propre
ConflitsRésolus une fois, mais nœud permanentRésolus pendant le rebase, puis clean
BisectCassé par les mergesFonctionne en 30 sec
Charge mentale”Qui a merge quoi et quand ?”Lecture séquentielle
Pour les agentsPlus de bruit, contexte polluéUn seul flux propre à comprendre

Le merge déplace le travail vers celui qui merge. Les agents font leur job dans leurs branches, et au moment de merger, c’est moi qui gère le chaos. Avec le rebase, chaque agent gère sa propre intégration. Le travail est distribué.

Et ce travail de rebase discipliné facilite toute la chaîne en aval : la review IA voit un diff propre, le test E2E tourne sur une version ciblée, et moi je valide en quelques minutes au lieu de passer 45 min à démêler un diff incompréhensible.

Les outils du marché (et pourquoi je n’en utilise aucun)

Le stacking est un concept. Des outils l’automatisent, mais aucun n’a remplacé un bon workflow maison.

Graphite est la solution clé en main la plus complète, CLI, VS Code, merge queue, AI code review. Utilisé chez Shopify, Duolingo, Snowflake. Mais ça coûte $20-40/user/mois et ajoute une dépendance.

Git Town est plus léger, un git town sync remplace une séquence manuelle de fetch/rebase/push. Intéressant sur le papier, mais un skill bien configuré pour mes agents fait le même travail.

Et puis il y a --update-refs, disponible depuis Git 2.38. Ça met à jour automatiquement toutes les branches qui pointent vers les commits rebasés. Sans ça, le stacking manuel = rebase récursif fastidieux. Avec, le stacking natif devient viable. Pas d’abonnement. Pas de dépendance. Juste Git.

Le takeaway : pas besoin d’outils payants. La méthode des 40 devs repose sur la discipline, pas sur le tooling.

Ce qui a changé concrètement

AvantAprès
Arbre GitSpaghettiCandélabre linéaire
git bisectInutilisable30 secondes
Conflits15× le même1× par rebase
Revue de codeDiff polluéDiff propre, à jour
Temps de review30-60 min5 min + review IA + test E2E
Agents IAContexte bruité, erreursInstructions claires, prédictibles

La plus grosse différence : mes agents comprennent le repo. Un historique linéaire = un contexte propre. L’agent peut tracer n’importe quel bug en remontant une ligne droite. Plus besoin de deviner quel merge a introduit le problème.

Ressources

Ce que j’ai appris chez ce client, c’est que la collaboration à grande échelle repose sur des principes simples appliqués avec discipline. Pas des outils magiques. Et ces mêmes principes transforment complètement la façon dont mes agents IA travaillent en autonomie, du dev à la review, jusqu’aux tests E2E ciblés.

Si ce genre de contenu te parle, des leçons de dev brutes, zéro théorie, de quelqu’un qui construit des apps tous les jours, rejoins la newsletter juste en dessous

#Git #stacking #agents IA #collaboration #rebase #développement mobile #équipe #autonomie #workflow #code review