Qu’est-ce qu’un git worktree et comment l’utiliser ?
Un git worktree donne à chaque agent de codage ses fichiers, sans tout séparer. Nous avons étudié cinq outils et notre dépôt.
En bref. Un git worktree ouvre un deuxième répertoire de travail à partir du même dépôt : les fichiers sont séparés, l’historique des commits et les branches sont partagés. Les cinq outils de codage que nous avons étudiés savent tous ouvrir un worktree pour séparer les agents qui travaillent en parallèle. Le 18 octobre 2026, nous avons lu dans la documentation de chaque outil comment Claude Code, Codex, Cursor, Gemini CLI et GitHub Copilot ouvrent et ferment un worktree. Les exemples et les chiffres viennent du dépôt où nous travaillons tous les jours avec des agents en parallèle. Le 28 octobre 2026, nous avons ajouté Antigravity CLI, de Google.
- Un worktree sépare les fichiers et partage le dépôt. Chaque worktree a ses propres fichiers, son propre HEAD et son propre index. Les branches, le stash et la configuration du dépôt (y compris le chemin des hooks) sont communs à tous.
- Les cinq outils le prennent en charge, avec des réglages par défaut différents. L’endroit où le worktree est créé, le commit dont il part, le fait qu’il apporte ou non des fichiers comme
.envet le moment où il est supprimé changent d’un outil à l’autre. - Le vrai problème, c’est qu’ils s’accumulent. Le 18 octobre 2026, notre dépôt comptait 66 worktrees. Pour au moins 34 d’entre eux, la branche avait déjà été fusionnée.
- Un contrôle à l’ouverture de session ne suffit pas. Quand deux sessions sont ouvertes dans le même répertoire, l’une peut changer la branche sur laquelle travaille l’autre. Nous utilisons donc un hook qui vérifie à nouveau la branche et le commit avant chaque modification.
Qu’est-ce qui casse quand deux agents travaillent dans le même répertoire ?
Aujourd’hui, nous faisons le plus souvent tourner nos agents de codage en parallèle : une session écrit une nouvelle fonctionnalité pendant qu’une autre corrige un bug, et des sous-agents modifient en même temps des fichiers différents. S’ils travaillent tous dans le même répertoire, ils partagent les mêmes fichiers, la même branche et le même index git. Dans le dépôt où nous développons diffox, nous l’avons payé plusieurs fois. Chaque fois, nous en avons tiré une règle :
- Un simple commit a aussi emporté le travail d’un autre agent.
git commitcommite tout ce qui se trouve dans l’index, y compris les fichiers qu’un autre agent du même répertoire a préparés. Notre règle : les agents qui travaillent en parallèle ne commitent que leurs propres fichiers (git commit --only <chemins>). - Un
git checkout -ba changé la branche d’une autre session. Le shell de l’agent revient à son répertoire de départ à chaque commande, et une commande git lancée sans chemin a un jour changé la branche d’une session parallèle. Notre règle : chaque commande git indique son chemin explicitement (git -C <chemin absolu>). - Une session a prévu des modifications dans un répertoire qui a changé 3 fois de branche en 40 minutes. C’est pour cela qu’existe le hook d’ouverture de session présenté dans l’article sur les hooks.
- Notre script de nettoyage a fait la même erreur. Le script qui supprime les branches fusionnées basculait sur
devchaque répertoire propre qu’il trouvait. Or un répertoire propre peut appartenir à une autre session qui n’a simplement pas encore commencé à écrire ; le script a changé la branche de cette session. Désormais, il ne bascule qu’un répertoire qui se trouve surdev, surmainou sur une branche dont la pull request a été fusionnée.
Le point commun de tous ces cas, c’est un répertoire unique. C’est à cela que sert un worktree : il donne à chaque agent son propre répertoire, sa propre branche et son propre index. Mais, comme vous le verrez plus bas, il ne sépare pas tout. Nous avons présenté le réglage isolation: worktree de Claude Code dans l’article sur les sous-agents. Cet article-ci s’intéresse au dépôt que les agents partagent.
Qu’est-ce qu’un git worktree ?
D’après la documentation de git, un dépôt peut avoir plusieurs répertoires de travail (working trees), ce qui permet d’avoir plusieurs branches extraites en même temps. Le répertoire obtenu avec git clone est le worktree principal. Ceux que vous ouvrez avec git worktree add sont des worktrees liés (linked worktrees).
Un worktree lié partage tout avec le dépôt, à part quelques fichiers qui lui sont propres, comme HEAD et l’index. L’historique des commits n’est stocké qu’une fois ; chaque worktree ne contient que sa propre copie des fichiers. Ces commandes font l’essentiel du travail :
git worktree add -b recherche ../projet-recherche # nouveau répertoire, nouvelle branche
git worktree list # tous les worktrees
git worktree remove ../projet-recherche # le supprime s'il est propre
git worktree prune # nettoie les entrées des worktrees dont le répertoire a été supprimé à la mainGit empêche certaines erreurs de lui-même. Une branche ne peut être extraite que dans un seul worktree à la fois : par défaut, add refuse une branche déjà extraite dans un autre worktree. Et remove ne supprime que les worktrees propres ; pour en supprimer un qui contient des modifications non commitées ou des fichiers non suivis, il faut --force.
La différence entre worktree et branche. Une branche est un nom qui pointe vers un commit. Un worktree est un répertoire où sont extraits les fichiers d’une branche. Quand vous changez de branche dans un répertoire unique, les fichiers changent pour tous ceux qui y travaillent. Avec les worktrees, chaque agent reste dans son propre répertoire, sur sa propre branche. Une remarque : la documentation de git elle-même considère toujours les checkouts multiples comme expérimentaux et indique que la prise en charge des sous-modules est incomplète.
Comment ouvrir un worktree dans les outils de codage ?
Les cinq outils savent créer un worktree eux-mêmes ; dans Gemini CLI, la fonctionnalité est expérimentale et s’active dans les paramètres. Les outils diffèrent sur l’endroit où le worktree est créé, le commit dont il part, le fait qu’il apporte ou non les fichiers ignorés par git (comme .env) et le moment où il est supprimé.
| Outil | Comment l’ouvrir | Où | Commit de départ | Fichiers comme .env | Quand il est supprimé |
|---|---|---|---|---|---|
| Claude Code | claude --worktree <nom> ; pour un sous-agent, isolation: worktree | .claude/worktrees/<nom>/ | Branche par défaut du dépôt distant ; HEAD local avec worktree.baseRef: "head" | Copiés s’ils figurent dans .worktreeinclude | En quittant la session : automatiquement pour une session sans nom s’il est propre ; s’il contient du travail, Claude Code vous demande. Worktrees de sous-agents et d’arrière-plan une fois cleanupPeriodDays dépassé (par défaut 30 jours), s’il n’y reste aucun travail |
| Codex | Choisir Worktree dans une nouvelle conversation | $CODEX_HOME/worktrees | HEAD de la branche choisie, avec ses modifications non commitées ; aucune branche créée, detached HEAD | Copiés s’ils figurent dans .worktreeinclude | Garde par défaut les 15 derniers worktrees ; prend un instantané avant d’en supprimer un |
| Cursor | Choisir worktree dans l’Agents Window ; /worktree dans l’IDE | Non précisé dans la documentation | Non précisé dans la documentation | Pas d’eux-mêmes ; via les commandes d’installation de .cursor/worktrees.json | Périodiquement ; garde par défaut au plus 25 worktrees par machine |
| Gemini CLI | S’active dans les paramètres (expérimental), puis gemini --worktree <nom> | .gemini/worktrees/<nom> | Non précisé dans la documentation | Non précisé dans la documentation | Jamais de lui-même, le nettoyage est à votre charge |
| GitHub Copilot CLI | copilot --worktree ou /worktree dans la session | <dépôt>.worktrees/ | HEAD du checkout où vous êtes ; branche par défaut du dépôt distant avec worktreeBaseRef: "defaultBranch" | Non précisé dans la documentation | Non précisé dans la documentation |
Source : la documentation worktree de chaque outil, 18 octobre 2026. « Non précisé dans la documentation » : sur la page que nous avons lue ce jour-là, nous n’avons trouvé aucune phrase à ce sujet. La ligne Codex concerne Codex dans l’application de bureau ChatGPT, celle que décrit la page. Le nettoyage de Cursor est décrit pour la version 3.5 et les suivantes. L’application GitHub Copilot ouvre elle aussi un worktree et une branche distincts pour chaque session.
La différence la plus importante, c’est le point de départ. Par défaut, Claude Code part de la branche par défaut du dépôt distant : les commits que vous n’avez pas encore pushés ne sont pas dans le nouveau worktree. Copilot CLI, lui, part du HEAD du checkout où vous vous trouvez. Codex va jusqu’à reporter dans le nouveau worktree les modifications non commitées de la branche choisie. Choisissez ce réglage en connaissance de cause, selon ce que l’agent doit voir.
Les fichiers ignorés par git n’arrivent pas dans le nouveau worktree. Pour cela, Claude Code et Codex lisent un fichier du même nom : .worktreeinclude, à la racine du dépôt. Il s’écrit avec la syntaxe de .gitignore et ne copie que les fichiers ignorés par git. Dans Cursor, ce sont les commandes d’installation de .cursor/worktrees.json qui font ce travail ; l’exemple de la documentation copie .env avec cp.
Sur les dépendances, deux outils ne donnent pas le même conseil. Cursor déconseille d’amener les dépendances dans le worktree par un lien symbolique, car cela peut poser problème dans le worktree principal. Claude Code, au contraire, peut amener par lien symbolique de gros répertoires comme node_modules dans chaque worktree, grâce au réglage worktree.symlinkDirectories.
Il existe aussi des commandes toutes prêtes pour le travail en parallèle. Le skill /batch de Claude Code découpe un gros changement entre 5 et 30 sous-agents, chacun dans son propre worktree. La commande /best-of-n de Cursor lance la même tâche sur plusieurs modèles et donne à chaque exécution son propre worktree. Les équipes d’agents (agent teams) de Claude Code, en revanche, ne placent pas leurs membres dans des worktrees séparés ; la documentation conseille de découper le travail pour que chaque membre soit responsable de fichiers différents.
Le 18 juin 2026, Google a cessé de servir Gemini CLI aux utilisateurs gratuits et aux abonnés Google AI Pro et Ultra, et les a orientés vers Antigravity CLI ; avec une clé d’API payante ou une licence d’entreprise, vous pouvez continuer à utiliser Gemini CLI. Nous avons lu la documentation d’Antigravity le 28 octobre 2026. D’après sa page sur les sous-agents, l’agent principal peut donner à un sous-agent qu’il lance son propre worktree Git ; quand le sous-agent est arrêté, ce worktree est supprimé automatiquement. La documentation ne dit pas de quel commit part le worktree, ni s’il apporte des fichiers comme .env. L’application de bureau sait ouvrir une nouvelle conversation directement dans son propre worktree ; dans la CLI, nous n’avons trouvé aucune option qui le fasse.
Que sépare un worktree, et que ne sépare-t-il pas ?
On a vite fait de voir un worktree comme un bac à sable complet. Pourtant, git ne donne à chaque worktree que quelques éléments à lui. Le reste est partagé, et une partie échappe complètement à git :

La configuration et le chemin des hooks sont partagés. D’après git, le fichier de configuration du dépôt est par défaut commun à tous les worktrees. Dans notre dépôt, l’emplacement des hooks git est lui aussi écrit dans ce fichier (core.hooksPath), sous la forme d’un seul chemin absolu. Le hook pre-push, qui s’exécute avant un push, tourne donc depuis la copie du worktree principal, et non depuis la copie de la branche dont vous faites le push. Le 24 août 2026, nous avons ajouté une nouvelle règle à ce hook sur une branche de worktree, et ses 11 tests sont passés. Mais un push depuis ce même worktree est quand même passé, car le worktree principal contenait l’ancienne version. Il en va de même pour d’autres réglages comme l’identité (user.email) ; pour une configuration propre à un worktree, il faut activer extensions.worktreeConfig dans git.
Les permissions des outils eux-mêmes peuvent aussi être partagées. Dans Claude Code, une autorisation « Yes, and don’t ask again » donnée dans un worktree est écrite dans le fichier .claude/settings.local.json du worktree principal et s’applique dans tous les worktrees. Dans Copilot CLI aussi, les worktrees liés partagent les permissions du dépôt principal.
Les branches et le stash sont partagés. D’après git, toutes les références qui commencent par refs/ sont communes aux worktrees, et le dernier stash est conservé dans refs/stash. Un git stash pop sans nom de stash prend le plus récent. En mettant côte à côte ces phrases de la documentation de git, on obtient ceci : un git stash pop dans un worktree prend le dernier stash, même si c’est un agent d’un autre worktree qui l’a laissé. Dans un dépôt où des agents travaillent en parallèle, un commit temporaire est plus sûr qu’un stash.
Ce qui est hors de git n’est pas séparé du tout. Une base de données, un port, un cache ou un répertoire de données ignoré ne savent rien des worktrees. Dans notre dépôt, nous relions un gros répertoire de mesures (.runs) à chaque worktree par un lien symbolique, parce que des résultats de mesures payantes s’y trouvent et qu’ils ne doivent pas disparaître quand un worktree est supprimé. Le motif .runs/ du .gitignore ne correspond qu’à des répertoires ; il n’a donc pas ignoré ce lien. Le 21 août 2026, git status l’affichait comme fichier non suivi dans chaque worktree ; il était à un git add -A d’entrer dans un commit. Nos tests de base de données utilisent aussi une base de test commune. Pour que les tests de deux worktrees ne tournent pas en même temps, nous gardons un répertoire de verrou.
Pourquoi un contrôle à l’ouverture de session ne suffit-il pas ?
Regarder l’état du répertoire à l’ouverture d’une session est utile, mais seulement pour cet instant. Dans notre dépôt, le hook d’ouverture de session dit à une session qui démarre sur un dev propre : « une branche suffit, pas besoin de worktree ». Si deux sessions s’ouvrent sur le même dev propre, elles reçoivent toutes les deux cette réponse et créent toutes les deux une branche dans le même répertoire. Quand la seconde passe sur sa nouvelle branche, la branche sur laquelle travaille la première a changé elle aussi.
C’est pourquoi un second hook, qui s’exécute avant chaque modification, compare la branche et le commit avec ce qui a été dit à la session en dernier. Les détails sont dans l’article sur les hooks ; ce que nous voulons ajouter ici, c’est ce qui est comparé. La première idée qui vient, c’est le nombre de fichiers non commités. Mais le 12 septembre 2026, nous avons vu qu’une seule modification faite par la session elle-même fait passer un répertoire propre pour modifié. Une alerte qui regarde cela prend le travail de l’agent pour celui d’un autre. Le hook ne regarde donc que la branche et le commit en dessous, et il avertit sans arrêter l’opération.
Le hook ne peut pas savoir qui a fait le changement, et il n’essaie pas de le deviner. Une session qui crée sa propre branche est elle aussi avertie une fois ; elle y reconnaît son propre geste et continue.
Claude Code lance en plus ses propres contrôles pour une session isolée dans un worktree. D’après sa documentation, il refuse les modifications qui visent un chemin du checkout principal et les commandes qui dirigent git vers le checkout principal. La documentation écrit aussi clairement la limite : ces contrôles ne suivent pas les fichiers dans lesquels une commande shell écrit. Une commande qui écrit dans le checkout principal avec cp ou une redirection n’est pas arrêtée par ces contrôles ; d’après la documentation, elle est traitée selon vos réglages de permissions et de sandbox. Autrement dit, ce n’est pas le worktree qui limite l’endroit où un agent peut écrire, ce sont ces réglages.
Pourquoi les worktrees s’accumulent-ils, et comment les nettoyer ?
Ouvrir un worktree tient en une commande ; le refermer, on l’oublie souvent. Comme nous l’avons raconté dans l’article sur les sous-agents, le 27 août 2026, 41 worktrees s’étaient accumulés dans notre dépôt, dont 37 laissés par un seul tour de review. Ce désordre vient des workflows, pas des personnes. Ce jour-là, nous avons écrit un script de nettoyage. Le 18 octobre 2026, nous avons recompté :

git worktree list --porcelain et gh pr list ; les commandes et leur sortie sont dans le fichier de mesures de l’article.Aucun des 34 worktrees dont la branche avait été fusionnée ne contenait de modifications non commitées. C’est exactement ce type de worktree que notre script de nettoyage supprime. Mais le script ne se lance pas tout seul ; le hook d’ouverture de session se contente de proposer de le lancer, et tant que personne ne le fait, tout reste en place. Au total, 5 worktrees se trouvaient dans le répertoire de Codex (~/.codex/worktrees) et les 61 autres sous .claude/worktrees/. D’après la date de création du répertoire que git tient pour chaque worktree, 28 de ceux qui étaient encore là avaient été ouverts en une seule journée, le 15 octobre. Le brouillon de cet article a lui aussi été écrit dans un worktree ouvert le 18 octobre 2026.
Git ne peut pas dire qu’une branche a été fusionnée. Notre dépôt fusionne les pull requests par squash, et un squash réécrit les commits. Une branche fusionnée n’est donc ni un ancêtre de dev, ni identique commit pour commit. Nous avons regardé une branche quelques minutes après son merge : merge-base --is-ancestor a répondu « non fusionnée », git cherry « 2 commits manquants » ; les deux avaient tort. Une autre branche, dont tout le contenu était dans dev, apparaissait avec « 36 commits d’avance ». Le seul endroit qui le sait, c’est la pull request. C’est pourquoi notre script de nettoyage interroge GitHub et ne supprime que les worktrees propres dont la pull request a été fusionnée.
Le nombre lui-même peut tromper. Un worktree dont le répertoire a été supprimé à la main reste dans la liste, marqué prunable, jusqu’à ce que git worktree prune s’exécute. Notre hook d’ouverture de session comptait d’abord toutes les lignes ensemble. Le 8 septembre 2026, il a annoncé 26 worktrees ; quelques commandes plus tard, git worktree list en montrait 7. Il compte désormais à part les worktrees vivants et les entrées supprimables, et propose le script de nettoyage dès qu’il y a plus de 4 worktrees vivants ou une seule entrée supprimable.
Le nettoyage propre à chaque outil diffère aussi. Codex garde par défaut ses 15 derniers worktrees. Cursor garde par défaut 25 worktrees par machine et, d’après sa documentation, considère aussi comme supprimables les worktrees créés avec git worktree add. Claude Code fait le ménage dans les worktrees des sous-agents et des sessions en arrière-plan, mais laisse ceux qui contiennent encore du travail. Gemini CLI, lui, vous laisse le nettoyage. Si vous utilisez plusieurs outils dans le même dépôt, sachez lequel supprime quoi.
À quoi faire attention quand on fait tourner des agents en parallèle ?
Chaque erreur ci-dessus a donné un point. Réunis, ils donnent ceci :

git -C, le verrou et le nettoyage sont des règles de notre dépôt ; le point sur le stash vient de la documentation de git, celui sur l’installation de la documentation des outils.- Tous les agents n’ont pas besoin d’un worktree. Un worktree sert quand deux travaux veulent le même dépôt en même temps, sur des commits différents. Si une seule session travaille sur un
devpropre, une branche suffit. Chaque worktree inutile, c’est un répertoire de plus à nettoyer ensuite. - N’oubliez pas l’installation. Un nouveau worktree est un checkout neuf : pas de dépendances, pas d’environnement virtuel, pas de
.env. Les documentations de Claude Code et de Gemini CLI demandent elles aussi d’installer l’environnement dans chaque nouveau worktree. Dans notre dépôt, chaque worktree installe son propre environnement avant sa première exécution de tests. - Découpez le travail par fichiers. Dans notre dépôt, les tâches qui tournaient en même temps avaient chacune leurs fichiers, chaque commit était fait avec
--only, et les exécutions de tests attendaient leur tour derrière le verrou commun. - Le parallélisme n’est pas gratuit. D’après la documentation de Claude Code, faire tourner plusieurs sessions ou sous-agents à la fois multiplie la consommation de tokens.
Au bout du compte, le travail des agents en parallèle arrive sur la même branche sous forme de pull requests, et cette branche avance à chaque merge. Quand diffox examine une pull request, il mesure le changement à partir du point où la branche s’est séparée de la branche de base (la merge base) ; c’est le changement que GitHub affiche dans la pull request. Il lit aussi l’état précédent des fichiers à ce même point. Ainsi, si le travail d’un autre agent a été fusionné plus tard dans la branche de base, il ne se mêle pas à cette review.
Questions fréquentes
Qu’est-ce qu’un git worktree ?
Un git worktree est un deuxième répertoire de travail ouvert à partir du même dépôt. Chaque worktree a ses propres fichiers, son propre HEAD et son propre index ; l’historique des commits, les branches et la configuration du dépôt sont partagés. On le crée avec git worktree add -b <branche> <répertoire> et on le supprime avec git worktree remove <répertoire>. Vous pouvez ainsi travailler sur plusieurs branches à la fois, sans toucher au répertoire où vous êtes.
Quelle est la différence entre un worktree et une branche ?
Une branche est un nom qui pointe vers un commit ; un worktree est un répertoire où sont extraits les fichiers d’une branche. Quand vous changez de branche dans un répertoire unique, les fichiers changent pour tous ceux qui y travaillent. Avec les worktrees, chaque branche reste extraite dans son propre répertoire. Git n’autorise une branche que dans un seul worktree à la fois ; si vous voulez extraire la même branche dans un deuxième worktree, git worktree add refuse.
Comment ouvrir un worktree dans Claude Code ?
claude --worktree <nom> (en abrégé -w) crée un nouveau worktree et y démarre la session. Par défaut, le worktree est créé sous .claude/worktrees/<nom>/, sur une nouvelle branche nommée worktree-<nom>, et part de la branche par défaut du dépôt distant. Pour qu’un sous-agent travaille toujours dans son propre worktree, ajoutez isolation: worktree à sa définition. La documentation conseille d’ajouter le répertoire .claude/worktrees/ au .gitignore.
Où Codex et Cursor rangent-ils les worktrees, et quand les suppriment-ils ?
Dans l’application de bureau ChatGPT, Codex crée les worktrees sous $CODEX_HOME/worktrees, en detached HEAD plutôt que sur une branche. Par défaut, il garde les 15 derniers worktrees et prend un instantané d’un worktree avant de le supprimer. Dans Cursor (3.5 et versions suivantes), le nettoyage s’exécute périodiquement et garde par défaut au plus 25 worktrees par machine ; tous les espaces de travail comptent dans la même limite. La documentation de Cursor ne dit pas dans quel répertoire les worktrees sont créés.
Un worktree copie-t-il le fichier .env et les dépendances ?
Pas de lui-même ; un nouveau worktree démarre seulement avec les fichiers suivis par git. Claude Code et Codex copient les fichiers ignorés par git (comme .env) s’ils figurent dans le fichier .worktreeinclude à la racine du dépôt. Dans Cursor, les commandes d’installation s’écrivent dans .cursor/worktrees.json. Les dépendances, il faut les réinstaller dans chaque worktree. Claude Code peut amener de gros répertoires par lien symbolique avec worktree.symlinkDirectories, tandis que Cursor le déconseille pour les dépendances.
Comment supprimer les worktrees qui ne servent plus ?
git worktree remove <répertoire> supprime un worktree propre ; s’il contient des modifications non commitées, il faut --force. Si vous avez supprimé le répertoire à la main, git worktree prune efface l’entrée restée derrière. Codex et Cursor suppriment eux-mêmes les vieux worktrees au-delà d’une limite, Gemini CLI non. Antigravity supprime le worktree qu’il a donné à un sous-agent dès que ce sous-agent est arrêté. Dans un dépôt qui fusionne les pull requests par squash, git ne peut pas dire si une branche a été fusionnée ; demandez-le à la pull request.