Cos’è un git worktree e come si usa con gli agenti?
Un git worktree dà a ogni agente i suoi file, ma non separa tutto. Abbiamo esaminato cinque strumenti e il nostro repository.
In sintesi. Un git worktree apre una seconda directory di lavoro dallo stesso repository: i file sono separati, la cronologia dei commit e i branch sono in comune. Tutti e cinque gli strumenti di programmazione che abbiamo esaminato sanno aprire un worktree per separare gli agenti che lavorano in parallelo. Il 18 ottobre 2026 abbiamo letto nella documentazione di ciascuno strumento come Claude Code, Codex, Cursor, Gemini CLI e GitHub Copilot aprono e chiudono i worktree. Esempi e numeri vengono dal repository in cui lavoriamo ogni giorno con agenti in parallelo. Il 28 ottobre 2026 abbiamo aggiunto Antigravity CLI di Google.
- Un worktree separa i file e condivide il repository. Ogni worktree ha i suoi file, il suo HEAD e il suo index. Branch, stash e impostazioni del repository (compreso il percorso degli hook) sono in comune a tutti.
- Tutti e cinque gli strumenti lo supportano, con impostazioni predefinite diverse. Dove si apre il worktree, da quale commit parte, se porta con sé file come
.enve quando viene eliminato cambiano da strumento a strumento. - Il vero problema è che si accumulano. Il 18 ottobre 2026 il nostro repository aveva 66 worktree. Per almeno 34 di questi, il branch era già stato unito.
- Un controllo all’apertura della sessione non basta. Di due sessioni aperte nella stessa directory, una può cambiare il branch su cui lavora l’altra. Per questo usiamo un hook che ricontrolla branch e commit prima di ogni modifica.
Che cosa si rompe quando due agenti lavorano nella stessa directory?
Ormai facciamo girare quasi sempre gli agenti di programmazione in parallelo: una sessione scrive una nuova funzionalità mentre un’altra corregge un bug, e i subagenti modificano nello stesso momento file diversi. Se lavorano tutti nella stessa directory, condividono gli stessi file, lo stesso branch e lo stesso index di git. Nel repository in cui sviluppiamo diffox l’abbiamo pagata più di una volta. Ogni volta ne è nata una regola:
- Un semplice commit si è portato via anche il lavoro di un altro agente.
git commitfa il commit di tutto ciò che c’è nell’index, compresi i file preparati da un altro agente nella stessa directory. La nostra regola: gli agenti che lavorano in parallelo fanno il commit solo dei propri file (git commit --only <percorsi>). - Un
git checkout -bha cambiato il branch di un’altra sessione. La shell dell’agente torna alla directory di partenza a ogni comando, e una volta un comando git senza percorso ha cambiato il branch di una sessione parallela. La nostra regola: ogni comando git indica il percorso in modo esplicito (git -C <percorso assoluto>). - Una sessione ha pianificato modifiche in una directory che in 40 minuti ha cambiato branch 3 volte. Per questo esiste l’hook di apertura della sessione di cui abbiamo parlato nell’articolo sugli hook.
- Anche il nostro script di pulizia ha fatto lo stesso errore. Lo script che ripulisce i branch già uniti spostava su
devogni directory pulita che trovava. Ma una directory pulita può essere quella di un’altra sessione che non ha ancora cominciato a scrivere; lo script ha cambiato il branch di quella sessione. Ora sposta solo una directory che sta sudev, sumaino su un branch la cui pull request è stata unita.
Il punto in comune è una sola directory. Il worktree esiste proprio per questo: dà a ogni agente la sua directory, il suo branch e il suo index. Ma, come vedrai più sotto, non separa tutto. L’impostazione isolation: worktree di Claude Code l’abbiamo spiegata nell’articolo sui subagenti. Questo articolo guarda il repository che gli agenti condividono.
Che cos’è un git worktree?
Secondo la documentazione di git, un repository può avere più directory di lavoro (working tree), così puoi avere più di un branch aperto nello stesso momento. La directory che ottieni con git clone è il worktree principale. Quelli che apri con git worktree add sono worktree collegati (linked worktree).
Un worktree collegato condivide tutto con il repository, tranne alcuni file suoi come HEAD e l’index. La cronologia dei commit è salvata una volta sola; ogni worktree contiene solo la sua copia dei file. Quasi tutto il lavoro lo fanno questi comandi:
git worktree add -b ricerca ../progetto-ricerca # nuova directory, nuovo branch
git worktree list # tutti i worktree
git worktree remove ../progetto-ricerca # lo rimuove se è pulito
git worktree prune # pulisce le voci dei worktree la cui directory è stata cancellata a manoAlcuni errori git li evita da solo. Un branch può essere aperto in un solo worktree alla volta: per impostazione predefinita, add rifiuta un branch già aperto in un altro worktree. E remove rimuove solo i worktree puliti; per cancellarne uno con modifiche non committate o file non tracciati serve --force.
La differenza tra worktree e branch. Un branch è un nome che punta a un commit. Un worktree è una directory in cui sono aperti i file di un branch. Se cambi branch in un’unica directory, i file cambiano per tutti quelli che ci lavorano. Con i worktree, ogni agente resta nella sua directory, sul suo branch. Una nota: la documentazione di git stessa considera ancora sperimentali i checkout multipli e scrive che il supporto ai submodule è incompleto.
Come si apre un worktree negli strumenti di programmazione?
Tutti e cinque gli strumenti sanno aprire un worktree da soli; in Gemini CLI la funzione è sperimentale e si attiva dalle impostazioni. Gli strumenti si differenziano su dove si apre il worktree, da quale commit parte, se porta con sé i file che git ignora (come .env) e quando viene eliminato.
| Strumento | Come si apre | Dove | Da quale commit parte | File come .env | Quando viene eliminato |
|---|---|---|---|---|---|
| Claude Code | claude --worktree <nome>; in un subagente isolation: worktree | .claude/worktrees/<nome>/ | Il branch predefinito del remoto; con worktree.baseRef: "head" l’HEAD locale | Viene copiato ciò che è scritto in .worktreeinclude | All’uscita dalla sessione: da solo se è pulito e la sessione non ha nome; se c’è lavoro, ti chiede. I worktree dei subagenti e in background dopo cleanupPeriodDays (predefinito 30 giorni), se non c’è più lavoro |
| Codex | Si sceglie Worktree in una nuova chat | $CODEX_HOME/worktrees | L’HEAD del branch che scegli, con le sue modifiche non committate; nessun branch, detached HEAD | Viene copiato ciò che è scritto in .worktreeinclude | Per impostazione predefinita tiene gli ultimi 15 worktree; prima di eliminarne uno salva uno snapshot |
| Cursor | Si sceglie worktree nell’Agents Window; nell’IDE /worktree | La documentazione non lo dice | La documentazione non lo dice | Non arrivano da soli; con i comandi di setup in .cursor/worktrees.json | A intervalli; per impostazione predefinita tiene al massimo 25 worktree per macchina |
| Gemini CLI | Si attiva dalle impostazioni (sperimentale), poi gemini --worktree <nome> | .gemini/worktrees/<nome> | La documentazione non lo dice | La documentazione non lo dice | Mai da solo; la pulizia tocca a te |
| GitHub Copilot CLI | copilot --worktree oppure /worktree nella sessione | <repo>.worktrees/ | L’HEAD del checkout in cui sei; con worktreeBaseRef: "defaultBranch" il branch predefinito del remoto | La documentazione non lo dice | La documentazione non lo dice |
Fonte: la documentazione sui worktree di ogni strumento, 18 ottobre 2026. «La documentazione non lo dice»: nella pagina che abbiamo letto quel giorno non abbiamo trovato una frase su questo punto. La riga di Codex riguarda Codex nell’app desktop di ChatGPT, quella descritta dalla pagina. La pulizia di Cursor è descritta per la versione 3.5 e successive. Anche l’app GitHub Copilot apre un worktree e un branch separati per ogni sessione.
La differenza più importante è il punto di partenza. Per impostazione predefinita Claude Code parte dal branch predefinito del repository remoto; i commit di cui non hai ancora fatto il push non ci sono nel nuovo worktree. Copilot CLI invece parte dall’HEAD del checkout in cui ti trovi. Codex porta nel nuovo worktree perfino le modifiche non committate del branch che scegli. Scegli questa impostazione con consapevolezza, in base a ciò che l’agente deve vedere.
I file che git ignora non arrivano nel nuovo worktree. Per questo Claude Code e Codex leggono un file con lo stesso nome: .worktreeinclude, nella radice del repository. Si scrive con la sintassi di .gitignore e copia solo i file che git ignora. In Cursor lo stesso lavoro lo fanno i comandi di setup in .cursor/worktrees.json; l’esempio della documentazione copia .env con cp.
Sulle dipendenze due strumenti danno consigli diversi. Cursor sconsiglia di portare le dipendenze nel worktree con un link simbolico, perché può creare problemi nel worktree principale. Claude Code invece, con l’impostazione worktree.symlinkDirectories, può portare in ogni worktree con un link simbolico directory grandi come node_modules.
Ci sono anche comandi pronti per il lavoro in parallelo. La skill /batch di Claude Code divide una modifica grande tra 5 e 30 subagenti, ciascuno nel proprio worktree. Il comando /best-of-n di Cursor esegue lo stesso compito su più modelli e dà a ogni esecuzione un worktree separato. I team di agenti (agent teams) di Claude Code invece non separano i membri in worktree; la documentazione dice di dividere il lavoro in modo che ogni membro sia responsabile di file diversi.
Il 18 giugno 2026 Google ha smesso di servire Gemini CLI agli utenti gratuiti e agli abbonati Google AI Pro e Ultra, indirizzandoli ad Antigravity CLI; con una chiave API a pagamento o una licenza aziendale puoi continuare a usare Gemini CLI. Il 28 ottobre 2026 abbiamo letto la documentazione di Antigravity. Secondo la sua pagina sui subagenti, l’agente principale può dare a un subagente che avvia un proprio worktree Git; quando il subagente viene terminato, quel worktree viene eliminato automaticamente. La documentazione non dice da quale commit parte il worktree né se porta con sé file come .env. L’app desktop può aprire una nuova conversazione direttamente in un proprio worktree; nella CLI non abbiamo trovato un flag che lo faccia.
Che cosa separa un worktree e che cosa no?
Viene facile pensare al worktree come a una sandbox completa. Ma git dà a ogni worktree solo poche cose sue. Il resto è in comune, e di una parte git non si occupa affatto:

Le impostazioni e il percorso degli hook sono in comune. Secondo git, il file di configurazione del repository è in comune a tutti i worktree per impostazione predefinita. Nel nostro repository anche la posizione degli hook di git è scritta in questo file (core.hooksPath), come un unico percorso assoluto. Per questo l’hook pre-push, che gira prima di un push, viene eseguito dalla copia nel worktree principale, non dalla copia sul branch di cui fai il push. Il 24 agosto 2026 abbiamo aggiunto una nuova regola a questo hook su un branch di un worktree, e i suoi 11 test sono passati. Ma un push dallo stesso worktree è passato lo stesso, perché il worktree principale aveva ancora la vecchia versione. Lo stesso vale per altre impostazioni come l’identità (user.email); per impostazioni specifiche di un worktree devi attivare extensions.worktreeConfig di git.
Anche i permessi degli strumenti possono essere in comune. In Claude Code, un’approvazione «Yes, and don’t ask again» data in un worktree viene scritta nel file .claude/settings.local.json del worktree principale e vale in tutti i worktree. Anche in Copilot CLI i worktree collegati condividono i permessi del repository principale.
Branch e stash sono in comune. Secondo git, tutti i riferimenti che iniziano con refs/ sono in comune tra i worktree, e l’ultimo stash è salvato in refs/stash. Un git stash pop senza nome prende l’ultimo stash. Mettendo una accanto all’altra queste frasi della documentazione di git, il risultato è questo: un git stash pop in un worktree prende l’ultimo stash anche se l’ha lasciato un agente in un altro worktree. In un repository dove gli agenti lavorano in parallelo, un commit temporaneo è più sicuro di uno stash.
Ciò che sta fuori da git non viene separato affatto. Un database, una porta, una cache o una directory di dati ignorata non sanno niente dei worktree. Nel nostro repository colleghiamo a ogni worktree, con un link simbolico, una grande directory di misurazioni (.runs), perché lì ci sono i risultati di misurazioni a pagamento e non devono perdersi quando un worktree viene cancellato. Il pattern .runs/ nel .gitignore corrisponde solo alle directory, quindi non ha ignorato questo link. Il 21 agosto 2026 git status lo mostrava in ogni worktree come file non tracciato; mancava solo un git add -A perché finisse in un commit. Anche i nostri test sul database usano un database di test in comune. Per evitare che i test di due worktree girino nello stesso momento, teniamo una directory di lock.
Perché un controllo all’apertura della sessione non basta?
Guardare lo stato della directory quando si apre una sessione serve, ma solo per quel momento. Nel nostro repository, l’hook di apertura della sessione dice a una sessione che si apre su un dev pulito: «basta un branch, non serve un worktree». Se due sessioni si aprono sullo stesso dev pulito, ricevono tutte e due questa risposta e tutte e due aprono un branch nella stessa directory. Quando la seconda passa al suo nuovo branch, cambia anche il branch su cui lavora la prima.
Per questo un secondo hook, che gira prima di ogni modifica, confronta branch e commit con quello che era stato detto l’ultima volta alla sessione. I dettagli sono nell’articolo sugli hook; qui vogliamo aggiungere che cosa viene confrontato. La prima cosa che viene in mente è il numero di file non committati. Ma il 12 settembre 2026 abbiamo visto che una sola modifica fatta dalla sessione stessa fa sembrare sporca una directory pulita. Un avviso che guarda lo sporco scambia il lavoro dell’agente per quello di un altro. Per questo l’hook guarda solo il branch e il commit sottostante, e avvisa senza fermare l’azione.
L’hook non può sapere chi ha fatto il cambiamento, e non prova a indovinarlo. Anche la sessione che apre il proprio branch riceve un avviso, una volta; capisce che è opera sua e va avanti.
Claude Code, in più, esegue i propri controlli per una sessione isolata in un worktree. Secondo la sua documentazione, rifiuta le modifiche che puntano a un percorso del checkout principale e i comandi che indirizzano git verso il checkout principale. La documentazione scrive chiaramente anche il limite: questi controlli non seguono in quali file scrive un comando di shell. Un comando che scrive nel checkout principale con cp o con una redirezione non viene fermato da questi controlli; secondo la documentazione, un comando del genere viene valutato in base alle tue impostazioni di permessi e di sandbox. Quindi, dove un agente può scrivere non lo limita il worktree, ma quelle impostazioni.
Perché i worktree si accumulano e come si puliscono?
Aprire un worktree è un solo comando; chiuderlo, invece, spesso ce lo si dimentica. Come abbiamo raccontato nell’articolo sui subagenti, il 27 agosto 2026 nel nostro repository si erano accumulati 41 worktree, e 37 erano rimasti da un solo giro di review. Il disordine non lo creano le persone, ma i flussi di lavoro. Quel giorno abbiamo scritto uno script di pulizia. Il 18 ottobre 2026 abbiamo contato di nuovo:

git worktree list --porcelain e gh pr list; i comandi e l’output sono nel file delle misurazioni dell’articolo.Nessuno dei 34 worktree con il branch già unito aveva modifiche non committate. Sono proprio i worktree che il nostro script di pulizia rimuove. Ma lo script non parte da solo; l’hook di apertura della sessione si limita a suggerire di lanciarlo, e finché qualcuno non lo fa, restano tutti lì. In tutto, 5 worktree stavano nella directory di Codex (~/.codex/worktrees) e gli altri 61 sotto .claude/worktrees/. Secondo la data di creazione della directory che git tiene per ogni worktree, 28 di quelli ancora presenti erano stati aperti in un solo giorno, il 15 ottobre. Anche la bozza di questo articolo è stata scritta in un worktree aperto il 18 ottobre 2026.
Git non sa dire se un branch è stato unito. Il nostro repository unisce le pull request con lo squash, e lo squash riscrive i commit. Per questo un branch unito non è né un antenato di dev né identico commit per commit. Abbiamo controllato un branch pochi minuti dopo il merge: merge-base --is-ancestor ha detto «non unito» e git cherry «mancano 2 commit»; avevano torto tutti e due. Un altro branch, con tutto il contenuto già in dev, risultava «avanti di 36 commit». L’unico posto che lo sa è la pull request. Per questo il nostro script di pulizia chiede a GitHub e rimuove solo i worktree puliti la cui pull request è stata unita.
Anche il numero stesso può ingannare. Un worktree la cui directory è stata cancellata a mano resta nella lista, segnato come prunable, finché non gira git worktree prune. Il nostro hook di apertura della sessione all’inizio contava tutte le righe insieme. L’8 settembre 2026 ha detto 26 worktree; qualche comando dopo, git worktree list ne mostrava 7. Ora conta separatamente quelli vivi e quelli eliminabili, e suggerisce lo script di pulizia quando i worktree vivi sono più di 4 o c’è anche una sola voce eliminabile.
Anche la pulizia dei singoli strumenti è diversa. Codex tiene per impostazione predefinita i suoi ultimi 15 worktree. Cursor ne tiene per impostazione predefinita 25 per macchina e, secondo la sua documentazione, considera eliminabili anche i worktree aperti con git worktree add. Claude Code fa pulizia dei worktree dei subagenti e di quelli in background, ma lascia quelli in cui c’è ancora lavoro. Gemini CLI invece lascia la pulizia a te. Se usi più strumenti nello stesso repository, sappi quale cancella che cosa.
A che cosa fare attenzione quando fai girare agenti in parallelo?
Da ogni errore qui sopra è nato un punto. Messi insieme, si riassumono così:

git -C, lock e pulizia sono regole del nostro repository; quello sullo stash viene dalla documentazione di git, quello sul setup dalla documentazione degli strumenti.- Non tutti gli agenti hanno bisogno di un worktree. Il worktree serve quando due lavori vogliono lo stesso repository nello stesso momento, su commit diversi. Se una sola sessione lavora su un
devpulito, basta un branch. Ogni worktree inutile è una directory in più da pulire dopo. - Non dimenticare il setup. Un nuovo worktree è un checkout pulito: niente dipendenze, niente ambiente virtuale, niente
.env. Anche la documentazione di Claude Code e quella di Gemini CLI dicono di preparare l’ambiente in ogni nuovo worktree. Nel nostro repository ogni worktree installa il proprio ambiente prima della sua prima esecuzione dei test. - Dividi il lavoro per file. Nel nostro repository i compiti che giravano nello stesso momento avevano file separati, ogni commit è stato fatto con
--onlye le esecuzioni dei test si mettevano in coda dietro al lock comune. - Il parallelismo non è gratis. Secondo la documentazione di Claude Code, far girare più sessioni o subagenti nello stesso momento moltiplica il consumo di token.
Alla fine il lavoro degli agenti in parallelo arriva sullo stesso branch sotto forma di pull request, e quel branch avanza a ogni merge. Quando diffox esamina una pull request, misura la modifica dal punto in cui il branch si è staccato dal branch di base (il merge base); è la modifica che GitHub mostra nella pull request. Anche la versione precedente dei file la legge dallo stesso punto. Così, se il lavoro di un altro agente è stato unito al branch di base più tardi, non si mescola a questa review.
Domande frequenti
Che cos’è un git worktree?
Un git worktree è una seconda directory di lavoro aperta dallo stesso repository. Ogni worktree ha i suoi file, il suo HEAD e il suo index; la cronologia dei commit, i branch e le impostazioni del repository sono in comune. Si apre con git worktree add -b <branch> <directory> e si rimuove con git worktree remove <directory>. Così puoi lavorare su più branch nello stesso momento senza toccare la directory in cui sei.
Che differenza c’è tra worktree e branch?
Un branch è un nome che punta a un commit; un worktree è una directory in cui sono aperti i file di un branch. Se cambi branch in un’unica directory, i file cambiano per tutti quelli che ci lavorano. Con i worktree, ogni branch resta aperto nella sua directory. Git permette che un branch sia aperto in un solo worktree alla volta; se provi ad aprire lo stesso branch in un secondo worktree, git worktree add lo rifiuta.
Come si apre un worktree in Claude Code?
claude --worktree <nome> (in breve -w) apre un nuovo worktree e ci avvia la sessione. Per impostazione predefinita il worktree viene creato sotto .claude/worktrees/<nome>/, su un nuovo branch chiamato worktree-<nome>, e parte dal branch predefinito del repository remoto. Perché un subagente lavori sempre nel proprio worktree, aggiungi isolation: worktree alla sua definizione. La documentazione consiglia di aggiungere la directory .claude/worktrees/ al .gitignore.
Dove tengono i worktree Codex e Cursor, e quando li eliminano?
Nell’app desktop di ChatGPT, Codex apre i worktree sotto $CODEX_HOME/worktrees, in detached HEAD invece che su un branch. Per impostazione predefinita tiene gli ultimi 15 worktree e, prima di eliminarne uno, ne salva uno snapshot. In Cursor (3.5 e successive) la pulizia gira a intervalli e per impostazione predefinita tiene al massimo 25 worktree per macchina; tutti i workspace contano per lo stesso limite. La documentazione di Cursor non dice in quale directory vengono aperti i worktree.
Un worktree copia il file .env e le dipendenze?
Non da solo; un nuovo worktree parte solo con i file tracciati da git. Claude Code e Codex copiano i file che git ignora (come .env) se sono scritti nel file .worktreeinclude nella radice del repository. In Cursor i comandi di setup si scrivono in .cursor/worktrees.json. Le dipendenze vanno reinstallate in ogni worktree. Claude Code può portare directory grandi con un link simbolico tramite worktree.symlinkDirectories, mentre Cursor lo sconsiglia per le dipendenze.
Come si eliminano i worktree che non servono più?
git worktree remove <directory> rimuove un worktree pulito; se ci sono modifiche non committate serve --force. Se hai cancellato la directory a mano, git worktree prune pulisce la voce rimasta. Codex e Cursor eliminano da soli i worktree vecchi oltre un certo limite, Gemini CLI no. Antigravity elimina il worktree che ha dato a un subagente non appena quel subagente viene terminato. In un repository che unisce le pull request con lo squash, git non sa dire se un branch è stato unito; chiedilo alla pull request.