Vous êtes en plein travail sur une branche de feature, trois fichiers modifiés, rien de commité, quand un collègue vous signale un crash null-pointer en production. Le réflexe habituel : git stash, checkout de main, correction, push, puis git stash pop, en espérant que rien dans votre feature inachevée ne dépendait des fichiers que vous venez d’abandonner. git worktree évite cette gymnastique. Il fait le checkout de la branche de hotfix dans un second dossier, à côté de votre branche de feature, les deux s’appuyant sur le même dépôt.
Ce que fait réellement git worktree
Un checkout classique vous donne les fichiers d’une seule branche à la fois. Changer de branche réécrit ces fichiers sur place. git worktree vous donne plusieurs checkouts du même dépôt, chacun dans son propre dossier avec sa propre branche, et vous pouvez les modifier indépendamment.
Ce ne sont pas des clones séparés. Il existe un seul dossier .git, qui contient la base d’objets, les refs et la config, et chaque worktree y lit et y écrit. Dans un worktree secondaire, .git n’est même pas un dossier : c’est un fichier d’une ligne qui pointe vers le dossier partagé. C’est pour ça que créer un worktree est quasi instantané et n’ajoute aucun historique sur le disque.
Une restriction compte vraiment. Deux worktrees ne peuvent pas avoir la même branche checkoutée en même temps, car une branche pointe vers un seul commit courant, et deux checkouts qui commitent sur elle se disputeraient ce pointeur. Tout le reste est propre à chaque worktree, des fichiers non suivis et de l’index jusqu’au commit sur lequel se trouve HEAD.
Comment créer un worktree pour un hotfix
Depuis votre checkout existant de myapp, sur feature/checkout-flow avec des modifications non commitées :
| |
Cela crée ../myapp-hotfix à côté de votre dossier courant, avec une nouvelle branche hotfix/null-pointer créée depuis main et checkoutée à l’intérieur. Votre dossier d’origine reste sur feature/checkout-flow, modifié et intact.
| |
De retour dans le dossier d’origine, votre travail sur la feature est exactement comme vous l’aviez laissé. Rien à pop, et aucun stash à oublier.
Sans -b, git worktree add <path> nomme la branche d’après le dernier élément du chemin. Si aucune branche de ce nom n’existe, Git la crée depuis HEAD ; si elle existe et n’est pas déjà checkoutée dans un autre worktree, Git la checkoute. Utilisez -d (--detach) quand vous voulez explorer un commit sans aucune branche.
Comment lister, supprimer et nettoyer les worktrees
| |
| |
Une fois le hotfix mergé, supprimez le worktree via Git plutôt que de supprimer le dossier :
| |
remove refuse si le worktree a des fichiers suivis modifiés ou des fichiers non suivis. Passez -f pour forcer. Si le dossier disparaît d’une autre façon (un rm -rf malheureux, un job CI planté), Git garde son entrée administrative et git worktree list continue de l’afficher. Nettoyez l’entrée obsolète avec :
| |
Lancez-le d’abord avec -n pour voir ce qu’il supprimerait.
Certains worktrees doivent rester en place pendant des semaines : une branche de release de longue durée, ou un checkout sur un partage réseau qui n’est pas toujours monté. Verrouillez-les pour que prune laisse leur entrée tranquille et que move et remove refusent de les toucher :
| |
Déverrouillez d’abord si vous voulez en déplacer un avec git worktree move <path> <new-path>. Déplacer ou supprimer un worktree verrouillé sans le déverrouiller demande --force deux fois, pensé comme un contournement délibéré.
Quand utiliser git worktree en dehors des hotfixes
Chaque fois que vous avez besoin de deux checkouts actifs au lieu d’un seul :
- Relire une PR sans perdre votre place.
git worktree add ../myapp-review origin/some-pr-branchvous donne une copie buildable de la branche de quelqu’un d’autre, pendant que votre propre travail reste checkouté là où il était. - Lancer un
git bisectsans bloquer le reste. Un bisect déplaceHEADà chaque étape, donc le checkout dans lequel il tourne devient inutilisable pour autre chose jusqu’à ce que vous terminiez ou fassiez un reset. Lancez-le dans un worktree dédié (voir Git Bisect : trouver le commit qui a introduit un bug) et continuez à travailler dans le worktree principal. - Faire tourner deux tâches en parallèle sur le dépôt. Une suite de tests longue sur une branche pendant que vous modifiez une autre, ou deux agents de codage IA sur des tâches séparées : chacun a besoin de son propre dossier de travail. Un worktree en fournit un sans un second
git cloneni un second dossier.gitde plusieurs gigaoctets.
Quand ne pas utiliser git worktree
Chaque worktree duplique le working tree, pas la base d’objets. Dix worktrees d’un dépôt avec un checkout de 50 Mo coûtent environ 500 Mo de fichiers sur disque, même avec un seul .git. Pour un changement de contexte de cinq minutes, git stash est moins coûteux et ne laisse rien à nettoyer.
Les submodules sont le point sensible. git worktree move ne déplace pas un worktree qui contient des submodules, et un nouveau worktree démarre avec ses dossiers de submodules vides jusqu’à ce que vous lanciez git submodule update --init à l’intérieur. La documentation Git elle-même qualifie d’incomplet le support des submodules dans plusieurs checkouts, donc pour un superprojet avec de nombreux submodules, un clone séparé reste le choix le plus sûr.
Certains outils supposent aussi un seul dossier de travail par dépôt. Un IDE ou un file-watcher qui indexe son cache sur le chemin absolu du dépôt peut se perdre devant le même historique présent à deux endroits. Ouvrir chaque worktree comme son propre projet, et non comme un sous-dossier du premier, résout généralement le problème.
Si vous avez juste besoin de ranger ou d’annuler quelque chose dans le checkout que vous avez déjà, git stash ou git reset, revert ou restore est l’outil le plus léger. La prochaine fois qu’un hotfix tombe en plein milieu d’une feature, essayez git worktree add avant git stash, et voyez lequel des deux vous préférez nettoyer après.