Por que "origin / HEAD" é exibido ao executar o "git branch -r"?

160

Quando você corre, git branch -rpor que os incêndios são listados origin/HEAD? Por exemplo, há um repositório remoto no GitHub, digamos, com dois ramos: mestre e recurso impressionante. Se eu fizer git cloneisso, pegue no meu novo diretório e liste os ramos, vejo o seguinte:

$ git branch -r
origin/HEAD
origin/master
origin/awesome-feature

Ou em qualquer ordem em que esteja (alfa? Estou fingindo este exemplo para manter em segredo a identidade de um repo inocente). Então, qual é o problema HEAD? É o que a última pessoa a pushteve sua HEADpontas em quando empurrado? Isso não será sempre o que quer que eles sejam push? HEADs se movimentam ... por que eu me importo com o que alguém HEADapontou em outra máquina?

Eu só estou entendendo o rastreamento remoto e tal, então essa é uma confusão persistente. Obrigado!

EDIT: Eu tive a impressão de que repositórios remotos dedicados (como o GitHub, onde ninguém trabalha com ssh e trabalha nesse código, mas apenas puxa ou empurra, etc.) não tinham e não deveriam ter um HEAD, porque havia, basicamente, nenhuma cópia de trabalho. Não tão?

Ben Hamill
fonte

Respostas:

140

@robinst está correto.

No git, você pode selecionar qual ramificação é retirada por padrão (ou seja, quando você clona). Por padrão, origin/HEADapontará para isso.

No GitHub, você pode alterar isso nas configurações de administrador do seu repositório do GitHub. Você também pode fazer isso na linha de comando, via

git remote set-head origin trunk

ou exclua-o completamente via

git remote set-head origin -d

Exemplo . Veja o menu suspenso "Alternar ramos". trunkestá marcado, a origin/HEADseguir trunk.

cdunn2001
fonte
Renomeei o nome de outro controle remoto origine otherremote/HEAD -> masterestava me incomodando. Executar seu comando corrigiu isso para mim.
Felipe Alvarez
59

A razão pela qual um repositório simples pode ter um HEAD é porque ele determina qual ramificação é inicialmente retirada após um clone do repositório.

Normalmente, o HEAD aponta para mestre, e esse é o ramo que é retirado quando as pessoas clonam o repositório. Configurá-lo para outra ramificação (editando HEAD no repositório vazio) resulta no check-out dessa ramificação no clone.

robinst
fonte
2
Como é possível remover esta referência sem pressionar, origin/HEADuma referência local está correta? Removê-lo tem algum efeito origin?
Zach Posten
@zposten: Não, da mesma forma que a exclusão origin/masternão afeta o controle remoto.
robinst
Isso significa que, após a clonagem, a referência é apenas uma informação inútil.
Bachsau 17/06/19
@Bachsau a referência não é clonada.
robinst 01/07/19
27

Fiquei com a impressão de que repositórios remotos dedicados (como o GitHub, onde ninguém trabalha com ssh e trabalha nesse código, mas apenas puxa ou empurra, etc.) não tinham e não deveriam ter um HEAD, porque basicamente não havia trabalho. cópia de. Não tão?

Eu tive exatamente a mesma impressão como você disse.

E eu nem consigo excluir esse ramo de rastreamento remoto de origem / HEAD clonado no github fazendo

git branch -d -r origin/HEAD

Isso não teve efeito.

Alguém pode me dizer como posso excluir essa ramificação de rastreamento remoto de origem / HEAD?

atualizar

Embora eu não tenha descoberto por que existe uma origem / HEAD criada ao clonar no github, acho uma maneira de excluí-lo.

A nova versão do git fornece

git remote set-head <name> -d

para excluir o ponteiro inútil HEAD da ramificação de rastreamento remoto.

E também podemos alterar o nome padrão idiota 'origem' para o que quisermos usando

git remote rename origin <new_name>

Espero que isso possa ajudar. :)

boblu
fonte
Estou tendo o mesmo problema (no GitHub, mesmo), e o set-head não funcionou. Devo estar executando o 'git remote set-head HEAD -d'?
Joost Schuur
5
@Joost: it'sgit remote set-head origin -d
znq 15/03
13

Você está certo de que o envio para repositórios remotos dedicados funciona muito melhor quando estão "vazios", ou seja, quando eles não têm diretórios de trabalho. A arquitetura do Git é projetada para atualização por patches ou pull( fetch), o que faz sentido em um VCS distribuído. Como os documentos dizem em algum lugar, enviar para uma ramificação que está com check-out atualmente pode resultar em "resultados inesperados" .

O HEAD faz parte dos requisitos para um repositório válido. O Layout do Repositório Git diz, em parte:

HEAD

A symref (see glossary) to the refs/heads/ namespace describing the currently active  
branch. It does not mean much if the repository is not associated with any working tree  
(i.e. a bare repository), but a valid git repository must have the HEAD file; some  
porcelains may use it to guess the designated "default" branch of the repository  
(usually master). It is legal if the named branch name does not (yet) exist.

Então você verá HEAD como parte da lista de ramificações, mesmo que "isso não signifique muito ..."

Paulo
fonte
Isso não faz sentido. Os repositórios começam vazios, mas no minuto em que você envia algo a eles, eles não ficam mais vazios e, se você executar o "git branch" neles, eles mostrarão um branch atualmente com check-out.
Geoidesic
@geoidesic Um repositório pode estar vazio, mesmo se você o tiver pressionado. O seguinte: mkdir foobar; cd foobar; git init --bare; cd ..; git clone foobar foobar_clone; cd foobar_clone; touch file; git add file; git config --global user.email "[email protected]"; git config --global user.name "Your Name"; git commit -m "test"; git push origin master; cd ..; cd foobar; git config core.bareoutput true. Também não há cópia de trabalho do arquivo enviado no repositório foobar sobre esses comandos.
Anders Lindén
@geoidesic Um repositório pode estar vazio, mesmo se você o tiver pressionado. O seguinte: mkdir foobar; cd foobar; git init --bare; cd ..; git clone foobar foobar_clone; cd foobar_clone; touch file; git add file; git config user.email "[email protected]"; git config user.name "Your Name"; git commit -m "test"; git push origin master; cd ..; cd foobar; git config core.bareoutput true. Também não há cópia de trabalho do arquivo enviado no repositório foobar sobre esses comandos.
Anders Lindén
@geoidesic Um repositório git --bare significa apenas um repositório sem árvore de trabalho, ou seja, um repositório que contém apenas um diretório .git, mas não pode ter arquivos com check-out. Como ele não pode ter arquivos com check-out, na verdade nem sequer possui um diretório .git, apenas coloca todos os arquivos .git diretamente no diretório principal. Crie um e você verá!
00prometheus 26/06
5

Se "origin" for um repositório remoto, origin / HEAD identifica a ramificação padrão nesse repositório remoto.

Exemplo:

$ git remote show
origin
$ git remote show origin
* remote origin
  Fetch URL: [email protected]:walkerh/pipe-o-matic.git
  Push  URL: [email protected]:walkerh/pipe-o-matic.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (fast-forwardable)

Observe a linha que diz "HEAD branch: master". É aqui que o repositório remoto permite que os clientes saibam qual filial efetuar check-out por padrão.

Walker Hale IV
fonte
1

Sempre há um HEAD que aponta para a ramificação com check-out atualmente no repositório remoto (que pode ou não ser mestre). Mesmo repositórios remotos têm ramificações atuais. Geralmente é mestre, e de cabeça para baixo não consigo pensar em nenhuma razão para alguém querer mudar isso, mas pode ser mudado.

codelogic
fonte
2
Os repositórios do github não têm ramificações em check-out. Não vejo por que isso se aplicaria.
217 Dustin
Repositórios remotos NÃO devem ter um diretório ativo. Os repositórios remotos devem ser --bare e, portanto, não podem ter uma ramificação com check-out no momento.
N4rzul 01/12/2015
-14

Meu palpite é que alguém empurrou um galho e chamou HEAD:

git push origin HEAD
Dustin
fonte
Posso receber alguns comentários sobre o que há de errado nisso? Se você quer uma origem / HEAD no github, é a única maneira que eu sei para chegar lá.
217 Dustin
O HEAD remoto é uma referência simbólica (geralmente para refs / heads / master). Você substituirá a referência simbólica pelo hash id do commit da sua ramificação atual.
1011 Daniel Fanjul
2
As suposições não devem ser discutidas nos comentários, em vez de serem uma resposta imprecisa?
Luciano