git worktree : travailler sur deux branches en même temps
git worktree permet de checkout plusieurs branches comme de vrais répertoires, en même temps — sans stash, sans perte de contexte. Gardez votre stack Docker en route pendant que vous traitez un hotfix en parallèle.
Traduction automatique
Journal des modifications

Vous êtes plongé dans une branche de feature — du code à moitié écrit, des containers Docker qui tournent, des fichiers ouverts partout. Et là : « hotfix urgent à faire sur main ». Avec le workflow habituel, vous stashez tout, vous changez de branch, vous corrigez, vous committez, vous poussez, puis vous dépilez le stash en espérant que rien n'explose. Avec git worktree, vous checkoutez une deuxième branch dans un dossier séparé. Les deux branches existent en même temps, comme de vrais répertoires, avec leurs propres terminaux et leurs propres stacks Docker.
Il est 15h, un jeudi. Vous travaillez sur une nouvelle fonctionnalité depuis deux jours. Les containers Docker tournent, votre éditeur a huit fichiers ouverts, et vous êtes au milieu d'un refactoring qui ne compile pas encore.
Votre téléphone vibre. La production est cassée. Un correctif doit partir sur main dans les trente minutes.
Vous faites quoi ?
Le workflow du stash et sa douleur
L'approche classique :
Ça marche. La plupart du temps. Mais :
- Vos containers Docker pointent maintenant vers le mauvais code — il faut les redémarrer
- Votre éditeur a perdu le contexte — tous ces fichiers ouverts ont disparu ou pointent vers les versions de main
- Si
git stash poppart en conflit, vous voilà avec un joyeux bazar à trois branches à résoudre, encore sous le stress du hotfix - Vous ne pouvez avoir qu'une seule branch active à la fois
Le problème de fond : un git stash est un état fragile. Ce n'est pas une branch. Il n'a pas d'historique. Il peut entrer en conflit. Et il disparaît dès que vous le dépilez.
Puisqu'on parle de jongler avec les branches : Git - Quelques astuces pour votre fichier .gitconfig montre comment trier git branch par date du dernier commit, et Afficher les 3 dernières branches modifiées quand vous entrez dans un repo git les affiche automatiquement quand vous entrez dans un repository.
Ce que fait git worktree
Un git worktree est un deuxième (ou troisième, ou quatrième) répertoire de travail lié au même repository git.
Au lieu d'un dossier avec une seule branch checkoutée, vous obtenez :
~/projects/my-blog/ ← main branch (original)
~/projects/my-blog-hotfix/ ← hotfix/invoice-fix branch (worktree)
~/projects/my-blog-feature-auth/ ← feature/auth branch (worktree)
Chaque dossier est un vrai répertoire avec ses propres fichiers, son propre terminal, ses propres processus en cours. Ils partagent la même base .git (commits, objets, historique), mais chacun a une branch checkoutée indépendamment.
Vous ne quittez jamais votre branch de feature. Le hotfix vit juste à côté.
Les commandes de base
Ajouter un worktree
Crée un nouveau répertoire à l'emplacement <path> avec [branch] checkoutée :
Si la branch n'existe pas encore, créez-la en même temps :
Cela crée hotfix/invoice-fix à partir de main, checkoutée dans ../my-blog-hotfix.
Lister tous les worktrees
Sortie :
/home/christophe/projects/my-blog a4b2c1d [main]
/home/christophe/projects/my-blog-hotfix e8f3d2a [hotfix/invoice-fix]
Supprimer un worktree
Cela supprime le dossier et désenregistre le worktree. La branch elle-même (hotfix/invoice-fix) existe toujours — vous pouvez la supprimer séparément avec git branch -d.
Le voir en action avec Docker
git n'a pas besoin d'être installé — il est déjà sur votre machine. Ce qui vaut la peine d'être testé sans risque, c'est le scénario lui-même : un repo jetable, déjà en plein refactoring sur une branch de feature avec des modifications non committées, et un bug de calcul de TVA qui attend sur main. Exactement la situation du jeudi après-midi ci-dessous, sans le stress.
Pourquoi Docker d'abord ?
Le Dockerfile ci-dessous construit un repo déjà positionné sur feature/user-notifications avec deux
fichiers non stagés — le même point de départ que l'étape 1 ci-dessous — plus le navigateur fzf gwt
décrit plus bas, branché via un vrai autoload ZSH. Rien n'est touché sur vos propres repos.
Construisez-le et lancez-le :
$ docker build -t worktree-demo . [+] Building 24.1s (8/8) FINISHED ✔ exporting to image
$ docker run --rm -it worktree-demo 🐳 root ~/projects/my-blog # git status On branch feature/user-notifications Changes not staged for commit: modified: src/api/notifications.ts modified: src/components/Notifications.tsx
C'est l'étape 1 ci-dessous, déjà en place. Maintenant, déroulez le reste du scénario pour de vrai, exactement comme
écrit — git worktree add -b hotfix/invoice-fix ../my-blog-hotfix main, corrigez
src/billing/invoice.ts dans le nouveau dossier, committez, git worktree remove, et vérifiez avec git status que votre branch de feature n'a pas bougé. gwt est branché aussi, si vous voulez essayer le
navigateur fzf de la section « Une fonction ZSH » plus bas.
Lancez les commandes de l'étape 4 une par une
Ne collez pas tout le bloc de l'étape 4 d'un coup : vim est un éditeur plein écran, donc tout ce
que vous collez après vim src/billing/invoice.ts est tapé dans vim au lieu d'être exécuté comme
commandes shell. Lancez cette ligne seule, faites la modification (voir l'astuce à l'étape 4), sauvez et quittez, puis collez
le reste. git push fonctionne aussi dans ce container — l'image branche un repo bare local comme origin,
il y a donc une vraie cible où pousser, sans compte GitHub.
Le scénario du hotfix, étape par étape
Retour au jeudi après-midi. Voici la même situation traitée avec des worktrees.
1. Vous êtes sur votre branch de feature, en plein travail
Vous n'y touchez pas. Vous ne stashez rien.
2. Créez un worktree de hotfix à côté de votre projet
git worktree add -b hotfix/invoice-fix ../my-blog-hotfix main
Preparing worktree (new branch 'hotfix/invoice-fix') HEAD is now at a4b2c1d chore: update dependencies
3. Ouvrez un nouveau terminal, allez dans le dossier du hotfix
Ce répertoire contient les fichiers de main. Le répertoire de votre branch de feature est intact, toujours en cours d'exécution, toujours ouvert dans votre éditeur.
4. Corrigez le bug et poussez
Le vrai correctif TVA
calculateVat() retourne amount * rate — juste la part de TVA, pas le total de la facture. Dans vim :
appuyez sur i, changez la ligne en return amount * (1 + rate);, puis Esc suivi de :wq pour sauver
et quitter. Seulement ensuite, lancez les lignes git add/commit/push.
5. Nettoyez le worktree
Pourquoi -D et pas -d
Vous êtes toujours sur feature/user-notifications ici, qui n'a jamais reçu le commit du hotfix — seul
origin/hotfix/invoice-fix l'a reçu, via la PR mergée. git branch -d refuse de supprimer une branch qu'il
ne voit pas comme mergée dans votre branch courante, et sort l'erreur « not fully merged ». Comme vous savez
qu'elle est bien mergée sur le remote, -D (force) est le bon choix, pas un contournement d'erreur.
6. Retour à votre branch de feature — rien n'a changé
Pas de stash, pas de conflits, pas de changement de contexte.
Une contrainte : une branch ne peut être que dans un seul worktree à la fois
Git l'impose. Si feature/user-notifications est checkoutée dans votre répertoire principal, vous ne pouvez pas ajouter un second worktree avec la même branch. Si vous essayez :
C'est volontaire — deux répertoires écrivant simultanément sur la même branch corrompraient l'arbre de travail. Chaque worktree a sa propre branch.
Docker + worktrees : chaque branch a sa propre stack
C'est là que les worktrees deviennent vraiment puissants dans un workflow Docker.
Chaque worktree est un répertoire séparé. Chaque répertoire peut avoir son propre fichier .env et sa propre stack Docker Compose en route, tant que vous évitez les conflits de ports.
Une convention pratique : un port différent par worktree. Gardez les ports dans .env, qui est dans le .gitignore :
Vous pouvez maintenant lancer les deux stacks en même temps :
// Terminal 1 — branch de feature cd ~/projects/my-blog docker compose up
// Terminal 2 — branch de hotfix cd ~/projects/my-blog-hotfix docker compose up
Les deux serveurs tournent en même temps. Vous pouvez tester le hotfix sur http://localhost:3001 sans arrêter le développement de votre feature sur http://localhost:3000.
Projets Compose nommés
Docker Compose utilise le nom du dossier comme nom de projet par défaut. Comme vos worktrees sont dans des dossiers différents, Compose crée automatiquement des réseaux et des ensembles de containers séparés — aucune configuration supplémentaire n'est nécessaire.
Une fonction ZSH pour naviguer entre les worktrees
Si vous suivez le pattern du workflow ZSH modulaire, vous pouvez ajouter un navigateur interactif de worktrees basé sur fzf :
Utilisation :
gwt # fzf picker — select any active worktree and cd into it
gwt feature/dark-mode # create + cd into a new worktree for that branch
Astuces pratiques
Nommez les worktrees de manière cohérente
Un schéma de nommage prévisible évite la confusion :
# Pattern: <repo-name>-<branch-slug>
git worktree add ../my-blog-hotfix-invoice hotfix/invoice-fix
git worktree add ../my-blog-feat-auth feature/auth
Les worktrees fonctionnent avec VS Code
Ouvrez un dossier de worktree dans une nouvelle fenêtre VS Code :
Chaque fenêtre fonctionne indépendamment, avec ses propres fichiers ouverts et ses propres sessions de terminal.
Élaguez les worktrees obsolètes
Si vous supprimez manuellement un dossier de worktree (au lieu d'utiliser git worktree remove), git peut encore croire qu'il existe. Nettoyez les références obsolètes :
Conclusion
git stash | git worktree | |
|---|---|---|
| Changement de branch | Oui, obligatoire | Non — les branches coexistent |
| Containers Docker | À redémarrer | Tournent indépendamment |
| Contexte de l'éditeur | Perdu | Préservé |
| Développement parallèle | Non | Oui |
| Risque de conflit | Au stash pop | Aucun |
| Nettoyage | Automatique au pop | Manuel : worktree remove |
Le stash reste utile pour les petits trucs rapides — économiser une demi-ligne de frappe avant un git pull. Dès qu'il s'agit de services en cours d'exécution, d'une session d'éditeur ou de plus de cinq minutes de travail, un worktree est plus propre.
La première fois que vous traiterez un hotfix sans quitter votre branch de feature, vous vous demanderez comment vous avez pu travailler autrement.
Chargement des commentaires…






