git worktree : travailler sur plusieurs branches en même temps
git worktree permet d'associer plusieurs répertoires de travail à un même dépôt, chacun avec sa propre branche ouverte. La commande git worktree add ../hotfix main crée à côté du projet un dossier sur la branche main ; l'historique et les objets sont partagés, et il n'y a rien à recloner.
Ce que fait git worktree
git worktree associe plusieurs répertoires de travail à un seul dépôt. Dans le dossier principal, vous avez votre branche de fonctionnalité ; dans le dossier voisin, main pour un hotfix urgent — et les deux existent en même temps. Les objets, les commits et les branches sont partagés : un commit fait dans un dossier est immédiatement visible depuis l'autre, sans push ni fetch.
Sans worktree, changer de contexte ressemble à ceci : git stash, git switch main, correction, git switch en sens inverse, git stash pop. Si le projet a un build long ou un node_modules volumineux, chaque changement de branche invalide en plus les caches. L'autre option est de recloner le dépôt, mais vous obtenez alors deux copies indépendantes de l'historique qu'il faut synchroniser via le serveur distant.
Worktree réunit le meilleur des deux approches : des dossiers séparés, mais une seule base .git. C'est possible parce qu'une branche Git n'est qu'un pointeur vers un commit, et non une copie de fichiers, et rien n'empêche des copies de travail différentes de regarder des pointeurs différents.
Comment créer une copie de travail supplémentaire
La forme de base de la commande : git worktree add <chemin> [<branche>]. Voyons les principales variantes.
Ouvrir une branche existante
cd ~/projects/shop
git worktree add ../shop-main main
Preparing worktree (checking out 'main')
HEAD is now at 3f2c1ab Mettre à jour le README
Un dossier shop-main apparaît à côté du projet, sur la branche main. Entrez-y avec un simple cd et travaillez comme dans n'importe quel dépôt.
Créer une nouvelle branche avec sa copie de travail
git worktree add -b hotfix/payment-timeout ../shop-hotfix main
L'option -b crée la branche hotfix/payment-timeout à partir de main et l'ouvre dans le nouveau dossier. L'option -B fait la même chose, mais si la branche existe déjà, elle la réinitialise sur le commit indiqué — à utiliser avec prudence.
Forme courte
git worktree add ../experiment
Si vous n'indiquez pas de branche, Git crée une nouvelle branche portant le nom du dernier élément du chemin (ici experiment) à partir du HEAD courant. Si une branche de ce nom existe déjà, c'est elle qui est ouverte.
Copie de travail sans branche
git worktree add --detach ../shop-v1.4 v1.4.0
Le mode detached HEAD est pratique pour construire ou vérifier une ancienne release à partir d'un tag, sans créer de branches inutiles.
Branche du serveur distant
git fetch origin
git worktree add ../review-auth feature/auth
S'il n'existe pas de branche locale feature/auth mais exactement une branche distante origin/feature/auth, Git crée une branche locale qui la suit — comme avec git switch feature/auth. C'est pratique pour relire la pull request d'un collègue sans toucher à votre travail.
Comment lister et supprimer les copies de travail
git worktree list
/home/anna/projects/shop a1b2c3d [feature/cart]
/home/anna/projects/shop-hotfix 7e8f9a0 [hotfix/payment-timeout]
/home/anna/projects/shop-v1.4 5d6e7f8 (detached HEAD)
La première ligne est la copie de travail principale (main worktree), les autres sont liées (linked). Pour les scripts, il existe une sortie lisible par une machine : git worktree list --porcelain.
Une fois le hotfix fusionné, supprimez la copie de travail :
git worktree remove ../shop-hotfix
git branch -d hotfix/payment-timeout
git worktree remove supprime le dossier et les entrées internes. Si la copie contient des modifications non commitées ou des fichiers non suivis, la commande refuse ; n'ajoutez --force que si vous êtes sûr de ne pas en avoir besoin. Notez que la branche elle-même n'est pas supprimée, il faut le faire à part.
Si le dossier a été supprimé à la main
Supprimer le dossier via le gestionnaire de fichiers ou rm -rf laisse dans .git/worktrees une entrée « orpheline », et la branche reste considérée comme occupée. Nettoyez ces entrées :
git worktree prune --verbose
Git le fait aussi de lui-même de temps en temps lors du ramasse-miettes, mais rien ne vous oblige à attendre.
Comment cela fonctionne en interne
Dans une copie de travail liée, il n'y a pas de dossier .git mais un fichier .git d'une seule ligne :
gitdir: /home/anna/projects/shop/.git/worktrees/shop-hotfix
Ce dossier interne contient les données propres à la copie de travail : son propre HEAD, son propre index (staging area), ses propres états de merge et de rebase. Tout le reste est partagé : les objets, les branches, les tags, les dépôts distants, la configuration et les hooks.
| Propre à chaque copie de travail | Partagé par toutes |
|---|---|
| HEAD (branche ou commit courant) | Les objets et tout l'historique |
| L'index (git add) | Branches locales et distantes, tags |
| Merge, rebase, cherry-pick en cours | Le stash (refs/stash est commun) |
| Les fichiers du répertoire de travail | .git/config et les hooks |
Le tableau révèle un détail peu évident : git stash list affiche les mêmes entrées dans toutes les copies. C'est même pratique — on peut mettre des modifications de côté dans un dossier et les ressortir dans un autre.
La principale limite : une branche, une seule copie de travail
On ne peut pas ouvrir la même branche dans deux copies de travail. Si vous essayez, Git répond par une erreur de ce genre :
git worktree add ../shop-copy feature/cart
fatal: 'feature/cart' is already used by worktree at '/home/anna/projects/shop'
(dans les anciennes versions de Git, le message est « is already checked out at »). Cette limite empêche qu'un commit dans un dossier modifie en silence la branche sous les pieds de l'autre. Solutions : créer une nouvelle branche à partir du même commit (-b), ouvrir la copie en mode --detach ou, si c'est vraiment nécessaire, utiliser --force en connaissance de cause.
Pour la même raison, vous ne pourrez pas faire git switch main dans le dossier principal tant que main est ouverte dans une copie voisine.
Cas d'usage concrets
Hotfix urgent au milieu d'une fonctionnalité
git worktree add -b hotfix/null-price ../shop-hotfix main
cd ../shop-hotfix
# on corrige, on teste
git commit -am "Corriger le plantage quand le prix est vide"
git push -u origin hotfix/null-price
cd ../shop
git worktree remove ../shop-hotfix
Votre fonctionnalité inachevée est restée telle quelle, vous n'avez rien eu à mettre dans le stash, et l'IDE où le projet est ouvert n'a même pas remarqué le changement.
Revue de pull request avec exécution du code
Une copie dédiée à la revue permet de construire et de lancer la branche d'un collègue, de passer les tests, tout en continuant votre travail dans la fenêtre d'éditeur voisine.
Comparer le comportement de deux versions
Deux copies sur des tags différents peuvent tourner en parallèle sur des ports distincts, pour comparer par exemple le temps de réponse de l'API avant et après une optimisation.
Tests et builds longs
Lancez la suite de tests complète dans une copie et continuez à coder dans l'autre — le build ne cassera pas parce que vous modifiez des fichiers.
Plusieurs agents IA en parallèle
Si plusieurs agents ou processus travaillent sur des tâches, il est pratique de donner à chacun sa propre copie de travail sur sa propre branche : ils ne se gênent pas, et les résultats arrivent directement dans le dépôt commun.
Organiser ses dossiers quand on utilise worktree au quotidien
Si vous avez besoin de copies de travail tous les jours, fixez-vous une structure, sinon les dossiers voisins deviendront vite un fourre-tout. Un schéma populaire : un dossier parent par projet, contenant un dépôt bare et un dossier par branche :
git clone --bare git@example.com:team/shop.git ~/projects/shop/.bare
cd ~/projects/shop
echo "gitdir: ./.bare" > .git
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git fetch origin
git worktree add main
git worktree add -b feature/cart feature-cart main
La ligne remote.origin.fetch est nécessaire car un clone bare ne configure pas par défaut le suivi des branches distantes. Résultat : ~/projects/shop contient les dossiers main et feature-cart, chacun sur sa branche, et aucun n'est « plus principal » que l'autre.
Deuxième bonne habitude : nommer le dossier comme la branche (en remplaçant la barre oblique par un tiret). Ainsi, la sortie de git worktree list et le chemin dans le terminal indiquent toujours où vous êtes. Enfin, supprimez la copie juste après la fusion de la branche : les anciennes copies de travail prennent de la place et gardent des branches « occupées ».
Erreurs fréquentes et pièges
- Les dépendances et le build ne sont pas partagés. Chaque copie est un dossier à part :
node_modules, l'environnement virtuel Python,.envet les artefacts de build sont à recréer. Les fichiers non suivis ne sont pas copiés dans la nouvelle copie. - Copie de travail à l'intérieur du dossier principal.
git worktree add ./hotfixcrée un dossier dans le projet, que la copie principale verra comme des fichiers non suivis. Gardez les copies à côté (../) ou dans un répertoire dédié, ou ajoutez le chemin au.gitignore. - Dossier déplacé à la main. Le lien est rompu. Déplacez avec
git worktree move ../old ../new, et si c'est déjà fait, lancezgit worktree repairdans le nouveau dossier. - Copie sur un disque amovible qui disparaît. Pour que prune ne supprime pas l'entrée d'une copie située sur un disque débranché, verrouillez-la :
git worktree lock --reason "disque externe" ../shop-usb. - Sous-modules. La prise en charge des submodules dans les copies de travail est limitée ; après avoir créé une copie, lancez
git submodule update --initet vérifiez le résultat.
Aide-mémoire git worktree
| Besoin | Commande |
|---|---|
| Ouvrir une branche existante dans un nouveau dossier | git worktree add ../dir branch |
| Créer une branche et sa copie | git worktree add -b new-branch ../dir main |
| Copie sans branche (tag, commit) | git worktree add --detach ../dir v1.0 |
| Lister les copies | git worktree list |
| Supprimer une copie | git worktree remove ../dir |
| Nettoyer les entrées de dossiers supprimés | git worktree prune |
| Déplacer une copie | git worktree move ../dir ../new-dir |
| Réparer les liens après un déplacement | git worktree repair |
| Protéger contre prune | git worktree lock ../dir |
git worktree, stash ou second clone
| Critère | stash | worktree | second clone |
|---|---|---|---|
| Vitesse de bascule | Rapide, mais avec changement de branche | Instantanée — c'est juste un autre dossier | Instantanée |
| Espace disque | Minimal | Uniquement les fichiers de travail | Copie complète de l'historique |
| Synchronisation | Inutile | Inutile, l'historique est partagé | Via push/fetch |
| Travail simultané | Non | Oui | Oui |
Le stash reste le meilleur choix pour une interruption de quelques minutes. Pour tout ce qui dure plus longtemps, ou quand il faut garder deux versions ouvertes, worktree est plus pratique.
En résumé
git worktree est un moyen simple de travailler sur plusieurs branches en même temps : add crée un dossier, list les affiche, remove et prune font le ménage. L'historique est partagé, mais HEAD, l'index et les fichiers sont propres à chaque copie ; une même branche ne peut pas être ouverte dans deux copies. Le fonctionnement des branches et la raison pour laquelle basculer entre elles est si léger sont détaillés en pratique dans le cours Git.
Questions fréquentes
Depuis quelle version de Git git worktree existe-t-il ?
La commande est apparue dans Git 2.5 et a été nettement enrichie depuis, par exemple remove et move ont été ajoutés plus tard. Toute version récente de Git propose l'ensemble des commandes décrites.
Peut-on faire un commit dans une copie de travail et le voir dans une autre ?
Oui, l'historique est partagé. Le commit est immédiatement visible avec git log dans n'importe quelle copie, et on peut le fusionner avec git merge sans push ni fetch.
L'IDE voit-il plusieurs copies de travail ?
Pour l'IDE, chaque copie est un dossier de projet ordinaire qu'on ouvre dans une fenêtre séparée. Beaucoup d'éditeurs affichent aussi la liste des copies de travail dans leur interface Git intégrée.
git worktree remove supprime-t-il la branche ?
Non, seuls le dossier et l'entrée interne sont supprimés. Supprimez la branche séparément avec git branch -d.
git worktree fonctionne-t-il avec un dépôt bare ?
Oui, un schéma populaire consiste à garder un clone bare et à créer à partir de lui une copie de travail par branche ; il n'y a alors plus du tout de dossier « principal » avec des fichiers.
Ce sujet est traité en détail avec de la pratique dans le cours « Git de zéro à développeur confirmé ».
Voir le cours