Worktrees permitem que você faça checkout de múltiplos branches ao mesmo tempo, cada um em seu próprio diretório, todos compartilhando um único repositório subjacente. Chega de danças de git stash quando você precisa alternar entre contextos.
Cartão de receita de referência rápida -- pronto para copiar e colar.
# Adicionar um worktree em um branch existentegit worktree add ../feature-branch feature-branch# Adicionar um worktree e criar um novo branch em uma única etapagit worktree add ../new-feature -b new-feature# Adicionar um worktree em um commit ou tag específico (HEAD destacado)git worktree add ../hotfix abc1234# Listar todos os worktrees associados a este repositóriogit worktree list# Remover um worktree (após commitar ou dar stash nas alterações)git worktree remove ../feature-branch# Limpar entradas obsoletas após uma pasta ter sido excluída manualmentegit worktree prune
Quando usar isso: Sempre que você, de outra forma, faria um git stash, clonaria o repositório uma segunda vez, ou alternaria entre branches várias vezes por hora.
# 1. Iniciar um recurso em seu próprio diretóriogit worktree add ../my-feature -b my-feature# 2. Trabalhar e commitar dentro desse worktreecd ../my-feature# ...editar arquivos, executar testes...git commit -am "feat: estruturar novo recurso"# 3. Voltar para o worktree principal para fazer o mergecd ../main-repogit switch maingit merge my-feature# 4. Limpargit worktree remove ../my-featuregit branch -d my-feature
O que isso demonstra:
Um repositório, dois diretórios de trabalho simultâneos com arquivos independentes.
O novo commit do recurso é imediatamente visível a partir do worktree principal -- eles compartilham o histórico.
O worktree principal é onde o merge acontece; o worktree do recurso é apenas um lugar para escrever código.
Worktrees são temporários por design: crie, trabalhe, faça merge, remova.
Pense em um repositório Git como a casa de um escritor. Na sala dos fundos fica um armário de aço -- este é o diretório .git, contendo cada commit, cada branch, cada fragmento de histórico. No escritório fica sua mesa de escrita, onde uma versão do manuscrito está disposta para que você possa ler e editar.
Para a maior parte da história do Git, você tinha apenas uma mesa. Mudar de branch significava recolher as páginas da mesa, arquivá-las de volta e dispor uma versão diferente. Se você estivesse no meio de um recurso e precisasse corrigir um bug de produção, teria que dar stash no seu trabalho inacabado, limpar a mesa, corrigir o bug e depois reverter todo o processo.
Worktrees lhe dão uma segunda mesa. E uma terceira. E uma quarta. Cada mesa contém um branch diferente, com seus próprios arquivos visíveis e editáveis, enquanto as outras continuam contendo o que quer que você tenha disposto antes. Todas as mesas compartilham o mesmo armário -- o mesmo histórico, os mesmos commits, a mesma configuração remota. Mas os arquivos na superfície, as árvores de trabalho, são independentes.
É isso que um worktree é: uma segunda visualização do mesmo repositório.
Quando você adiciona um worktree, o Git faz algo elegante. Na nova pasta, ele cria os arquivos da árvore de trabalho para o branch que você solicitou, exatamente como se você tivesse clonado o projeto do zero. Mas ele não clona nada. A nova pasta contém um pequeno arquivo .git (não um diretório) que aponta de volta para a pasta .git do repositório original. Toda operação no novo worktree -- commit, push, pull, log -- lê e escreve naquele único armário compartilhado.
Compartilhado entre todos os worktrees
Separado por worktree
Banco de dados de objetos (commits, blobs, árvores)
Arquivos do diretório de trabalho
Branches e tags
Índice (área de staging)
Configuração remota
Referência HEAD
Stashes
Alterações não commitadas
A maioria das configurações
Checkouts de submódulos (inicializados por worktree)
Hooks
Artefatos de build (node_modules, etc.)
A consequência maravilhosa: não há duplicação de histórico. Se o seu repositório tem gigabytes de objetos, adicionar um worktree mal adiciona algo ao disco -- você paga apenas pelos arquivos checkoutados, não pelo histórico por trás deles.
O Git impõe uma única regra que pega todos uma vez: um determinado branch só pode ser feito checkout em um worktree por vez. Tentar fazer checkout de main em dois worktrees, e o Git se recusa. A razão é simples -- se ambas as mesas contivessem o mesmo rascunho e você escrevesse alterações diferentes em cada uma, qual conjunto de alterações o armário eventualmente aceitaria? A restrição protege você de uma pergunta que não tem resposta boa.
A solução alternativa é o que você esperaria: crie um branch. Se você quiser um segundo worktree baseado em main, crie um novo branch a partir de main (git worktree add ../scratch -b scratch main) e use-o.
Dentro da sua pasta .git original, um subdiretório worktrees/ contém uma pequena pasta para cada worktree vinculado. Cada uma contém o HEAD, índice, logs e alguns outros arquivos próprios desse worktree. O repositório original sempre sabe onde cada worktree vive, qual branch ele tem em checkout e se a pasta ainda existe no disco.
git worktree list imprime todos eles, incluindo o worktree principal -- que é apenas a primeira mesa entre iguais.
Worktrees vinculados parecem iguais ao principal no uso diário, mas o worktree principal é onde o diretório .git real reside. Se você excluir a pasta do worktree principal enquanto worktrees vinculados ainda existirem, todos eles quebrarão -- o armário do qual dependem desapareceu. Trate o worktree principal como a fundação. Mova-o com cuidado (use git worktree repair depois, se necessário).
A mudança mental é de "branches são lugares que eu visito, um de cada vez" para "branches são lugares que posso ocupar simultaneamente, cada um em sua própria sala". Worktrees brilham quando:
Você é interrompido por um hotfix e não quer perturbar seu recurso em andamento.
Você quer revisar o PR de um colega executando o branch dele em uma pasta separada.
Você precisa executar uma suíte de testes longa em um branch enquanto continua o desenvolvimento em outro.
Você está comparando duas implementações lado a lado, ambas rodando, ambas editáveis.
Você mantém um worktree "principal" como uma referência limpa e faz todo o trabalho em worktrees de recursos.
Worktrees não são um substituto para branches. Eles nem sempre são um substituto para stash -- uma troca de contexto rápida de 30 segundos ainda é mais rápida com stash. Eles são quase sempre um substituto para clonar o repositório duas vezes, pois você evita o custo de armazenamento e a dor de cabeça de manter dois clones sincronizados via remoto.
Coisas que vão te morder. Cada armadilha inclui o que dá errado, por que acontece e a correção.
Tentar fazer checkout de um branch já em outro worktree -- O Git se recusa com fatal: '<branch>' is already checked out at .... Correção: Ou trabalhe no worktree existente, crie um novo branch a partir dele (git worktree add ../scratch -b scratch <branch>), ou remova o outro worktree primeiro.
Excluir uma pasta de worktree manualmente com rm -rf -- Os metadados do Git ainda apontam para a pasta ausente, e git worktree list continua mostrando-a. Correção: Execute git worktree prune para limpar referências pendentes.
Remover o worktree principal enquanto worktrees vinculados existem -- O diretório .git compartilhado desaparece e cada worktree vinculado é quebrado. Correção: Nunca exclua a pasta do worktree principal. Se você precisar realocar o repositório, mova o worktree principal primeiro e depois execute git worktree repair de dentro dele para atualizar os links.
Submódulos não são inicializados automaticamente em um novo worktree -- Os diretórios de submódulos aparecem vazios. Correção: Execute git submodule update --init --recursive dentro de cada novo worktree que precise de submódulos.
node_modules e artefatos de build duplicados por worktree -- Cada worktree tem sua própria árvore de trabalho, então npm install em três worktrees significa três diretórios node_modules. Correção: Use um cache de pacotes compartilhado (o armazenamento endereçável por conteúdo do pnpm lida com isso naturalmente) ou aceite o custo de disco como o preço do paralelismo.
Hooks disparam em todos os worktrees -- Hooks vivem no diretório compartilhado .git/hooks, então um hook pre-commit é executado independentemente de qual worktree você commita. Correção: Geralmente é o que você quer -- aplicação consistente -- mas esteja ciente se um hook depender de caminhos absolutos.
IDEs abrem a pasta errada após alternar worktrees -- Janelas do editor vinculadas ao caminho antigo continuam mostrando arquivos obsoletos. Correção: Abra cada worktree como seu próprio projeto/janela no seu editor; trate-os como espaços de trabalho separados.
Esquecer de commitar antes de git worktree remove -- O Git se recusa a remover um worktree com alterações não commitadas (bom!), mas você pode ficar preso se a pasta tiver arquivos não rastreados que você esqueceu. Correção: Ou commite, dê stash, ou use git worktree remove --force se tiver certeza de que as alterações são descartáveis.
Um clone duplica todo o diretório .git, histórico e tudo mais -- dois repositórios independentes.
Um worktree compartilha o diretório .git original, então commits e fetches em um são imediatamente visíveis em outros.
Worktrees são dramaticamente mais baratos em disco e evitam a dor de cabeça de "manter dois clones sincronizados via remoto".
Posso ter dois worktrees no mesmo branch?
Não. O Git impõe um branch por worktree para evitar commits conflitantes no mesmo ref de branch.
A solução é criar um novo branch: git worktree add ../scratch -b scratch main cria um novo branch a partir de main e o faz checkout no novo worktree.
Onde devo colocar meus diretórios de worktree?
Fora da pasta do seu repositório principal. Padrões comuns: uma pasta irmã (../my-feature) ou um diretório pai dedicado para worktrees (~/projects/myrepo-worktrees/feature-x).
Evite aninhar um worktree dentro do worktree principal -- o Git tratará os arquivos internos como não rastreados e a experiência fica confusa.
Worktrees compartilham meus stashes?
Sim. Stashes vivem no diretório compartilhado .git, então git stash list mostra as mesmas entradas de qualquer worktree.
Isso significa que você pode dar stash em um worktree e aplicar em outro -- ocasionalmente útil, frequentemente surpreendente.
O que acontece com meus worktrees quando eu faço push ou pull?
Um git fetch em qualquer worktree atualiza os refs remotos compartilhados, então todos os worktrees veem os novos commits imediatamente.
Um git pull atualiza apenas o branch em checkout no worktree onde você o executou -- os outros worktrees permanecem no commit que tinham.
Como mover um worktree para um novo local?
git worktree move ../old-path ../new-path
O Git atualiza os metadados para que o worktree continue funcionando de seu novo local.
Se você moveu a pasta manualmente com mv, execute git worktree repair ../new-path de dentro do worktree principal.
Hooks rodam em todos os worktrees?
Sim. Hooks vivem em .git/hooks e esse diretório é compartilhado, então um hook pre-commit é disparado em qualquer worktree onde você commita.
Geralmente é o que você quer -- aplicação consistente -- mas esteja ciente se um hook depender de caminhos absolutos.
Posso usar worktrees com submódulos?
Sim, mas submódulos não são inicializados automaticamente em um novo worktree. Execute git submodule update --init --recursive após criá-lo.
Versões recentes do Git lidam com isso de forma mais graciosa, mas a inicialização manual é o padrão seguro.
Como listar todos os worktrees e o branch em que cada um está?
git worktree list
A saída mostra o caminho, o SHA do commit e o branch (ou (detached HEAD)).
Use --porcelain para um formato estável e legível por máquina.
Existe um custo de desempenho em ter muitos worktrees?
Disco: cada worktree tem seus próprios arquivos checkoutados, então o uso de disco escala com o tamanho da árvore de trabalho (não do histórico). node_modules e artefatos de build são duplicados.
CPU/memória: negligenciável. Operações como git status apenas escaneiam o worktree atual.
Um punhado de worktrees é aceitável. Centenas seria incomum, mas tecnicamente suportado.