Sei a metà di un feature branch, tre file modificati e niente ancora committato, quando un collega ti scrive per un crash da null pointer in produzione. La mossa classica è git stash, checkout di main, risolvi, pusha, poi git stash pop sperando che il lavoro a metà non dipendesse dai file da cui sei appena scappato. git worktree salta tutto questo. Fa il checkout del branch di hotfix in una seconda cartella, accanto al tuo feature branch, entrambe appoggiate sullo stesso repository.
Cosa fa davvero git worktree
Un checkout normale ti dà i file di un branch alla volta: cambiare branch riscrive quei file sul posto. git worktree ti dà più checkout dello stesso repository, ognuno nella sua cartella con il proprio branch, e puoi modificarli in modo indipendente.
Non sono clone separati. Esiste esattamente una cartella .git con il database degli oggetti, i ref e la config, e ogni worktree legge e scrive lì. In una worktree secondaria, .git non è nemmeno una cartella: è un file di una riga che punta a quella condivisa. Per questo creare una worktree è quasi istantaneo e non aggiunge storia su disco.
C’è una sola restrizione che conta. Due worktree non possono avere lo stesso branch in checkout contemporaneamente, perché un branch punta a un solo commit corrente e due checkout che committano su di esso litigherebbero per quel puntatore. Tutto il resto è per-worktree, dai file non tracciati e l’index fino al commit su cui si trova HEAD.
Come creare una worktree per un hotfix
Dal tuo checkout esistente di myapp, su feature/checkout-flow con modifiche non committate:
| |
Questo crea ../myapp-hotfix accanto alla tua cartella attuale, con un nuovo branch hotfix/null-pointer creato da main e già in checkout al suo interno. La cartella originale resta su feature/checkout-flow, sporca e intatta.
| |
Tornato nella cartella originale, il tuo lavoro sulla feature è esattamente dove l’avevi lasciato. Nessun pop da fare, nessuno stash da ricordare.
Senza -b, git worktree add <path> usa l’ultimo pezzo del percorso come nome del branch. Se non esiste un branch con quel nome, Git lo crea da HEAD; se esiste e non è già in checkout in un’altra worktree, Git lo mette in checkout. Usa -d (--detach) quando vuoi solo un commit da esplorare, senza nessun branch.
Come elencare, rimuovere e pulire le worktree
| |
| |
Una volta che l’hotfix è stato mergiato, rimuovi la worktree passando da Git invece di cancellare la cartella a mano:
| |
remove si rifiuta se la worktree ha file tracciati modificati o file non tracciati. Passa -f per forzare. Se la cartella scompare in un altro modo (un rm -rf per sbaglio, un job CI che crasha), Git mantiene la sua voce amministrativa e git worktree list continua a mostrarla. Rimuovi la voce obsoleta con:
| |
Esegui prima con -n per vedere cosa rimuoverebbe senza farlo davvero.
Alcune worktree devono restare per settimane: un branch di release di lunga durata, o un checkout su una share di rete che non è sempre montata. Blocca quelle così prune lascia stare la loro voce e move e remove si rifiutano di toccarle:
| |
Fai l’unlock prima se vuoi spostarne una con git worktree move <path> <new-path>. Spostare o rimuovere una worktree bloccata senza prima sbloccarla richiede --force due volte: una scelta pensata apposta come override deliberato.
Quando usare git worktree oltre agli hotfix
Ogni volta che ti servono due checkout vivi invece di uno:
- Revisionare una PR senza perdere il tuo punto.
git worktree add ../myapp-review origin/some-pr-branchti dà una copia compilabile del branch di qualcun altro, mentre il tuo lavoro resta in checkout dove era. - Eseguire
git bisectsenza bloccare tutto il resto. Un bisect spostaHEADa ogni passo, quindi il checkout in cui lo esegui diventa inutilizzabile per qualsiasi altra cosa finché non finisci o non fai reset. Eseguilo in una worktree dedicata (vedi Git Bisect: Trovare il Commit che ha Introdotto un Bug) e continua a lavorare in quella principale. - Eseguire due job sul repository in parallelo. Una test suite lunga su un branch mentre modifichi un altro, oppure due agenti AI su task separati: ognuno ha bisogno della propria cartella di lavoro. Una worktree te la fornisce senza un secondo
git clonee una seconda cartella.gitda più gigabyte.
Quando non usare git worktree
Ogni worktree duplica la working tree, non il database degli oggetti. Dieci worktree di un repository con un checkout da 50 MB costano circa 500 MB di file su disco, anche con un solo .git. Per un cambio di contesto di cinque minuti, git stash costa meno e non lascia niente da pulire dopo.
I submodule sono il punto dolente. git worktree move non sposta una worktree che contiene submodule, e una nuova worktree parte con le cartelle dei submodule vuote finché non esegui git submodule update --init al suo interno. La stessa documentazione di Git definisce incompleto il supporto ai submodule nei checkout multipli, quindi per un superprogetto con molti submodule un clone separato resta la scelta più sicura.
Anche certi strumenti assumono una sola cartella di lavoro per repository. Un IDE o un file-watcher che lega la sua cache al percorso assoluto del repository può confondersi davanti alla stessa storia in due posti. Apri ogni worktree come progetto a sé, non come sottocartella della prima: di solito risolve il problema.
Se devi solo accantonare o annullare qualcosa nel checkout che hai già, git stash oppure git reset, revert o restore è lo strumento più leggero. La prossima volta che un hotfix arriva a metà di una feature, prova git worktree add prima di git stash e guarda quale dei due preferisci pulire dopo.