O que é HEAD no Git?

Respostas:

775

Você pode pensar no HEAD como o "ramo atual". Quando você alterna ramificações git checkout, a revisão HEAD muda para apontar para a ponta da nova ramificação.

Você pode ver o que o HEAD aponta, fazendo:

cat .git/HEAD

No meu caso, a saída é:

$ cat .git/HEAD
ref: refs/heads/master

É possível que o HEAD se refira a uma revisão específica que não esteja associada a um nome de filial. Essa situação é chamada de CABEÇA desanexada .

Greg Hewgill
fonte
53
Então, o git HEAD depende do contexto em qual FILIAL você está, correto? Ainda mais, você como desenvolvedor? Acho que estou perguntando: o Git HEAD será uma coisa global em todo o repositório ou individual para cada desenvolvedor?
22410 Bobobobo
91
@obobobo: Isso mesmo, HEAD é como um ponteiro que aponta para o ramo atual. Quando você faz check-out de um ramo diferente, o HEAD muda para apontar para o novo. O HEAD atual é local para cada repositório e, portanto, é individual para cada desenvolvedor.
Greg Hewgill
16
@Meng Este ajudou-me, espero que ajude: marklodato.github.com/visual-git-guide/index-en.html
raphael
54
@ 動靜 能量: HEAD pode apontar para qualquer confirmação, não precisa ser a última confirmação em nenhum ramo. (Quando HEAD aponta para um commit que não é o último commit em uma ramificação, é um "HEAD desanexado").
Greg Hewgill 30/08/2012
127
HEAD não é "o ramo atual". Is é o nome dado ao commit a partir do qual o estado atual da árvore de trabalho foi inicializado. Em termos mais práticos, pode ser pensado como uma referência simbólica ao commit do check-out.
Ben Collins
184

Para citar outras pessoas :

Uma cabeça é simplesmente uma referência a um objeto de confirmação. Cada cabeça tem um nome (nome da filial ou nome da etiqueta, etc.). Por padrão, existe um cabeçalho em cada repositório chamado master. Um repositório pode conter qualquer número de cabeças. A qualquer momento, um cabeçote é selecionado como o "cabeçote atual". Esta cabeça é alias à HEAD, sempre em maiúsculas ".

Observe esta diferença: uma “cabeça” (minúscula) refere-se a qualquer uma das cabeças nomeadas no repositório; "CABEÇA" (maiúscula) refere-se exclusivamente à cabeça atualmente ativa. Essa distinção é usada frequentemente na documentação do Git.

Outra boa fonte que cobre rapidamente o funcionamento interno do git (e, portanto, uma melhor compreensão das cabeças / HEAD) pode ser encontrada aqui . Referências (ref :) ou cabeças ou ramificações podem ser consideradas como post-its colados em confirmações no histórico de confirmação. Geralmente eles apontam para a ponta da série de confirmações, mas podem ser movidos com git checkoutou git resetetc.

Silfheed
fonte
Disto: "Cada cabeça tem um nome". E "uma cabeça é selecionada como a" cabeça atual ". Esta cabeça é alias para HEAD ". Portanto, concluo disso que "HEAD" não se refere à situação do estado "desanexado HEAD".
Gddd 27/12/15
1
@ gxyd se for o caso em que HEAD não aponta para uma 'cabeça', é uma HEAD separada. Ele está apontando para o ID de confirmação que você especificou (usando, por exemplo git checkout HEAD~2), que não é o ID de confirmação de um cabeçalho conhecido. Veja o artigo em eagain.net/articles/git-for-computer-scientists para uma explicação mais completa.
Silfheed 5/01/16
1
@ Silfheed: Geralmente eu acho que essa resposta é conceitualmente mais sólida do que a aceita (embora o uso de "head" em minúsculas para se referir a um ramo confunda muitas pessoas). No entanto, git revertnão é um bom exemplo de mover uma ramificação para não ficar na ponta, porque git revertapenas cria algumas novas confirmações e ainda deixa a ramificação atual na (nova) dica.
Larsh
1
"que não é o ID de confirmação de uma cabeça conhecida" - Na verdade, um HEAD desanexado pode estar apontando para um ID de confirmação, que também é o ID de confirmação de uma cabeça conhecida (ou várias cabeças). O que o torna desanexado é que o HEAD está apontando diretamente para o ID de confirmação, não para uma cabeça. Isso afetará o comportamento de futuros commits, resets etc.
LarsH
1
@ LarsH: bom argumento em um HEAD desanexado apontando para um ID de confirmação em vez de uma referência. Você pode realmente verificar isso olhando para .git / HEAD. Se for desanexado, ele conterá o hash de uma confirmação, mesmo que seja a mesma confirmação que um cabeçalho conhecido. Se estiver anexado, conterá o caminho para a cabeça (ou seja, 'ref: refs / heads / bob'). Quanto ao comando de reversão, depois de 8 anos eu nunca peguei esse erro de digitação. Git reset é o que permite ajustar um cabeçalho específico para apontar para um commit específico.
Silfheed
62

Eu recomendo esta definição do desenvolvedor do github Scott Chacon [ referência de vídeo ]:

Head é o seu ramo atual. É uma referência simbólica. É uma referência a um ramo. Você sempre tem HEAD, mas HEAD estará apontando para um desses outros ponteiros, para um dos ramos em que você está. É o pai do seu próximo commit. É o que deveria ser o último check-out no seu diretório de trabalho ... Esse é o último estado conhecido do diretório de trabalho.

O vídeo inteiro apresentará uma introdução justa a todo o sistema git, então eu também recomendo que você assista tudo, se tiver tempo.

jasoares
fonte
34
Portanto, o verdadeiro def é "o pai do seu próximo cometem"
nicolas
1
e também "a coisa que aponta para o próximo ramo que se moverá"
nicolas
@nicolas - Eu não acho que que isso seja verdade. O HEAD pode apontar para qualquer confirmação, não necessariamente precisa apontar para uma ramificação - quando não, você está no modo "desanexado HEAD".
amigos estão dizendo sobre scubbo
23
O vídeo é ótimo, mas, infelizmente, é uma resposta inadequada para o Stack Overflow. E se o vídeo for retirado em algum momento no futuro? Então seu link não apontará para nada. Uma resposta melhor incluiria uma transcrição do que Scott diz no vídeo.
2
Scott diz que HEAD é um ponteiro para um galho. Mas o HEAD também pode apontar para confirmações antigas. Isso é tão confuso.
Fixee
60

HEAD é apenas um ponteiro especial que aponta para o ramo local em que você está atualmente.

No livro Pro Git , capítulo 3.1 Ramificação Git - Ramificações em poucas palavras , na seção Criando uma nova ramificação :

O que acontece se você criar uma nova ramificação? Bem, isso cria um novo ponteiro para você se movimentar. Digamos que você crie um novo ramo chamado testing. Você faz isso com o comando git branch:

$ git branch testing 

Isso cria um novo ponteiro no mesmo commit em que você está atualmente

insira a descrição da imagem aqui

Como o Git sabe em qual filial você está atualmente? Ele mantém um ponteiro especial chamado HEAD. Note que isso é muito diferente do conceito de HEAD em outros VCSs aos quais você pode estar acostumado, como Subversion ou CVS. No Git, este é um ponteiro para o ramo local em que você está atualmente. Nesse caso, você ainda está no mestre. O comando git branch criou apenas uma nova ramificação - não mudou para essa ramificação.

insira a descrição da imagem aqui

Alexandr
fonte
4
Bom, poderia usar uma foto mostrando o caso CABEÇA destacada embora
Don escotilha
@DonHatch, Boa explicação da cabeça destacada stackoverflow.com/a/35301963/1074179
Alexandr
3
Boa resposta. As ramificações não passam de confirmações rotuladas. Quando você faz novas confirmações, esse rótulo é movido para a nova nova confirmação. Quando você faz check-out de um commit que não possui um rótulo, ele fica no estado HEAD desanexado. Isso significa que HEAD está apontando para um commit que não possui um rótulo de ramificação. Se você fez o checkout 34ac2no exemplo acima, agora o HEAD estaria apontando para esse commit e é chamado de HEAD desanexado. Nesse estado, você também pode fazer alterações, experimentar e confirmar alterações, mas, ao fazer check-out de uma ramificação diferente, você perderá todas as alterações, a menos que, é claro, crie uma nova ramificação.
sleepwalkerfx
1
@sleepwalkerfx, mas você pode fazer o checkout de um commit que tem um rótulo de filial e ainda estar no estado de cabeça desanexada porque seu HEAD não está mais apontando para o rótulo do ramo, mas o ID de confirmação do ramo
Marc
1
@sleepwalkerfx Acho que estamos falando de semântica neste momento. Você está certo de que um rótulo de ramificação é uma referência de texto a um commit específico. No entanto, não é um commit. Portanto, se você fez um git loge obteve algo parecido, commit ad0265... HEAD -> foo ...isso significa que o fooramo é uma referência para confirmar o ID ad0265. Fazer um check-out da referência de texto foonão é uma cabeça separada. Fazer um checkout do ID de confirmação ad0265resultaria em um cabeçalho desanexado. Pode estar faltando alguma sutileza do que você está se comunicando. Espero que este mural de texto ajude a descobrir onde estou perdido.
Marc
40

Supondo que não seja um caso especial chamado "HEAD destacado", então, como afirmado no livro O'Reilly Git, 2ª edição, p.69, HEADsignifica:

HEADsempre se refere à confirmação mais recente na ramificação atual. Quando você altera ramificações, HEADé atualizado para se referir à confirmação mais recente da nova ramificação.

tão

HEADé a "dica" do ramo atual .

Observe que podemos usar HEADa referência ao commit mais recente e usá-lo HEAD~como commit antes da dica e / HEAD~~ou HEAD~2como commit ainda mais cedo, e assim por diante.

falta de polaridade
fonte
27

Há um equívoco, talvez sutil, mas importante em várias respostas. Pensei em adicionar minha resposta para esclarecê-la.

O que é HEAD?

A CABEÇA É VOCÊ

HEADé uma referência simbólica que aponta para onde você estiver no seu histórico de consolidação. Ele te segue onde quer que você vá, faça o que fizer, como uma sombra. Se você fizer um commit, HEADserá movido. Se você fizer o pagamento, algo HEADserá movido. O que você fizer, se você se mudou para algum lugar novo no seu histórico de consolidação, HEADfoi junto com você. Para resolver um equívoco comum: você não pode se desanexar deHEAD . Não é isso que é um estado HEAD desanexado. Se você se perguntar: "oh não, estou desapegado do CABEÇOTE! Perdi o CABEÇOTE!" Lembre-se, é a sua cabeça. CABEÇA é você. Você não se separou do HEAD, você e seu HEAD se separaram de outra coisa.

O que o HEAD pode anexar?

HEADpode apontar para um commit, sim, mas normalmente não. Deixe-me dizer isso de novo. Normalmente HEADnão aponta para uma confirmação. Aponta para uma referência de ramificação. Ele está anexado a esse ramo e, quando você faz certas coisas (por exemplo, commitou reset), o ramo anexado se move junto HEAD. Você pode ver o que ele aponta apontando para baixo do capô.

cat .git/HEAD

Normalmente você terá algo parecido com isto:

ref: refs/heads/master

Às vezes, você terá algo parecido com isto:

a3c485d9688e3c6bc14b06ca1529f0e78edd3f86

É o que acontece quando HEADaponta diretamente para um commit. Isso é chamado de HEAD desanexado, porque HEADestá apontando para algo diferente de uma referência de ramificação. Se você fizer uma confirmação nesse estado, masternão HEADestará mais anexado a , não se moverá mais com você. Não importa onde está o commit. Você pode estar no mesmo commit que seu branch master, mas se HEADestiver apontando para o commit e não para o branch, ele será desanexado e um novo commit não será associado a uma referência do branch.

Você pode ver isso graficamente se tentar o seguinte exercício. Em um repositório git, execute isso. Você terá algo um pouco diferente, mas os bits principais estarão lá. Quando chegar a hora de efetuar o checkout do commit diretamente, use qualquer hash abreviado que você obtiver da primeira saída (aqui está a3c485d).

git checkout master
git log --pretty=format:"%h:  %d" -1
# a3c485d:   (HEAD -> master)

git checkout a3c485d -q # (-q is for dramatic effect)
git log --pretty=format:"%h:  %d" -1   
# a3c485d:   (HEAD, master)

OK, então há uma pequena diferença na saída aqui. Verificar o commit diretamente (em vez do ramo) nos dá uma vírgula em vez de uma flecha. O que você acha, estamos em um estado HEAD desapegado? HEAD ainda está se referindo a uma revisão específica associada a um nome de filial. Ainda estamos no ramo principal, não estamos?

Agora tente:

git status
# HEAD detached at a3c485d

Não. Estamos no estado 'desapegado da CABEÇA'.

Você pode ver a mesma representação de (HEAD -> branch)vs. (HEAD, branch)com git log -1.

Em conclusão

HEADé você. Aponta para o que você fez check-out, onde quer que esteja. Normalmente, isso não é um commit, é um ramo. Se HEAD não apontam para um commit (ou tag), mesmo que seja o mesmo commit (ou tag) que um ramo também aponta para, você (e HEAD) tenham sido destacadas daquele ramo. Como você não tem um ramo anexado a você, o ramo não o acompanhará à medida que você faz novos commit. HEAD, no entanto, vontade.

De novo
fonte
1
Gosto dessa resposta, porque, embora a documentação descreva a verdade, o software define a verdade. .git/HEADé o que o software considera HEAD.
Don Branson
2
Apenas para sua definição conceitual, essa deve ser a resposta aceita.
ata
22

HEADrefere-se ao commit atual para o qual sua cópia de trabalho aponta, ou seja, o commit que você fez check-out no momento. Na documentação oficial do Linux Kernel sobre a especificação de revisões do Git :

HEAD nomeia o commit no qual você baseou as alterações na árvore de trabalho.

Observe, no entanto, que na próxima versão 1.8.4 do Git, @também pode ser usado como uma abreviação para HEAD, como observado pelo colaborador do Git Junio ​​C Hamano em seu blog Git Blame :

Em vez de digitar "HEAD", você pode dizer "@", por exemplo, "git log @".

O usuário do Stack Overflow VonC também encontrou algumas informações interessantes sobre por que @foi escolhido como uma abreviação em sua resposta a outra pergunta .

Também é interessante, em alguns ambientes, não é necessário capitalizar HEAD, especificamente em sistemas operacionais que usam sistemas de arquivos que não diferenciam maiúsculas de minúsculas, especificamente Windows e OS X.

Comunidade
fonte
17

Dê uma olhada em Criando e brincando com ramificações

HEAD é na verdade um arquivo cujo conteúdo determina aonde a variável HEAD se refere:

$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed

Neste repositório, o conteúdo do arquivo HEAD se refere a um segundo arquivo chamado refs / heads / master . O arquivo refs / heads / master contém o hash do commit mais recente na ramificação master.

O resultado são pontos HEAD para a consolidação da ramificação mestre a partir do arquivo .git / refs / heads / master .

insira a descrição da imagem aqui

onmyway133
fonte
1
Cuidado: o link gitguys.com parece apontar para um domínio estacionado.
MKesper
14

Gostaria apenas de detalhar algumas coisas na resposta aceita por Greg Hewgil. De acordo com o Git Pocket Guide

Ramo:

o próprio ramo é definido como todos os pontos alcançáveis ​​no gráfico de consolidação a partir do commit nomeado (a "dica" do ramo).

CABEÇA: Um tipo especial de referência

A referência especial HEAD determina em que ramo você está ...

Refs

O Git define dois tipos de referências, ou ponteiros nomeados, que ele chama de "refs":

  • Uma referência simples, que aponta diretamente para um ID de objeto (geralmente uma confirmação ou tag)
  • Um ref simbólico (ou symref), que aponta para outro ref (simples ou simbólico)

Como Greg mencionou, o HEAD pode estar em um "estado desanexado". Portanto, HEAD pode ser uma ref simples (para um HEAD desanexado) ou um symref.

se HEAD for uma referência simbólica para um ramo existente, você estará "ligado" nesse ramo. Se, por outro lado, HEAD é um ref simples nomeando diretamente um commit pelo seu ID SHA-1, você não está "em" nenhuma ramificação, mas no modo "desanexado HEAD", o que acontece quando você faz check-out anteriormente. comprometer-se a examinar.

Mike
fonte
Obrigado, @mike! Esta é a primeira resposta que esclarece o que acontece quando você faz check-out de um commit anterior. Olhando para o livro no site git, tive a impressão de que um "HEAD destacado" era um estado patológico em que você só entrava se fazia alguma coisa estranha de reprovação. Mas verificar uma confirmação anterior não é uma coisa estranha a se fazer, e quando você faz isso, HEAD não é "a ponta da ramificação atual". Então esta é a primeira vez que sinto que realmente entendo.
Nat Kuhn
7

Eu acho que 'HEAD' é atual check out commit. Em outras palavras, 'HEAD' aponta para o commit que está atualmente com check-out.

Se você acabou de clonar e não fez check-out, não sei para onde ele aponta, provavelmente algum local inválido.

Nataraj
fonte
Sim, a referência especial HEADé qualquer confirmação que você fez no check-out. Consulte o manual para obter detalhes (o parágrafo relevante segue imediatamente a Fig 3.4).
Calrion # 31/12
1
Se você clonar um repositório, o git, por padrão, verificará a masterramificação - então o HEAD apontará para o master.
sleske
1
@sleske se você clonar um repositório sem opções especiais, o git verificará o cabeçote remoto. geralmente é master, mas nem sempre é. Vejaremote set-head
De Novo
Meu comentário anterior estava correto, exceto pela referência a remote set-head, que afeta apenas a ramificação padrão local e não altera o padrão no servidor.
De Novo
5

A cabeça aponta para a ponta do ramo atualmente com check-out.

insira a descrição da imagem aqui

No seu repositório, há uma pasta .git. Abra o arquivo neste local: .git \ refs \ heads. O código (sha-1 hash) nesse arquivo (mestre na maioria dos casos) será o commit mais recente, ou seja, o visto na saída do comandogit log . Mais informações sobre a pasta .git: http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html

stack1
fonte
1
É um equívoco comum que a ponta do ramo atual aponte para o commit mais recente. Normalmente, isso é verdade, mas também não é incomum git reset HEAD^, e o commit mais recente (a dica anterior) não é mais apontado pela ponta do ramo.
Larsh
4

Uma ótima maneira de levar para casa o que foi dito nas respostas corretas é seguir em frente git reflog HEAD. Você obtém um histórico de todos os lugares apontados pela HEAD.

tjb
fonte
4

Depois de ler todas as respostas anteriores, eu ainda queria mais clareza. Este blog no site oficial do git http://git-scm.com/blog me deu o que eu estava procurando:

O HEAD: Ponteiro para o último instantâneo de confirmação, próximo pai

O HEAD no Git é o ponteiro para a referência de ramificação atual, que por sua vez é um ponteiro para a última confirmação que você fez ou a última confirmação que foi registrada no diretório de trabalho. Isso também significa que será o pai do próximo commit que você fizer. Geralmente é mais simples pensar nisso como HEAD é o instantâneo do seu último commit.

user3751385
fonte
1
O instantâneo HEAD: último commit, o próximo pai não é preciso. HEADnão é um commit; que aponta para um.
Jub0bs 26/09/14
Não há necessidade de sarcasmo; antes da sua edição, apesar de a citação ser precisa, as grandes letras em negrito eram uma simplificação e um pouco enganosas. Agora está melhor.
Jb0bs 27/09/14
1
SE você ler a próxima linha: O HEAD no Git é o ponteiro para a referência de ramificação atual, que por sua vez é um ponteiro para o último commit que você fez ou o último commit que foi verificado no seu diretório de trabalho. - Observe o uso da palavra "ponteiro" lá.
user3751385
Embora a descrição do "último instantâneo de confirmação" dê uma idéia conceitual de como o HEAD normalmente deve ser usado, ele não é realmente preciso. Se eu fizer uma confirmação, mude para outra ramificação, HEAD não apontará mais para o último instantâneo de confirmação. Aponta para o último instantâneo de confirmação na ramificação para a qual eu mudei. Se eu checkout HEAD^, agora o HEAD nem sequer aponta para o último instantâneo de confirmação em qualquer ramificação.
Larsh
"O pai do seu próximo commit (se você fosse o commit agora)" é mais preciso, mas existem muitas outras operações no git além do commit que são afetadas pelo HEAD. Realmente, no final, HEAD é HEAD, e sua natureza é definida por como ela afeta comandos como commit, merge, rebase, log, etc. Mas conceitualmente talvez "(ponteiro para) a posição atual" é um resumo bom.
Larsh
3

Parece que HEADé apenas uma tag para o último commit que você fez check-out.

Pode ser a dica de uma ramificação específica (como "mestre") ou alguma confirmação intermediária de uma ramificação ("cabeça desanexada")

Vertexwahn
fonte
1

Além de todas as definições, o que ficou em minha mente foi que, quando você faz uma confirmação, o GIT cria um objeto de confirmação no repositório. Os objetos de confirmação devem ter um pai (ou vários pais, se for um commit de mesclagem). Agora, como o git conhece o pai do commit atual? Portanto, HEAD é um ponteiro para a (última referência) última confirmação que se tornará o pai da confirmação atual.

Anwar Husain
fonte
0

Estes dois podem confundir você:

cabeça

Apontar para referências nomeadas que um ramo enviou recentemente. A menos que você use a referência do pacote, os cabeçotes geralmente são armazenados em $ GIT_DIR / refs / heads /.

CABEÇA

A ramificação atual ou sua árvore de trabalho geralmente é gerada a partir da árvore que HEAD está apontando. O HEAD deve apontar para uma cabeça, exceto se você estiver usando um HEAD desanexado.

Marcus Thornton
fonte
0

Dê uma olhada em http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is

Figura 3-5. Arquivo HEAD apontando para o ramo em que você está.

Ting Wang
fonte
4
As respostas apenas para links geralmente são desaprovadas no Stackoverflow, inclua as informações relevantes em sua resposta.
HaskellElephant
2
Isso não está totalmente correto. O que HEADse refere depende se você está falando de um repo bare contra um non-bare. No contexto de um repositório não-bare, refere-se efetivamente ao commit atualmente com check-out, o que não exige que haja um ramo anexado a ele (ou seja, quando no HEADestado desconectado ).
0

Uma ramificação é na verdade um ponteiro que contém um ID de confirmação como 17a5 . HEAD é um ponteiro para um ramo no qual o usuário está trabalhando no momento.

HEAD tem um arquivo de referência que se parece com isso:

ref:

Você pode verificar esses arquivos acessando o .git/HEAD .git/refsque está no repositório em que está trabalhando.

Okd
fonte
0

Gité tudo sobre confirmações.
E Headaponta para o commit que você fez check-out no momento.

$ git cat-file -t HEAD
commit

Sempre que você faz check-out de uma ramificação, o HEAD aponta para a confirmação mais recente nessa ramificação. O conteúdo do HEAD pode ser verificado como abaixo (para ramificação mestre):

$ cat .git/refs/heads/master
  b089141cc8a7d89d606b2f7c15bfdc48640a8e25
SR Chaitanya
fonte
-5

Como conceito, a cabeça é a revisão mais recente em um ramo. Se você tiver mais de um cabeçalho por ramificação nomeada, provavelmente a criou ao realizar confirmações locais sem mesclar, criando efetivamente uma ramificação sem nome.

Para ter um repositório "limpo", você deve ter um cabeçalho por ramificação nomeada e sempre mesclar a uma ramificação nomeada depois de trabalhar localmente.

Isso também é verdade para o Mercurial .

dukeofgaming
fonte
4
Isso é verdade para o Mercurial, mas não para o Git.
Reintegrar Monica - notmaynard