Você está no meio de um branch de feature, três arquivos alterados e nada commitado, quando um colega avisa sobre um null pointer quebrando a produção. O jeito usual é dar git stash, fazer checkout da main, corrigir, dar push, depois git stash pop e torcer para que nada na sua feature inacabada dependesse dos arquivos que você acabou de trocar. O git worktree elimina essa dança. Ele faz checkout do branch do hotfix em uma segunda pasta, ao lado do seu branch de feature, com os dois apoiados no mesmo repositório.

O que o git worktree realmente faz

Um checkout normal te dá os arquivos de um branch por vez. Trocar de branch sobrescreve esses arquivos no lugar. O git worktree te dá vários checkouts do mesmo repositório, cada um em seu próprio diretório com seu próprio branch, e você pode editá-los de forma independente.

Não são clones separados. Existe exatamente um diretório .git guardando o banco de objetos, as refs e a config, e cada worktree lê e grava nele. Em um worktree secundário, o .git nem é um diretório: é um arquivo de uma linha só, apontando de volta para o compartilhado. É por isso que criar um worktree é quase instantâneo e não duplica o histórico em disco.

Há uma restrição que importa: dois worktrees não podem ter o mesmo branch em checkout ao mesmo tempo, porque um branch aponta para um único commit atual, e dois checkouts fazendo commit nele entrariam em conflito por esse ponteiro. Tudo o mais é por worktree: dos arquivos não rastreados e do index até o commit em que o HEAD está.

Como criar um worktree para um hotfix

A partir do seu checkout já existente de myapp, no feature/checkout-flow com mudanças não commitadas:

1
git worktree add ../myapp-hotfix -b hotfix/null-pointer main

Isso cria ../myapp-hotfix ao lado do seu diretório atual, com um branch novo, hotfix/null-pointer, criado a partir da main e já em checkout dentro dele. Seu diretório original continua no feature/checkout-flow, sujo e intocado.

1
2
3
4
cd ../myapp-hotfix
# corrija o bug, commit, push
git push -u origin hotfix/null-pointer
cd ../myapp

De volta ao diretório original, seu trabalho na feature está exatamente como você deixou. Nada para dar pop, e nenhum stash para esquecer.

Sem -b, o git worktree add <path> nomeia o branch a partir do último componente do caminho. Se não existir um branch com esse nome, o Git o cria a partir do HEAD; se existir e não estiver em checkout em outro worktree, o Git faz o checkout dele. Use -d (--detach) quando quiser só um commit para explorar, sem nenhum branch.

Como listar, remover e limpar worktrees

1
git worktree list
1
2
/home/user/myapp          3a1f9c2 [feature/checkout-flow]
/home/user/myapp-hotfix   7e04d81 [hotfix/null-pointer]

Depois que o hotfix for mergeado, remova o worktree pelo Git, em vez de simplesmente apagar a pasta:

1
git worktree remove ../myapp-hotfix

O remove se recusa se o worktree tiver arquivos rastreados modificados ou arquivos não rastreados. Passe -f para forçar. Se o diretório desaparecer de outro jeito (um rm -rf por engano, um job de CI que travou), o Git mantém a entrada administrativa e o git worktree list continua mostrando ela. Limpe a entrada obsoleta com:

1
git worktree prune

Rode com -n primeiro para ver o que seria removido.

Alguns worktrees devem continuar por semanas: um branch de release de longa duração, ou um checkout em um compartilhamento de rede que nem sempre está montado. Trave esses para que o prune deixe a entrada em paz e o move e o remove se recusem a tocar neles:

1
2
git worktree lock --reason "branch de release, nao fazer prune" ../myapp-release
git worktree unlock ../myapp-release

Destrave primeiro se quiser realocar um worktree com git worktree move <path> <new-path>. Mover ou remover um worktree travado sem destravar exige --force duas vezes: é uma barreira deliberada, não um acidente.

Quando usar git worktree além de hotfixes

Sempre que você precisar de dois checkouts ativos em vez de um:

  • Revisar um PR sem perder seu lugar. git worktree add ../myapp-review origin/some-pr-branch te dá uma cópia buildável do branch de outra pessoa, enquanto seu próprio trabalho continua em checkout onde estava.
  • Rodar o git bisect sem travar todo o resto. Um bisect move o HEAD a cada passo, então o checkout onde ele roda fica inútil para qualquer outra coisa até você terminar ou resetar. Rode em um worktree dedicado (veja Git Bisect: Como Encontrar o Commit que Quebrou seu Código) e continue trabalhando no seu worktree principal.
  • Rodar dois trabalhos contra o repositório em paralelo. Uma suíte de testes longa em um branch enquanto você edita outro, ou dois agentes de IA trabalhando em tarefas separadas: cada um precisa do seu próprio diretório de trabalho. Um worktree fornece isso sem precisar de um segundo git clone e uma segunda pasta .git de vários gigabytes.

Quando não usar git worktree

Cada worktree duplica a working tree, não o banco de objetos. Dez worktrees de um repositório com um checkout de 50 MB custam cerca de 500 MB de arquivos em disco, mesmo com um único .git. Para uma troca de contexto de cinco minutos, o git stash é mais barato e não deixa nada para limpar depois.

Submodules são o ponto mais delicado. O git worktree move não move um worktree que contenha submodules, e um worktree novo começa com os diretórios de submodule vazios até você rodar git submodule update --init dentro dele. A própria documentação do Git chama o suporte a submodules em múltiplos checkouts de incompleto, então para um superprojeto com muitos submodules um clone separado é a escolha mais segura.

Algumas ferramentas também assumem um único diretório de trabalho por repositório. Uma IDE ou um file-watcher que baseia o cache no caminho absoluto do repositório pode se confundir com o mesmo histórico em dois lugares. Abrir cada worktree como seu próprio projeto, não como subpasta do primeiro, costuma resolver.

Se você só precisa guardar ou desfazer algo no checkout que já tem, o git stash ou git reset, revert ou restore é a ferramenta mais leve. Na próxima vez que um hotfix cair no meio de uma feature, tente o git worktree add antes do git stash e veja qual dos dois você prefere limpar depois.

Artigos relacionados