Tutoriel

git worktree : travailler sur plusieurs branches en même temps

Mis à jour: · Skillaria.Top

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 travailPartagé 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 coursLe 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, .env et 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 ./hotfix cré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, lancez git worktree repair dans 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 --init et vérifiez le résultat.

Aide-mémoire git worktree

BesoinCommande
Ouvrir une branche existante dans un nouveau dossiergit worktree add ../dir branch
Créer une branche et sa copiegit worktree add -b new-branch ../dir main
Copie sans branche (tag, commit)git worktree add --detach ../dir v1.0
Lister les copiesgit worktree list
Supprimer une copiegit worktree remove ../dir
Nettoyer les entrées de dossiers supprimésgit worktree prune
Déplacer une copiegit worktree move ../dir ../new-dir
Réparer les liens après un déplacementgit worktree repair
Protéger contre prunegit worktree lock ../dir

git worktree, stash ou second clone

Critèrestashworktreesecond clone
Vitesse de basculeRapide, mais avec changement de brancheInstantanée — c'est juste un autre dossierInstantanée
Espace disqueMinimalUniquement les fichiers de travailCopie complète de l'historique
SynchronisationInutileInutile, l'historique est partagéVia push/fetch
Travail simultanéNonOuiOui

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.

Apprenez ce sujet en vidéo

Ce sujet est traité en détail avec de la pratique dans le cours « Git de zéro à développeur confirmé ».

Voir le cours