Detached HEAD
Entenda o estado detached HEAD do Git — o que significa, por que acontece, como manter o trabalho feito nele e como voltar a um branch.
Definição
Um detached HEAD ocorre quando o HEAD aponta diretamente para um commit em vez de apontar para um branch. Normalmente, o HEAD referencia o nome de um branch (como main), e esse branch aponta para o commit mais recente — assim, ao fazer um commit, o branch avança junto com você. No estado de detached HEAD, essa cadeia é quebrada: o HEAD fica em um commit específico sem nenhum branch para carregar os novos commits.
Como o HEAD normalmente funciona
O HEAD é uma referência que diz ao Git "onde você está agora." No estado normal "anexado", as referências formam uma cadeia: HEAD → branch → commit. O HEAD não aponta diretamente para um commit — ele aponta para o nome de um branch, e esse branch aponta para o commit mais recente.
Quando você faz um novo commit, o Git avança o ponteiro do branch para o novo commit e, como o HEAD aponta para o branch, ele segue automaticamente. Seu histórico permanece ancorado a um branch com nome.
Você mesmo pode ver essa cadeia. O arquivo .git/HEAD contém uma referência simbólica:
cat .git/HEAD
# ref: refs/heads/main <- attached: HEAD points at a branchO que desanexa o HEAD
O HEAD é desanexado sempre que você faz checkout de algo que não é um branch — na maioria das vezes um commit específico, uma tag ou uma referência de rastreamento remoto:
git checkout a1b2c3d # a commit hash
git checkout v1.0.0 # a tag
git checkout origin/main # a remote-tracking ref
git switch --detach main # explicitly detach at main's tipO Git avisa quando isso acontece. A mensagem tem a seguinte aparência:
Note: switching to 'a1b2c3d'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.Após a desanexação, .git/HEAD não aponta mais para um branch — ele contém um hash de commit bruto:
cat .git/HEAD
# a1b2c3d4e5f6... <- detached: HEAD points at a commit directlyO comando
git checkouttem dupla função (alternar branches e mover o HEAD). Os capítulos mais recentes sobre git switch e git checkout explicam por que o Git separou essas funções.
Quando o detached HEAD é útil
Um detached HEAD não é um erro — é uma ferramenta normal. Você o usa deliberadamente quando quer inspecionar ou construir o histórico sem tocar em nenhum branch:
- Inspecionar uma versão antiga — faça checkout de um commit ou tag para ler o código como estava naquele momento.
- Construir ou testar uma versão antiga — faça checkout de
v1.0.0, execute o build e depois volte ao seu branch. - Bissetar um bug —
git bisectfaz checkout de commits em um detached HEAD enquanto procura o commit que introduziu um bug. - Experimentar sem comprometer — faça alguns commits experimentais, decida que foram um beco sem saída e saia sem deixar um branch para trás.
Por que isso importa
Olhar ao redor em um detached HEAD é totalmente seguro — esse é o seu objetivo. O perigo aparece apenas quando você faz commits lá. Como nenhum branch está rastreando seu trabalho, esses novos commits só são acessíveis através do próprio HEAD. No momento em que você muda para outro branch, o HEAD avança e nada aponta para os commits que você fez. Eles ficam "soltos": ainda estão no repositório por um tempo, mas sem nenhuma referência mantendo-os, e eventualmente são removidos pela coleta de lixo.
A correção é simples — dê um nome a esses commits antes de sair.
Preservando o trabalho feito em um detached HEAD
Se você fez commits em um detached HEAD e quer mantê-los, crie um branch antes de sair. Isso ancora os commits a um nome:
git switch -c my-rescued-workSeus commits desanexados agora vivem no novo branch, seguros e acessíveis. O equivalente com o comando mais antigo é git checkout -b my-rescued-work.
Um passo a passo completo
Aqui está o ciclo completo — desanexar, fazer commit e depois salvar o trabalho:
git checkout a1b2c3d # detach HEAD onto an old commit
# ... edit files ...
git commit -am "Experiment" # commit lives only on HEAD now
git switch -c experiment # name it -> commit is now safe on a branch
git log --oneline experiment # the new commit is reachable by nameAssim que o branch existir, você pode fazer merge, rebase ou excluí-lo como qualquer outro branch.
Voltando ao normal
Para sair de um detached HEAD sem manter novos commits, basta mudar para um branch:
git switch mainSe você fez commits no estado desanexado, esqueceu de criar um branch e já mudou para outro lugar, não entre em pânico — o git reflog registra cada posição que o HEAD visitou, incluindo commits para os quais nenhum branch aponta. Encontre o hash do commit perdido lá e recupere-o em um novo branch:
git reflog
# a1b2c3d HEAD@{1}: commit: Experiment <- your lost commit
# 8120552 HEAD@{2}: checkout: moving from main to 8120552
git switch -c recovered a1b2c3dAs entradas do reflog expiram (90 dias por padrão para histórico acessível, 30 para inacessível), portanto recupere o quanto antes.
Tópicos relacionados
- git switch — a forma moderna e mais segura de mover entre branches.
- git checkout — o comando original que pode alternar branches e desanexar o
HEAD. - git branch — cria o branch que resgata o trabalho desanexado.
- git reflog — recupera commits depois que você já saiu de um detached HEAD.
- git tag — fazer checkout de uma tag é uma forma comum de entrar em um detached HEAD.