Pourquoi «origin / HEAD» est-il affiché lors de l'exécution de «git branch -r»?

160

Quand vous exécutez, git branch -rpourquoi les flammes listent-elles origin/HEAD? Par exemple, il existe un dépôt distant sur GitHub, disons, avec deux branches: master et awesome-feature. Si je le git clonesaisis et que j'entre dans mon nouveau répertoire et que je répertorie les branches, je vois ceci:

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

Ou quel que soit l'ordre dans lequel il se trouverait (alpha? Je simule cet exemple pour garder secrète l'identité d'un repo innocent). Alors, quel est le HEADproblème? Est-ce ce que la dernière personne à pushavoir HEADpointé quand ils ont poussé? N'est-ce pas toujours ce qu'ils ont été push? HEADs se déplacer ... pourquoi est-ce que je me soucie de ce que quelqu'un a HEADpointé sur une autre machine?

Je suis juste en train de comprendre le suivi à distance et autres, c'est donc une confusion persistante. Merci!

EDIT: J'avais l'impression que les dépôts distants dédiés (comme GitHub où personne ne va ssh et travailler sur ce code, mais seulement tirer ou pousser, etc.) n'avaient pas et ne devraient pas avoir de HEAD parce qu'il y avait, fondamentalement, pas de copie de travail. Non?

Ben Hamill
la source

Réponses:

140

@robinst est correct.

Dans git, vous pouvez sélectionner quelle branche est extraite par défaut (c'est-à-dire lorsque vous clonez). Par défaut, origin/HEADpointera vers cela.

Sur GitHub, vous pouvez modifier cela dans les paramètres d'administration de votre dépôt GitHub. Vous pouvez également le faire à partir de la ligne de commande via

git remote set-head origin trunk

ou supprimez-le complètement via

git remote set-head origin -d

Exemple . Regardez la liste déroulante «Changer de branche». trunkest vérifié, donc origin/HEADsuit trunk.

cdunn2001
la source
J'ai renommé une autre télécommande pour être originet ma otherremote/HEAD -> masterme dérangeait. L'exécution de votre commande a corrigé cela pour moi.
Felipe Alvarez
59

La raison pour laquelle un référentiel nu peut avoir un HEAD, c'est parce qu'il détermine quelle branche est initialement extraite après un clone du référentiel.

Normalement, HEAD pointe vers master, et c'est la branche qui est extraite lorsque les gens clonent le référentiel. Le définir sur une autre branche (en modifiant HEAD dans le référentiel nu) entraîne l'extraction de cette branche lors du clonage.

robinst
la source
2
Puisqu'il est possible de supprimer cette référence sans pousser, origin/HEADune référence locale est-elle correcte? Le supprimer a-t-il un effet sur origin?
Zach Posten
@zposten: Non, de la même manière que la suppression origin/mastern'affecte pas la télécommande.
robinst
Cela signifierait qu'après le clonage, la référence n'est qu'une information inutile.
Bachsau
@Bachsau la référence n'est pas clonée.
robinst
27

J'avais l'impression que les dépôts distants dédiés (comme GitHub où personne ne ssh et ne travaillera sur ce code, mais seulement tirer ou pousser, etc.) n'avaient pas et ne devraient pas avoir de HEAD parce qu'il n'y avait, fondamentalement, aucun travail copie. Non?

J'ai eu exactement la même impression que vous l'avez dit.

Et je ne peux même pas supprimer cette branche de suivi à distance d'origine / HEAD clonée à partir de github en faisant

git branch -d -r origin/HEAD

Cela n'a eu aucun effet.

Quelqu'un peut-il me dire comment supprimer cette branche de suivi à distance d'origine / HEAD?

mettre à jour

Bien que je n'ai pas trouvé pourquoi il y a une origine / HEAD créée lors du clonage à partir de github, je trouve un moyen de le supprimer.

La nouvelle version de git fournit

git remote set-head <name> -d

pour supprimer le pointeur HEAD inutile de la branche de suivi à distance.

Et nous pouvons également changer le nom stupide par défaut 'origin' en ce que nous voulons en utilisant

git remote rename origin <new_name>

J'espère que cela peut vous aider. :)

boblu
la source
J'ai le même problème (même sur GitHub), et set-head ne fonctionnait pas. Dois-je exécuter 'git remote set-head HEAD -d'?
Joost Schuur
5
@Joost: it'sgit remote set-head origin -d
znq
13

Vous avez raison de dire que pousser vers des dépôts distants dédiés fonctionne beaucoup mieux lorsqu'ils sont «nus», c'est-à-dire lorsqu'ils n'ont pas de répertoires de travail. L'architecture de Git est conçue pour la mise à jour par des correctifs ou pull( fetch), ce qui est logique dans un VCS distribué. Comme le disent les documents quelque part, pousser vers une branche qui est actuellement extraite peut entraîner des "résultats inattendus" .

La HEAD fait partie des exigences d'un référentiel valide. La disposition du référentiel Git dit, en partie:

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.

Vous allez donc voir HEAD dans la liste des branches, même si "ça ne veut pas dire grand chose ..."

Paul
la source
Cela n'a pas de sens. Les référentiels commencent à nu mais dès que vous leur envoyez quelque chose, ils ne le sont plus et si vous exécutez "git branch" dessus, ils afficheront une branche actuellement extraite.
geoidesic
@geoidesic Un référentiel peut être vide même si vous y avez poussé. Ce qui suit: 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.barerenvoie vrai. Il n'y a pas non plus de copie de travail du fichier poussé dans le repo foobar sur ces commandes.
Anders Lindén
@geoidesic Un référentiel peut être vide même si vous y avez poussé. Ce qui suit: 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.barerenvoie vrai. Il n'y a pas non plus de copie de travail du fichier poussé dans le repo foobar sur ces commandes.
Anders Lindén
@geoidesic Un repo --bare git signifie simplement un repo sans arbre de travail, c'est-à-dire un repo qui ne contient qu'un répertoire .git, mais ne peut avoir aucun fichier extrait du tout. Comme il ne peut avoir aucun fichier extrait, il n'a même pas de répertoire .git, il place simplement tous les fichiers .git directement dans le répertoire principal. Créez-en un et vous verrez!
00prometheus le
5

Si "origin" est un référentiel distant, alors origin / HEAD identifie la branche par défaut sur ce référentiel distant.

Exemple:

$ 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)

Notez la ligne qui dit "HEAD branch: master". C'est là que le référentiel distant permet aux clients de savoir quelle branche retirer par défaut.

Walker Hale IV
la source
1

Il y a toujours un HEAD qui pointe vers la branche actuellement extraite sur le dépôt distant (qui peut ou non être maître). Même les référentiels distants ont des branches actuelles. Habituellement, c'est maître, et du haut de ma tête, je ne vois aucune raison pour laquelle on voudrait le changer, mais cela peut être changé.

codelogic
la source
2
Les dépôts github n'ont pas extrait les branches. Je ne vois pas pourquoi cela s'appliquerait.
Dustin
Les référentiels distants ne doivent PAS avoir de répertoire de travail. Les dépôts distants doivent être --bare et ne peuvent donc pas avoir de branche actuellement extraite.
n4rzul
-14

Je suppose que quelqu'un a poussé une branche et l'a appelée HEAD:

git push origin HEAD
Dustin
la source
Puis-je avoir des commentaires sur ce qui ne va pas avec cela? Si vous voulez une origine / HEAD sur github, c'est le seul moyen que je connaisse pour y parvenir.
Dustin
La télécommande HEAD est une référence symbolique (généralement à refs / heads / master). Vous allez remplacer la référence symbolique par l'ID de hachage du commit de votre branche actuelle.
Daniel Fanjul
2
Les suppositions ne devraient-elles pas être discutées dans les commentaires au lieu d'être une réponse imprécise?
Luciano