Voltar para as novidades

O que a git worktree não isola para agentes de IA de programação?

A git worktree isola arquivos e branch, não comportamento. Três coisas continuam compartilhadas com o seu checkout principal: o diretório .git do repositório, os plugins de escopo de projeto e as aprovações de permissão salvas. É por isso que dois agentes de IA de programação trabalhando em worktrees separadas ainda conseguem se alcançar, e é por isso que a pergunta útil não é se a worktree isola, e sim o que exatamente você está protegendo: os seus arquivos, ou a sua máquina.

Isso virou discussão pública em 30 de julho de 2026, quando uma thread no Hacker News intitulada "Git worktrees are not an isolation boundary for coding agents" juntou 35 comentários. Os que tratam do assunto se dividem entre gente que roda agente em worktree todo dia e gente que considera o enquadramento um espantalho.

O que a git worktree isola de fato para um agente de IA de programação?

A git worktree dá ao agente de IA de programação um diretório de trabalho próprio e uma branch própria, extraídos do mesmo repositório. As edições feitas por um agente em ../projeto-feature-a não aparecem no seu checkout principal, e as duas branches avançam de forma independente até alguém integrá-las. Para a falha que a maioria das pessoas está tentando evitar, que é dois agentes escreverem o mesmo arquivo com minutos de diferença e o segundo vencer em silêncio, a worktree resolve por completo.

Essa é a fronteira que se compra, e ela é real. No Hacker News, o usuário markush_ resumiu o lado positivo numa linha: "The big advantage of using worktrees is the shared git state, it makes it so much easier to cherry-pick and move commits around those worktrees", ou seja, a grande vantagem é justamente o estado compartilhado do git, que facilita mover commits entre as worktrees. O repositório compartilhado não é um descuido de projeto. Ele é a funcionalidade, e é o que torna a worktree mais barata e mais rápida que um segundo clone. Cobrimos a mecânica de criar uma, e as dependências e artefatos de build que não vão junto, no nosso guia de git worktree para agentes de IA. Este artigo começa onde aquele para: depois que as worktrees existem e os agentes continuam colidindo.

O que continua compartilhado entre a worktree e o checkout principal?

A documentação do Claude Code, da Anthropic, responde isso diretamente numa seção chamada "What worktrees share with the main checkout", lida em 12 de agosto de 2026. Ela nomeia três itens, e cada um tem uma consequência diferente para quem roda agentes de IA em paralelo.

  • O diretório .git do repositório. Segundo a documentação, comandos git rodados dentro de uma worktree escrevem no diretório .git compartilhado do repositório principal, e ela acrescenta que o sandbox permite essas escritas, de modo que comandos como git commit funcionam de dentro de uma worktree com o sandbox ligado.
  • Plugins de escopo de projeto. Plugins instalados em escopo de projeto a partir do checkout principal também carregam nas worktrees do mesmo repositório, então não precisam ser reinstalados em cada uma. A documentação amarra esse comportamento à versão 2.1.200 do Claude Code ou posterior.
  • Aprovações de permissão salvas. Escolher "Yes, don't ask again" para um comando de Bash dentro de uma sessão em worktree salva a regra no .claude/settings.local.json do checkout principal, então ela passa a valer no principal e em todas as outras worktrees daquele repositório, e sobrevive à remoção da worktree. A documentação registra que isso mudou na versão 2.1.211: antes dela, a aprovação era salva dentro da worktree e se perdia junto com ela.

O terceiro item merece releitura. Uma permissão que você concedeu a um agente, num diretório descartável, para se livrar de um aviso chato, vira permissão permanente para todos os agentes que você rodar naquele repositório depois.

Um agente de IA dentro da worktree consegue mexer no checkout principal?

Pelo git puro, consegue, e você prova isso para si mesmo em uns trinta segundos. Como o .git é compartilhado, um processo rodando dentro da worktree consegue escrever em .git/hooks, e hooks colocados ali rodam quando você commita a partir do checkout principal. Este bloco trabalha num diretório temporário, faz a demonstração e apaga tudo o que criou:

d=$(mktemp -d) && cd "$d"
git init -q demo && cd demo
git -c user.email=a@b.c -c user.name=t commit -q --allow-empty -m first
git worktree add -q ../agent-a -b agent-a
cd ../agent-a
printf '#!/bin/sh\necho "hook written from the worktree"\n' > "$(git rev-parse --git-common-dir)/hooks/pre-commit"
chmod +x "$(git rev-parse --git-common-dir)/hooks/pre-commit"
cd ../demo
git -c user.email=a@b.c -c user.name=t commit -q --allow-empty -m second
cd "${d:?}"; git -C demo worktree remove --force ../agent-a; rm -rf "${d:?}/demo" "${d:?}/agent-a"

Numa configuração padrão do git, sem core.hooksPath definido, o segundo commit imprime hook written from the worktree. Rodamos isso no git 2.50.1 em 12 de agosto de 2026. Se a sua máquina define core.hooksPath, o que husky, lefthook e muitas configurações corporativas fazem, o git procura os hooks em outro lugar e o comando não imprime nada: a demonstração fica silenciosa, e não errada. O ${d:?} da última linha não é enfeite. Ele faz o shell abortar em vez de expandir para string vazia caso o mktemp falhe, e essa é a diferença entre apagar um diretório temporário e apagar um caminho na raiz.

O que o resultado significa, dito com cuidado. Nenhum arquivo versionado mudou e nenhuma branch foi tocada, então o git status no checkout principal continua limpo. A escrita caiu dentro do diretório .git do checkout principal, que fisicamente mora dentro da pasta do checkout principal. E é justamente esse o ponto: a mudança é invisível para o comando que as pessoas usam para procurar mudança, e um script que só existiu dentro do diretório isolado agora roda na sua máquina, disparado pelo seu próprio commit. O comando git rev-parse --git-common-dir é o truque, porque de dentro da worktree ele imprime o caminho do .git do repositório principal, que é a superfície compartilhada.

A thread do Hacker News não deixou isso em aberto por muito tempo, e vale contar a troca inteira porque ela ESTREITA o que a demonstração prova. O usuário alchaplinsky perguntou se um agente confinado a um perfil de sandbox "can still write a pre-commit hook that runs on your machine whenever you commit outside the sandbox", isto é, se ele ainda consegue escrever um hook que roda na sua máquina quando você commita fora do sandbox, e terminou com "Or am I missing something?". O usuário sbysb, que tinha recomendado aquela ferramenta de sandbox e a roda com um perfil montado pelo time dele, respondeu que "All git config and hooks are not writable inside the sandbox", ou seja, que ali a configuração e os hooks do git não são graváveis. Dentro do perfil que aquele time usa, portanto, a resposta é não. E o mesmo comentarista fez em seguida a distinção mais afiada da thread inteira, que joga contra a própria montagem dele: "this doesn't close all of these types of attacks, just the ones that are invisible", isto é, aquilo não fecha todos os ataques, só os invisíveis. Um agente ainda consegue escrever um script e amarrá-lo ao seu código, mas isso chega como uma mudança que você lê num diff. Um hook do git não. O que o bloco acima acrescenta é a linha de base embaixo de tudo isso: no git puro, sem sandbox e sem harness nenhum impondo nada, o mecanismo funciona exatamente como alchaplinsky descreveu. Isso não é uma vulnerabilidade do git nem defeito de agente nenhum. É o repositório compartilhado fazendo o que foi desenhado para fazer, e o que fica estabelecido é estreito e útil: isolamento de arquivo e isolamento de processo são propriedades diferentes, e a worktree só vende a primeira.

O que o Claude Code bloqueia dentro de uma worktree, então?

O diretório .git compartilhado é exatamente a lacuna que a camada do harness existe para fechar, e o Claude Code publica o que ele impõe. Numa seção chamada "How Claude Code enforces isolation", lida em 12 de agosto de 2026, a documentação lista quatro checagens aplicadas enquanto a sessão está isolada numa worktree, valendo para a sessão e para todo subagente que ela criar.

O Claude Code bloqueia Edit, Write ou NotebookEdit que aponte para um caminho do checkout principal. Bloqueia comando de Bash, PowerShell ou Monitor cujo diretório de trabalho resolva para o checkout principal. Bloqueia comando que redirecione o git para o checkout principal, seja por git -C, por --git-dir, pelas variáveis GIT_DIR e GIT_WORK_TREE, ou por um cd antes de rodar o git. E bloqueia comando cuja forma ele não consegue verificar estaticamente como restrita à worktree, como expansão de chaves e heredoc com delimitador sem aspas, uma checagem que a documentação diz não ser possível desligar.

A leitura prática para quem roda agentes em paralelo: a sua garantia de isolamento vem do harness, quer dizer, da camada que roda o agente, seja ela o Claude Code, o Codex ou um executor que você mesmo escreveu. Ela não vem do git. Se você troca o harness ou dispara o agente por um invólucro que pula essas checagens, a fronteira que você achava que tinha vai junto.

A git worktree isola o banco de dados, o servidor de desenvolvimento ou as portas?

Não, e essa é a colisão que surpreende quem fez tudo certo. A worktree copia arquivos versionados. Ela não dá ao agente de IA um PostgreSQL próprio, um Redis próprio, uma porta 3000 própria nem uma pilha Docker própria. Cinco agentes em cinco worktrees compartilham um banco de desenvolvimento, e uma migration destrutiva rodada por qualquer um deles cai sobre os cinco.

A thread do Hacker News está cheia de gente que bateu nisso e construiu em volta. Um comentarista, francislavoie, descreveu um hook do Claude que roda um script próprio de criação de worktree, copiando node_modules e o .env para a worktree nova "plus doing some edits to the .env to isolate it so it can run in parallel", isto é, editando o .env para que aquela worktree rode em paralelo, e dando a cada uma o seu próprio nome de projeto no Docker Compose. Outro, madarco, disse de uma ferramenta de sandbox que outro comentarista tinha acabado de recomendar: "nono is great but you'll still won't be able to run multiple dev servers, dbs or test in the browser", ou seja, que mesmo com ela não daria para rodar vários servidores de desenvolvimento, vários bancos ou testar no navegador. O comentarista que recomendou a ferramenta, sbysb, contestou isso no comentário seguinte, respondendo que "With our profile setup you can do all three of those things", que com a configuração deles as três coisas são possíveis. Não somos juiz dessa divergência, porque o ponto sobre worktree não depende dela, e o ponto é NOSSO e não de nenhum dos dois: nada no git worktree add aloca porta, banco de dados ou perfil de navegador.

As mitigações baratas, na ordem em que tentaríamos: dar a cada worktree a sua porta por um .env editado, dar a cada uma o seu nome de projeto no Docker Compose, e fazer a suíte de testes usar banco em memória ou um banco por worktree em vez do banco de desenvolvimento compartilhado. Nada disso vem do git worktree add. É preparação que você escreve uma vez e reaproveita.

Como copiar o .env e o node_modules para uma worktree nova?

A worktree é um checkout novo, então arquivos ignorados pelo git como .env e .env.local simplesmente não estão lá, e essa é, pela nossa experiência, a primeira coisa que quebra numa worktree recém-criada. O Claude Code documenta um mecanismo para isso: um arquivo .worktreeinclude na raiz do projeto, com a sintaxe do gitignore, listando os arquivos a copiar para cada worktree nova. Segundo a documentação lida em 12 de agosto de 2026, só são copiados os arquivos que casam com um padrão e também são ignorados pelo git, de modo que arquivo versionado nunca é duplicado, e isso vale para worktrees criadas com --worktree, para worktrees de subagente e para sessões paralelas no aplicativo de mesa.

Uma ressalva que a página declara, e uma que acrescentamos por nossa conta. A página diz que, se você substituir a criação de worktree por um hook WorktreeCreate, a cópia precisa acontecer dentro do seu script. A nossa, que a página não faz: o exemplo da própria página lista config/secrets.json, e um .worktreeinclude que lista arquivo de segredo é uma decisão sobre raio de dano, porque coloca uma cópia daquele arquivo em todo diretório onde um agente trabalha.

Worktree, clone ou contêiner: qual o seu caso pede?

As três opções respondem a três perguntas diferentes, e a thread do Hacker News discutiu todas. O usuário firasd enquadrou a escolha pelo que se quer preservar: "[t]he answer is: non-pushed changes", as mudanças ainda não empurradas, que é o que tanto worktree quanto clone protegem. Um clone separado dá a você um .git próprio, então a superfície de hooks compartilhados descrita acima desaparece, e ele é mais barato do que parece: como o usuário alchaplinsky observou na mesma thread, git clone --shared escreve um arquivo de alternates apontando para o seu repositório de objetos e copia zero objetos. Confirmamos esse comportamento em 12 de agosto de 2026.

Para isolamento de processo e de rede, nenhum dos dois serve. O usuário QuercusMax disse em duas frases: "If you want to properly isolate things, use containers. That's not what worktrees are for", isto é, se quiser isolar de verdade, use contêiner, porque não é para isso que a worktree existe. Esse é o teto honesto. Contêiner ou máquina virtual é o que você quer antes de deixar um agente de IA rodando sem supervisão, porque é a única opção desta lista que isola o que o agente pode executar, e não apenas o que ele pode editar.

Uma regra de decisão grosseira: worktree para trabalho paralelo supervisionado numa máquina em que você confia, clone quando quiser um .git separado e hooks independentes, contêiner quando o agente roda sem ninguém olhando.

O que este artigo não prova

A demonstração do hook estabelece que um .git compartilhado é alcançável a partir de uma worktree, no git 2.50.1, em 12 de agosto de 2026, sem core.hooksPath definido e sem sandbox no caminho. Ela não diz nada sobre uma ferramenta de sandbox bloquear ou não a mesma escrita, e um comentarista da thread afirma que o perfil que o time dele usa bloqueia. Ela também não mede com que frequência isso causa dano real, e não temos dado dizendo que causa com frequência. Todo comentário citado aqui é a experiência de uma pessoa nomeada, não uma pesquisa, e a thread tem gente defendendo a posição contrária com a mesma convicção, incluindo quem disse que worktree funciona como esperado para a maioria.

Uma divulgação sobre uma das fontes. O usuário alchaplinsky, citado duas vezes aqui, é Alex Chaplinsky, que escreveu o texto ligado à thread e o submeteu ao Hacker News. Um comentarista de lá acusou Chaplinsky de montar um espantalho para vender um produto. Chaplinsky não respondeu à acusação na thread, e nós não a testamos. Testamos, sim, as duas afirmações técnicas de Chaplinsky que aparecem neste artigo, e as duas se sustentam.

Os comportamentos do Claude Code descritos vêm da documentação do próprio fabricante, lida em 12 de agosto de 2026, e não de teste nosso de cada checagem. Documentação pode ficar atrás do produto nos dois sentidos. Por fim, este artigo trata só de fronteira de isolamento. Se rodar muitos agentes em paralelo é uma boa ideia é outra pergunta, e a respondemos com menos confiança em quantos agentes de IA dá para rodar em paralelo.