Verificar a tag Git leva ao "estado HEAD desanexado"

166

Estou desenvolvendo um script de implantação para o meu projeto git e comecei a usar tags. Adicionei uma nova tag chamada v2.0:

git tag -a v2.0 -m "Launching version 2.0"

E eu empurrei essa tag para o repositório remoto

git push --tags

Quando tento executar o script de implantação e verificar a v2.0tag, recebo esta mensagem:

Você está no estado 'CABEÇA desanexada'. Você pode olhar em volta, fazer alterações experimentais e confirmá-las, além de poder descartar quaisquer confirmações feitas nesse estado sem impactar nenhuma ramificação executando outro checkout. Se você deseja criar uma nova ramificação para reter confirmações criadas, faça isso (agora ou mais tarde) usando -b com o comando checkout novamente. Exemplo: git checkout -b new_branch_name HEAD agora está em

Isso é normal? O repositório está no limbo porque se eu fizer:

git branch

Eu recebo esta saída:

* (no branch)
  master

Desculpe se isso é óbvio, mas não consegui descobrir.

Khriz
fonte
Quando você diz "executar o script de implantação e verificar a v2.0", seu código se parece com "git checkout v2.0"? Estou tentando renovar meu script de lançamento e quando executo o "git checkout v2.0" da minha máquina de produção, recebo "erro: pathspec 'v2.0' não corresponde a nenhum arquivo conhecido pelo git." Mesmo que eu tenha executado, "git push origin --tags" na minha máquina local antes de fazer o "git checkout v2.0" na produção. Também tentei rodar "git pull - tags" e "git fetch - tags" na produção antes de chamar "git checkout v2.0" e isso também não funciona ... Eu ainda estou recebendo o erro. Alguma ideia?
31412 John Erck
3
Eu estava prestes a excluir o comentário acima, mas achei que mantê-lo poderia ajudar outra pessoa. Eu estava recebendo o erro porque tinha um TYPO no nome da minha tag quando estava executando o "git checkout v2.0". No entanto, o erro relacionado ao erro de digitação é exatamente o mesmo erro que ocorrerá se você executar "git checkout v2.0" SEM um erro de digitação ANTES de executar, "git fetch --tags". Então, finalmente, meu problema foi resolvido executando "git fetch --tags" ANTES de executar "git checkout v2.0" sem erros de digitação. Ufa!
31412 John Erck
Bom, sim, você precisa buscar --tags antes (ou git fetch que puxará tudo do controle remoto) para que o git possa verificar a tag. Desculpe, acabei de ver seu comentário hoje.
Khriz

Respostas:

429

Ok, primeiro alguns termos um pouco simplificados.

Em git, a tag(como muitas outras coisas) é o que se chama de arborizado . É uma maneira de se referir a um ponto na história do projeto. Treeishes podem ser uma tag, um commit, um especificador de data, um especificador ordinal ou muitas outras coisas.

Agora, a branché como uma tag, mas é móvel. Quando você está "em" uma ramificação e faz uma consolidação, a ramificação é movida para a nova consolidação que você fez, indicando sua posição atual.

Seu HEADponteiro é para um ramo que é considerado "atual". Geralmente, quando você clona um repositório, HEADaponta para o masterqual, por sua vez, aponta para um commit. Quando você faz algo assim git checkout experimental, alterna HEADpara apontar para o experimentalramo que pode apontar para um commit diferente.

Agora a explicação.

Quando você faz a git checkout v2.0, está alternando para uma confirmação que não é apontada por a branch. O HEADagora está "desanexado" e não está apontando para um ramo. Se você decidir fazer uma confirmação agora (como você pode), não há ponteiro de ramificação a ser atualizado para rastrear essa confirmação. Voltar para outro commit fará com que você perca esse novo commit que você fez. É isso que a mensagem está dizendo.

Normalmente, o que você pode fazer é dizer git checkout -b v2.0-fixes v2.0. Isso criará um novo ponteiro de ramificação no commit apontado pelo treeish v2.0(uma tag nesse caso) e depois mudará o seu HEADpara apontar para isso. Agora, se você fizer commits, será possível rastreá-los (usando o v2.0-fixesbranch) e você poderá trabalhar como faria normalmente. Não há nada de "errado" no que você fez, especialmente se você quiser apenas dar uma olhada no v2.0código. Se, no entanto, você quiser fazer as alterações que deseja rastrear, precisará de uma ramificação.

Você deve dedicar algum tempo para entender todo o modelo do DAG do git. É surpreendentemente simples e deixa todos os comandos bem claros.

Noufal Ibrahim
fonte
Ok obrigado, não preciso fazer nenhuma alteração no código, então acho que está tudo bem. Não preciso criar um ramo. Muito obrigado!
Khriz
1
Perdi-me na primeira vez em que examinei esta resposta, mas depois de ler a documentação de ramificação do Git: http://git-scm.com/book/en/Git-Branching-What-a-Branch-É muito mais claro .
mark stiles
3
Resposta impressionante, mas devo acrescentar a respeito: "Voltar para outro commit fará com que você perca esse novo commit que você fez." - você ainda pode encontrar o commit git reflog, que é um ótimo comando para se conhecer! A menos que a coleta de lixo tenha acontecido, é aparentemente "impossível" perder uma confirmação.
Dmitry Minkovsky
As confirmações não referenciadas podem ser perdidas por uma operação de coleta de lixo.
Noufal Ibrahim 29/08
1
O URL está errado porque eles mudaram o layout da página.
Jcubic
12

Sim, é normal. Isso ocorre porque você faz check-out de um único commit, que não tem cabeça. Especialmente (mais cedo ou mais tarde) não é chefe de nenhum ramo.

Mas geralmente não há problema com esse estado. Você pode criar uma nova ramificação a partir da tag, se isso fizer você se sentir mais seguro :)

KingCrunch
fonte
1
Ok, eu vou mantê-lo assim ... segurança é avaliada em excesso de qualquer maneira;)
Khriz
Como você comentou na resposta de Noufals (é a melhor, devo dizer;)): Desde que você não mude nada, não há com o que se preocupar. No entanto, se você assumir que pode mudar alguma coisa, basta criar uma ramificação, porque ela é barata no git e você pode excluí-la (e recriar mais tarde e assim por diante).
KingCrunch