Git Worktrees expliqués : quand et pourquoi les utiliser
Explication des git worktrees : différence avec les stashes et les clones, quand les utiliser et les commandes pour les gérer.
Un worktree Git est un répertoire de travail supplémentaire rattaché au même dépôt, avec sa propre branche extraite, ce qui permet d’avoir deux branches ouvertes dans deux dossiers en même temps sans avoir à cloner quoi que ce soit.
La plupart des développeurs en découvrent l’utilité en pleine frustration : un stash appliqué sur la mauvaise branche, un serveur de langage qui s’épuise à réindexer après un checkout, ou un second clone du même dépôt qui ne reste jamais vraiment synchronisé. Les worktrees résolvent ces trois problèmes, et ils sont livrés avec Git 2.5 depuis juillet 2015 : il n’y a donc rien à installer.
Cet article explique ce qu’est réellement un worktree sur le disque, les trois commandes qui pilotent la fonctionnalité, quand il surpasse un stash, quand il surpasse un second clone, et ce qu’il vous coûte.
Points clés à retenir
- Un worktree Git est un second répertoire de travail rattaché au même dépôt, avec sa propre branche extraite ; le répertoire lié contient un petit fichier
.gitqui pointe vers le dépôt principal, et non un dossier.gitcomplet. - Une seule commande
git worktree add -b hotfix-bug ../hotfix-workspace mainremplace toute la séquence stash, checkout, création de branche, correction et stash pop. - Tous les worktrees partagent une même base d’objets et un même ensemble de refs : un seul
git fetchmet donc tout le monde à jour et aucun historique n’est dupliqué sur le disque. - Git suit les fichiers versionnés, pas votre environnement : les dépendances installées, les fichiers
.envet les caches de build restent dans le répertoire d’origine. - Par défaut, Git refuse d’extraire la même branche dans deux worktrees ; créez un worktree en HEAD détachée avec
git worktree add -dlorsque vous avez seulement besoin de compiler ou de tester un commit.
Qu’est-ce qu’un worktree Git sur le disque ?
Un worktree lié est un répertoire de fichiers extraits, pas une copie de votre dépôt. Son .git de premier niveau est un simple fichier, et non un répertoire, et il pointe vers un petit dossier de métadonnées situé sous le .git/worktrees/ du dépôt principal, une organisation que la documentation de git worktree détaille intégralement. Tout ce qui est volumineux reste au même endroit : une seule base d’objets, un seul historique et un seul ensemble de refs servent tous les worktrees, et seule une poignée de fichiers appartient en propre à un worktree, dont HEAD et l’index.
Ce seul fait explique tout le reste à propos des worktrees. En créer un coûte un checkout, pas un clone. Les commits réalisés dans n’importe quel worktree sont immédiatement visibles depuis tous les autres, puisqu’il n’existe qu’un seul dépôt en dessous.
Quel workflow un worktree remplace-t-il ?
Sans worktrees, une interruption urgente implique de suspendre votre état courant. La séquence familière, avec la forme git stash push pour que le message soit effectivement attaché :
git stash push -m "wip: login form"
git checkout main
git checkout -b hotfix-bug
# fix, commit, push, wait for the merge
git checkout feature-login
git stash pop
Cinq commandes, deux changements de contexte, et une occasion d’appliquer le stash sur la mauvaise branche. La version worktree tient en une commande :
git worktree add -b hotfix-bug ../hotfix-workspace main
Cela crée un dossier voisin, crée la branche hotfix-bug à partir de main, et l’extrait à cet endroit. Votre répertoire d’origine reste intact : même branche, mêmes fichiers modifiés, même éditeur ouvert. Une fois le correctif fusionné, git worktree remove ../hotfix-workspace supprime le dossier et le désenregistre.
Les trois commandes : add, list, remove
L’usage quotidien des worktrees repose sur trois sous-commandes. git worktree add <path> <branch> extrait une branche existante vers un nouveau chemin ; ajoutez -b <new-branch> avant le chemin pour créer la branche au passage. Indiquez à add un chemin qui n’existe pas encore et Git créera le répertoire pour vous.
git worktree list affiche tous les worktrees, le principal en premier, avec leur chemin, le hash de commit abrégé et la branche extraite entre crochets :
/home/you/project abc1234 [feature-login]
/home/you/hotfix-workspace def5678 [hotfix-bug]
git worktree remove <path> supprime un worktree, et les règles de suppression de Git sont strictes : un seul fichier non suivi ou un seul fichier suivi modifié bloque la commande, sauf si vous ajoutez --force, qui écarte alors ces modifications. Git refuse purement et simplement de lâcher le worktree principal, et un worktree verrouillé exige --force deux fois. Si vous supprimez plutôt le dossier d’un worktree à la main, git worktree prune nettoie les métadonnées laissées derrière.
Quand un worktree vaut-il mieux qu’un stash ?
Un stash suspend votre travail ; un worktree le laisse tourner. C’est cette distinction qui détermine lequel vous convient. Un stash fait très bien l’affaire pour mettre de côté un diff de deux lignes pendant dix minutes. C’est le mauvais outil lorsque le travail dans votre répertoire est encore en cours : une suite de tests ou un build long en pleine exécution, un serveur de développement qui surveille les fichiers, ou un éditeur dont le serveur de langage réindexerait tout le projet après un changement de branche.
Avec un worktree, rien de cet état n’est perturbé, puisque vous ne touchez jamais au répertoire d’origine. Vous ouvrez le nouveau dossier dans une seconde fenêtre d’éditeur, réalisez la tâche interruptrice là-bas, puis revenez retrouver tout exactement là où vous l’avez laissé. C’est cette même isolation qui explique que les outils exécutant des agents de codage IA en parallèle ont adopté les worktrees comme modèle de travail. Pour un point de vue plus tranché, l’article de matklad décrit l’organisation d’un développeur autour d’un ensemble fixe de cinq worktrees associés à des activités concurrentes plutôt qu’à des branches ; à considérer comme une configuration personnelle, pas comme une pratique standard.
Worktree ou second clone ?
Un worktree vaut mieux qu’un second clone dès lors que les deux répertoires sont censés suivre le même dépôt. Comme chaque worktree partage une même base d’objets et un même ensemble de refs, un seul git fetch les met tous à jour, une branche poussée depuis l’un est instantanément visible dans les autres, et ajouter un worktree ne duplique aucun historique sur le disque. Un second clone ne vous offre rien de tout cela : deux bases d’objets à alimenter, deux ensembles de refs qui divergent, et le double d’espace disque.
Un clone reste le bon choix dans deux cas : quand le travail relève d’un remote véritablement différent, comme un fork avec lequel vous interagissez séparément, ou quand vous voulez une expérimentation jetable totalement isolée de votre dépôt principal, où même des refs partagées sont indésirables.
| Stash | Worktree | Second clone | |
|---|---|---|---|
| Le travail continue de tourner | Non | Oui | Oui |
| Coût de mise en place | Immédiat | Un checkout | Un clone complet |
| Historique sur le disque | Partagé | Partagé | Dupliqué |
| Un seul fetch met à jour | Oui | Oui | Non |
Que coûtent les worktrees ?
Git suit les fichiers versionnés, pas votre environnement. C’est là le principal impôt à payer pour chaque nouveau worktree :
- Les dépendances installées ne suivent pas. Un worktree tout neuf d’un projet npm ou pip nécessite généralement sa propre étape d’installation avant de pouvoir être compilé.
- Les fichiers locaux non suivis restent en arrière : fichiers
.env, configuration locale et caches de build vivent tous dans le répertoire d’origine, parce que Git n’en garde aucune trace. - Les dossiers de worktree créés à l’intérieur du dépôt apparaissent comme du désordre non suivi et nécessitent une entrée dans
.gitignore. Des répertoires voisins (../hotfix-workspace) évitent complètement le problème. - Par défaut, une branche ne peut être extraite que dans un seul worktree à la fois. Des contournements existent (
--forcesuradd,--ignore-other-worktreessurswitch), mais la réponse la plus propre, quand vous avez seulement besoin de compiler ou de tester un commit, est un worktree en HEAD détachée :
git worktree add -d ../build-check 1a2b3c4
L’option -d laisse HEAD détachée dans le nouveau dossier : aucune branche n’est réservée et la restriction ne se déclenche jamais. git switch -d <commit> dans un worktree existant remplit le même rôle.
En avez-vous assez sur le feu ?
Le test d’adoption est court. Des interruptions surviennent-elles régulièrement alors que vous avez du vrai travail non commité en cours ? Un changement de branche déclenche-t-il une réinstallation de dépendances ou une réindexation du serveur de langage que vous ressentez ? Maintenez-vous déjà un second clone du même dépôt ? Deux « oui » et les worktrees seront rentabilisés dès la première semaine. Aucun, et le duo stash + branches convient parfaitement. Commencez par un seul : la prochaine fois qu’un correctif urgent tombe en pleine fonctionnalité, lancez git worktree add au lieu de git stash, et supprimez le dossier une fois le correctif fusionné.
FAQ
Les worktrees Git fonctionnent-ils avec des dépôts qui utilisent des submodules ?
En partie. Le manuel de Git lui-même signale dans sa note BUGS que la prise en charge des submodules est inachevée, et déconseille d'extraire un superprojet en plus d'un endroit à la fois. En pratique, un worktree lié contenant des submodules ne peut pas être déplacé avec git worktree move, et sa suppression avec git worktree remove nécessite l'option force. Si votre dépôt s'appuie fortement sur les submodules, un second clone est le choix le plus sûr.
Les stashes et les branches sont-ils partagés entre les worktrees Git ?
Oui. Tout ce qui se trouve sous refs/ est commun à tous les worktrees : branches, tags et stash sont donc identiques où que vous soyez. Trois espaces de noms font exception et restent locaux à un worktree : refs/bisect, refs/worktree et refs/rewritten. Au-delà de ceux-là, seuls les pointeurs propres à un worktree sont privés, dont HEAD et son index. Un stash créé dans un worktree peut donc être listé, et appliqué, depuis n'importe quel autre worktree du même dépôt.
Puis-je déplacer un worktree vers un autre dossier après l'avoir créé ?
Oui. Passez à git worktree move le worktree et le chemin visé, et Git déplace le dossier et réécrit ses métadonnées d'un seul coup. Deux cas qu'il ne gérera pas : le worktree principal, et tout worktree lié contenant des submodules. Un worktree verrouillé exige l'option force deux fois. Si vous avez déjà déplacé le dossier vous-même, git worktree repair rétablit la connexion.
Que se passe-t-il si j'exécute git worktree add avec seulement un chemin et aucune branche ?
Git prend la dernière partie du chemin comme nom de branche, démarre cette branche à HEAD et l'extrait dans le nouveau dossier. Ainsi, git worktree add ../hotfix vous laisse avec une branche nommée hotfix, extraite dans ../hotfix. Si ce nom est déjà pris, Git extrait la branche existante à la place, à condition qu'aucun autre worktree ne la détienne actuellement.