Git Worktrees Explicados: Quando e Por Que Usá-los
Git worktrees explicados: em que diferem de stashes e clones, quando usá-los e quais comandos servem para gerenciá-los.
Um Git worktree é um diretório de trabalho adicional vinculado ao mesmo repositório, com sua própria branch em checkout, permitindo que você tenha duas branches abertas em duas pastas ao mesmo tempo sem precisar clonar nada.
A maioria dos desenvolvedores descobre essa necessidade em meio à frustração: um stash aplicado na branch errada, um language server travado em uma reindexação após um checkout, ou um segundo clone do mesmo repositório que nunca fica realmente sincronizado. Worktrees resolvem os três casos, e estão disponíveis desde o Git 2.5, em julho de 2015, então não há nada para instalar.
Este artigo aborda o que um worktree realmente é em disco, os três comandos que operam o recurso, quando ele supera um stash, quando ele supera um segundo clone, e qual é o custo envolvido.
Principais Conclusões
- Um Git worktree é um segundo diretório de trabalho vinculado ao mesmo repositório, com sua própria branch em checkout; o diretório vinculado contém um pequeno arquivo
.gitapontando de volta para o repositório principal, e não uma pasta.gitcompleta. - Um único
git worktree add -b hotfix-bug ../hotfix-workspace mainsubstitui toda a sequência de stash, checkout, criação de branch, correção e stash-pop. - Todos os worktrees compartilham um único banco de objetos e um único conjunto de refs, portanto um único
git fetchatualiza todos os worktrees e nenhum histórico é duplicado em disco. - O Git rastreia arquivos commitados, não o seu ambiente: dependências instaladas, arquivos
.enve caches de build permanecem no diretório original. - Por padrão, o Git se recusa a fazer checkout da mesma branch em dois worktrees; crie um worktree com HEAD desanexado usando
git worktree add -dquando você só precisa compilar ou testar um commit.
O Que É um Git Worktree em Disco?
Um worktree vinculado é um diretório de arquivos em checkout, não uma cópia do seu repositório. Seu .git de nível superior é um arquivo comum, não um diretório, e ele aponta para uma pequena pasta de metadados dentro de .git/worktrees/ do repositório principal — um layout que a documentação do git worktree descreve por completo. Tudo o que é pesado permanece em um só lugar: um banco de objetos, um histórico e um conjunto de refs servem a todos os worktrees, e apenas um punhado de arquivos pertence a um worktree individual, entre eles o HEAD e o index.
Esse único fato explica todo o resto sobre worktrees. Criar um custa um checkout, não um clone. Commits feitos em qualquer worktree ficam imediatamente visíveis a partir de todos os outros, porque existe apenas um repositório por baixo.
Que Fluxo de Trabalho um Worktree Substitui?
Sem worktrees, uma interrupção urgente significa suspender seu estado atual. A sequência familiar, usando a forma git stash push para que a mensagem realmente seja anexada:
git stash push -m "wip: login form"
git checkout main
git checkout -b hotfix-bug
# fix, commit, push, wait for the merge
git checkout feature-login
git stash pop
Cinco comandos, duas trocas de contexto e uma chance de aplicar o stash na branch errada. A versão com worktree é um único comando:
git worktree add -b hotfix-bug ../hotfix-workspace main
Isso cria uma pasta irmã, cria a branch hotfix-bug a partir de main e faz o checkout dela ali. Seu diretório original permanece intocado: mesma branch, mesmos arquivos modificados, mesmo editor aberto. Quando a correção for mesclada, git worktree remove ../hotfix-workspace apaga a pasta e a desregistra.
Os Três Comandos: add, list, remove
O uso cotidiano de worktrees se resume a três subcomandos. git worktree add <path> <branch> faz o checkout de uma branch existente em um novo caminho; adicione -b <new-branch> antes do caminho para criar a branch no mesmo processo. Aponte o add para um caminho que ainda não existe e o Git cria o diretório para você.
git worktree list mostra todos os worktrees, começando pelo principal, com seu caminho, o hash abreviado do commit e a branch em checkout entre colchetes:
/home/you/project abc1234 [feature-login]
/home/you/hotfix-workspace def5678 [hotfix-bug]
git worktree remove <path> exclui um worktree, e as regras do Git para remoção são rígidas: um único arquivo untracked ou um arquivo rastreado editado interrompe o comando, a menos que você adicione --force, que descarta essas alterações. O Git não permite remover o worktree principal de forma alguma, e um worktree bloqueado exige --force duas vezes. Se você apagar a pasta do worktree manualmente, git worktree prune limpa os metadados deixados para trás.
Quando um Worktree Supera um Stash?
Um stash suspende seu trabalho; um worktree permite que ele continue rodando. Essa distinção define qual dos dois você quer. Um stash é adequado para guardar um diff de duas linhas por dez minutos. É a ferramenta errada quando o trabalho no seu diretório ainda está em andamento: uma suíte de testes ou um build longo em execução, um dev server observando arquivos, ou um editor cujo language server reindexaria o projeto inteiro após uma troca de branch.
Com um worktree, nada desse estado é perturbado, porque você nunca toca no diretório original. Você abre a nova pasta em uma segunda janela do editor, faz a tarefa interruptiva ali e volta para encontrar tudo exatamente onde deixou. Esse mesmo isolamento é o motivo pelo qual ferramentas que executam agentes de codificação com IA em paralelo adotaram worktrees como seu modelo de trabalho. Para uma visão mais opinativa, o texto de matklad descreve o conjunto fixo de cinco worktrees de um desenvolvedor, mapeados para atividades concorrentes em vez de branches; encare isso como uma configuração pessoal, não como prática padrão.
Worktree ou Segundo Clone?
Um worktree supera um segundo clone sempre que ambos os diretórios devem acompanhar o mesmo repositório. Como todos os worktrees compartilham um único object store e um único conjunto de refs, um único git fetch atualiza todos eles, uma branch enviada a partir de um fica instantaneamente visível nos outros, e adicionar um worktree não duplica histórico algum em disco. Um segundo clone não oferece nada disso: dois object stores para receber fetches, dois conjuntos de refs que divergem entre si e o dobro de espaço em disco.
Um clone ainda é a escolha certa em dois casos: quando o trabalho pertence a um remote genuinamente diferente, como um fork com o qual você interage separadamente, ou quando você quer um experimento descartável totalmente isolado do seu repositório principal, onde até mesmo refs compartilhadas são indesejadas.
| Stash | Worktree | Segundo clone | |
|---|---|---|---|
| O trabalho continua rodando | Não | Sim | Sim |
| Custo de configuração | Instantâneo | Um checkout | Clone completo |
| Histórico em disco | Compartilhado | Compartilhado | Duplicado |
| Um fetch atualiza tudo | Sim | Sim | Não |
Qual É o Custo dos Worktrees?
O Git rastreia arquivos commitados, não o seu ambiente. Esse é o principal imposto cobrado em cada novo worktree:
- Dependências instaladas não vêm junto. Um worktree novo de um projeto npm ou pip normalmente precisa da sua própria etapa de instalação antes de compilar.
- Arquivos locais untracked ficam para trás: arquivos
.env, configurações locais e caches de build permanecem no diretório original, porque o Git não tem registro deles. - Pastas de worktree criadas dentro do repositório aparecem como sujeira untracked e precisam de uma entrada no
.gitignore. Diretórios irmãos (../hotfix-workspace) evitam completamente o problema. - Por padrão, uma branch pode estar em checkout em apenas um worktree por vez. Existem formas de contornar isso (
--forcenoadd,--ignore-other-worktreesnoswitch), mas a resposta mais limpa quando você só precisa compilar ou testar um commit é um worktree com HEAD desanexado:
git worktree add -d ../build-check 1a2b3c4
A flag -d deixa o HEAD desanexado na nova pasta, de modo que nenhuma branch é reivindicada e a restrição nunca é acionada. git switch -d <commit> dentro de um worktree existente faz o mesmo trabalho.
Você Tem Coisas Suficientes em Andamento?
O teste de adoção é curto. Interrupções aparecem regularmente enquanto você tem trabalho real não commitado em andamento? Uma troca de branch dispara uma reinstalação de dependências ou uma reindexação do language server que você sente na prática? Você já mantém um segundo clone do mesmo repositório? Dois “sim” e os worktrees se pagarão já na primeira semana. Nenhum, e stash mais branches funciona perfeitamente bem. Comece com um: na próxima vez que uma correção urgente surgir no meio de uma feature, execute git worktree add em vez de git stash, e remova a pasta quando a correção for mesclada.
Perguntas Frequentes
Git worktrees funcionam com repositórios que usam submodules?
Parcialmente. O próprio manual do Git sinaliza o suporte a submodules como inacabado em sua nota de BUGS, e desaconselha fazer checkout de um superproject em mais de um lugar ao mesmo tempo. Na prática, um worktree vinculado com submodules dentro dele não pode ser realocado usando git worktree move, e removê-lo com git worktree remove exige a flag force. Se o seu repositório depende fortemente de submodules, um segundo clone é a escolha mais segura.
Stashes e branches são compartilhados entre git worktrees?
Sim. Qualquer coisa sob refs/ é comum a todos os worktrees, então branches, tags e o stash aparecem iguais onde quer que você esteja. Três namespaces são exceção e permanecem locais a um worktree: refs/bisect, refs/worktree e refs/rewritten. Além desses, apenas os ponteiros próprios de um worktree são privados, entre eles o HEAD e seu index. Um stash criado em um worktree pode, portanto, ser listado e aplicado a partir de qualquer outro worktree do mesmo repositório.
Posso mover um worktree para outra pasta depois de criá-lo?
Sim. Passe ao git worktree move o worktree e o caminho onde você o quer, e o Git move a pasta e reescreve seus metadados de uma só vez. Dois casos que ele não trata: o worktree principal e qualquer worktree vinculado com submodules dentro dele. Um worktree bloqueado exige a flag force duas vezes. Se você já arrastou a pasta para outro lugar por conta própria, git worktree repair a reconecta.
O que acontece se eu executar git worktree add apenas com um caminho e sem branch?
O Git usa a última parte do caminho como nome de branch, inicia essa branch em HEAD e faz o checkout dela na nova pasta. Assim, git worktree add ../hotfix deixa você com uma branch chamada hotfix, em checkout em ../hotfix. Se esse nome já estiver em uso, o Git faz o checkout da branch existente, desde que nenhum outro worktree a esteja ocupando no momento.