Git Worktrees, Branches et Réconciliation : guide pratique pour les sessions parallèles
Git Worktrees, Branches et sessions parallèles
Voici une explication pratique de la façon dont les worktrees Git se rapportent aux branches, et de la manière dont plusieurs sessions finissent par réconcilier leur travail.
Les trois concepts distincts
Il y a trois choses différentes en jeu :
1. Le dépôt
Le dépôt est le projet Git lui-même :
- l’historique des commits
- les branches
- les tags
- les métadonnées dans
.git
C’est la source de vérité partagée.
2. La branche
Une branche est un pointeur nommé vers un commit.
Exemples :
mainfeature-uifeature-api
Une branche n’est pas un dossier. C’est une référence dans l’historique Git.
3. Le worktree
Un worktree est un répertoire sur disque contenant une version extraite du dépôt.
C’est le dossier que vous ouvrez réellement dans votre éditeur et que vous modifiez.
Exemples :
/projects/repo/projects/repo-ui/projects/repo-api
Un worktree n’est pas une branche. C’est un répertoire du système de fichiers.
La relation entre eux
La source de confusion, c’est qu’un worktree a généralement une branche checkoutée à l’intérieur.
Les gens parlent donc souvent comme ça :
- “le worktree UI”
- “la branche
feature-ui”
En pratique, ils sont étroitement associés, mais ils restent différents :
- la branche est la ligne d’historique
- le worktree est le dossier qui utilise cette ligne d’historique
Sans worktrees
Normalement, un dépôt a un seul répertoire de travail :
/projects/repo
Si ce répertoire a main checkouté, et que vous voulez travailler sur feature-ui, vous changez de branche dans le même dossier :
git checkout feature-ui
Cela crée un problème pour les sessions parallèles :
- un seul dossier ne peut avoir qu’un seul checkout à la fois
- les changements non commités d’une tâche gênent les autres
- deux terminaux dans le même dossier partagent toujours le même checkout
Avec worktrees
Les worktrees permettent au même dépôt d’avoir plusieurs répertoires de travail en même temps.
Exemple :
git worktree add ../repo-ui -b feature-ui
git worktree add ../repo-api -b feature-api
Vous pouvez alors avoir :
/projects/repo -> dossier worktree
/projects/repo-ui -> dossier worktree
/projects/repo-api -> dossier worktree
Et les checkouts actifs :
/projects/repoamain/projects/repo-uiafeature-ui/projects/repo-apiafeature-api
Tous ces dossiers appartiennent toujours au même dépôt.
Ce que fait réellement git worktree add
Quand vous lancez :
git worktree add ../repo-ui -b feature-ui
Git fait plusieurs choses :
- crée un nouveau répertoire à
../repo-ui - crée une nouvelle branche nommée
feature-ui - checkout cette branche dans le nouveau répertoire
- relie ce répertoire au même historique de dépôt
C’est pour cela que worktrees et branches semblent souvent fusionnés dans les exemples. Une seule commande crée fréquemment les deux.
Mais ils restent séparés :
- vous pouvez parler de la branche seule
- vous pouvez parler du dossier worktree seul
Un modèle mental concret
Pensez-y comme ceci :
- dépôt = la bibliothèque
- branche = une version de l’histoire
- worktree = un bureau sur lequel une version est posée pour être éditée
Vous pouvez avoir plusieurs bureaux ouverts en même temps, chacun avec une version différente, mais la bibliothèque derrière est la même.
Ce à quoi ressemblent réellement plusieurs sessions
Imaginez trois terminaux :
Terminal A
cd /projects/repo
git branch --show-current
# main
Terminal B
cd /projects/repo-ui
git branch --show-current
# feature-ui
Terminal C
cd /projects/repo-api
git branch --show-current
# feature-api
Chaque terminal travaille dans un dossier différent.
C’est le point important.
L’isolation vient des répertoires worktree distincts, pas d’une coordination magique entre les sessions.
Ce que signifie git worktree list
Cette commande :
git worktree list
peut afficher :
/projects/repo abc1234 [main]
/projects/repo-ui def5678 [feature-ui]
/projects/repo-api 9876fed [feature-api]
Chaque ligne signifie :
- ce dossier est un worktree
- il pointe actuellement sur ce commit
- il a actuellement cette branche checkoutée
Encore une fois :
- dossier = worktree
- nom entre crochets = branche
Comment le travail est réconcilié
Les worktrees ne réconcilient pas le code.
Ils empêchent seulement les conflits de checkout local en donnant à chaque tâche son propre dossier.
La vraie réconciliation arrive plus tard via les opérations Git normales :
git mergegit rebasegit cherry-pick
Le point clé est celui-ci :
- les worktrees isolent l’édition active
- les commits préservent le travail de chaque session
- les opérations sur l’historique Git combinent ce travail plus tard
Ce que veut réellement dire “réconcilier”
Quand on dit que le travail de deux sessions doit être “réconcilié”, cela veut généralement dire l’une de ces choses :
- les deux séries de commits doivent finir sur la même branche
- une branche doit être mise à jour pour inclure les changements de l’autre
- les conflits entre modifications qui se recouvrent doivent être résolus
Cela se passe au niveau des branches et des commits, pas au niveau du worktree.
Le worktree n’est que l’endroit où vivent les fichiers pendant l’édition.
La chronologie de la réconciliation
Une séquence réaliste ressemble à ceci :
- créer des worktrees séparés
- chaque worktree checkout une branche différente
- chaque session édite dans son propre dossier
- chaque session commit ses changements sur sa propre branche
- plus tard, une branche est fusionnée, rebasée ou cherry-pickée dans une autre
- si Git détecte des changements qui se recouvrent, un humain résout le conflit
Voilà le cycle complet.
Le worktree compte surtout aux étapes 1 à 3. Les opérations Git sur les branches comptent surtout aux étapes 4 à 6.
Exemple : réconciliation sans conflit
Supposons que vous partez de main au commit A.
Historique :
A
Vous créez deux worktrees :
/projects/repo-uisurfeature-ui/projects/repo-apisurfeature-api
La session 1 fait un changement UI et crée le commit B.
La session 2 fait un changement API et crée le commit C.
L’historique ressemble alors à ceci :
B feature-ui
/
A---+
\
C feature-api
Plus tard, depuis un worktree avec main, vous lancez :
git merge feature-ui
git merge feature-api
Si les changements ne se recouvrent pas de manière conflictuelle, Git combine proprement les deux :
B feature-ui
/ \
A---M---N main
\ /
C feature-api
Vous pouvez le lire ainsi :
- le travail UI a été fait dans un worktree
- le travail API a été fait dans un autre
- la réconciliation a eu lieu quand les branches ont été fusionnées dans
main
Les worktrees n’ont pas été fusionnés. Les branches, si.
Exemple : réconciliation avec conflit
Imaginez maintenant que les deux sessions modifient la même zone logique du même fichier.
La session 1 dans /projects/repo-ui modifie :
src/app/page.tsx
La session 2 dans /projects/repo-api modifie aussi :
src/app/page.tsx
Comme ces dossiers worktree sont séparés, les deux sessions peuvent continuer à travailler sans interférence immédiate.
C’est utile, mais cela ne fait que repousser le conflit au moment de l’intégration.
L’historique peut ressembler à ceci :
B feature-ui
/
A---+
\
C feature-api
Puis quelqu’un essaie :
git checkout main
git merge feature-ui
git merge feature-api
Git peut alors s’arrêter et signaler un conflit de merge.
À ce moment-là, Git vous dit :
- les deux branches ont modifié des lignes liées
- Git ne peut pas choisir seul la version finale en toute sécurité
- un humain doit éditer le fichier et décider du contenu final
Cette correction manuelle est la vraie réconciliation.
Où le conflit est résolu
Le conflit est résolu dans le worktree qui exécute le merge ou le rebase.
Par exemple, si /projects/repo a main checkouté et que vous lancez :
cd /projects/repo
git merge feature-api
alors /projects/repo devient l’endroit où apparaissent les marqueurs de conflit.
Les autres worktrees ne montrent pas automatiquement cet état temporaire de merge.
À quoi ressemble la résolution de conflit
Supposons que Git insère des marqueurs :
<<<<<<< HEAD
version actuelle depuis main
=======
version entrante depuis feature-api
>>>>>>> feature-api
Un humain édite ensuite le fichier pour produire la version finale souhaitée, puis lance :
git add <file>
git commit
À ce moment-là, la réconciliation est terminée pour ce merge.
Réconciliation avec rebase
Le rebase réconcilie le travail différemment.
Au lieu de combiner deux têtes de branches avec un commit de merge, il rejoue les commits d’une branche au-dessus d’une autre base.
Exemple :
cd /projects/repo-api
git rebase main
Cela signifie :
- prendre les commits de
feature-api - faire comme s’ils avaient été créés à partir du
mainactuel - les rejouer un par un
Si un commit rejoué entre en conflit, Git s’arrête et demande une résolution dans ce worktree.
Flux typique :
git rebase main
# résoudre les fichiers
git add <file>
git rebase --continue
Donc avec le rebase :
- la réconciliation a toujours lieu au moment de l’intégration
- les conflits demandent toujours des décisions humaines
- le worktree qui exécute le rebase est l’endroit où cela se passe
Réconciliation avec cherry-pick
Le cherry-pick est la forme la plus étroite de réconciliation.
Au lieu de combiner des branches entières, il applique des commits choisis sur une autre branche.
Exemple :
cd /projects/repo
git cherry-pick <commit-from-feature-ui>
C’est utile quand :
- un seul commit d’une autre session est nécessaire
- vous ne voulez pas la branche entière
- vous voulez une intégration très sélective
Le cherry-pick peut aussi produire des conflits, et ils sont résolus dans le worktree qui exécute l’opération.
Pourquoi les worktrees séparés restent utiles même si les conflits arrivent plus tard
Une incompréhension fréquente est :
- “Si les conflits peuvent quand même arriver plus tard, à quoi sert le worktree ?”
Il résout le problème de l’état de travail actif.
Sans worktrees :
- vous changez constamment de branche dans un seul dossier
- le travail non commité bloque les changements de branche
- une session peut salir l’environnement d’une autre
- tester une branche peut perturber les fichiers d’une autre
Avec worktrees :
- chaque branche a son propre dossier
- chaque session garde son propre état non commité
- chaque session peut fonctionner indépendamment
- l’intégration est repoussée jusqu’à ce que les commits soient prêts
Les worktrees réduisent donc la friction opérationnelle, même s’ils n’éliminent pas les conflits de merge.
Que deviennent les autres worktrees après la réconciliation
Supposons que /projects/repo fusionne feature-ui dans main.
Le worktree /projects/repo-ui ne disparaît pas magiquement.
Il existe toujours comme dossier séparé, toujours associé à sa branche checkoutée.
Selon ce que vous voulez, vous pouvez :
- garder ce worktree pour plus de travail
- le mettre à jour avec
git pullougit rebase main - le supprimer si la tâche est terminée
La réconciliation ne nettoie donc pas automatiquement les worktrees. Elle ne fait que changer l’historique des branches.
Règle importante : une branche ne peut pas être checkoutée dans deux worktrees en même temps
Git empêche qu’une même branche soit checkoutée simultanément dans plusieurs worktrees.
Cette règle existe parce que Git veut qu’une branche checkoutée ait un seul état de travail actif.
Vous pouvez toujours :
- créer plusieurs worktrees pour le même dépôt
- utiliser une branche différente dans chacun
- fusionner ou rebaser ces branches plus tard
Mais vous ne pouvez pas normalement avoir la même branche checkoutée dans deux worktrees actifs à la fois.
Dépôt partagé, états de travail séparés
Tous les worktrees partagent les mêmes données de dépôt sous-jacentes :
- base d’objets
- refs
- historique de commits
Mais chaque worktree a son propre :
- ensemble de fichiers checkoutés
HEAD- index / état de staging
C’est ce qui rend la réconciliation possible :
- tous les commits appartiennent au même dépôt
- Git peut faire des merges, rebases ou cherry-picks entre eux plus tard
Pack opérateur
Recevez le pack Git Worktrees Reconciliation
Demandez la version opérateur de ce guide : checklist de setup, aide au choix merge/rebase, et workflow simple pour les équipes qui travaillent en parallèle.
- Checklist de setup worktree pour travail parallèle
- Guide de décision merge vs rebase vs cherry-pick
- Workflow de résolution de conflits à l'intégration
- Checklist de nettoyage pour branches et worktrees terminés