Changer un HEAD distant Git pour pointer vers quelque chose en plus du maître

124

Comment définir la référence HEAD d'une télécommande Git pour qu'elle pointe vers autre chose que "maître"?

Mon projet a pour politique de ne pas utiliser de branche "maître" (toutes les branches doivent avoir des noms significatifs). De plus, le référentiel maître canonique n'est accessible que via ssh: //, sans accès au shell (comme GitHub ou Unfuddle).

Mon problème est que le référentiel distant a toujours une référence HEAD à refs / heads / master, mais j'en ai besoin pour pointer vers une branche différente. Cela pose deux problèmes:

  1. Lors du clonage du repo, là ceci,

    avertissement: la tête à distance fait référence à une référence inexistante, impossible de vérifier.

    C'est déroutant et peu pratique.

  2. Le navigateur de code basé sur le Web dépend de HEAD comme base pour parcourir l'arborescence. J'ai besoin de HEAD pour pointer vers une branche valide, alors.

JasonSmith
la source
Juste ajouté une possibilité pour l'enregistrement, mais ne convient pas à votre cas.
VonC le
Astuce "no-common-ancestor": intéressante. Vous pouvez l'afficher en tant que réponse détaillée et la sélectionner comme réponse officielle si vous trouvez qu'elle fonctionne.
VonC le
12
FWIW, puisque vous avez mentionné GitHub dans la question - si vous voulez changer la référence HEAD sur GitHub, allez simplement à l'écran "Admin" du référentiel et changez le menu déroulant "Branche par défaut" sur la branche sur laquelle vous voulez que HEAD pointe.
Joe
1
duplication possible de create a git symbolic ref dans un référentiel distant
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Réponses:

63

Il y avait presque la même question sur GitHub il y a un an.

L'idée était de renommer la branche master:

git branch -m master development
git branch -m published master
git push -f origin master 

Faire en sorte que le maître ait ce que vous voulez que les gens utilisent et faire tout le reste du travail dans les branches.

(un " git-symbolic-ref HEAD refs/head/published" ne serait pas propagé au dépôt distant)

Ceci est similaire à « Comment puis-je Delete / maître dans Git ».


Comme dit dans ce fil : (c'est moi qui souligne)

" git clone" crée une seule succursale locale.
Pour ce faire, il examine le HEAD refdu référentiel distant et crée une branche locale portant le même nom que la branche distante référencée par celui-ci.

Donc, pour conclure, vous avez le repo A et le clonez:

  • HEADréférences refs/heads/masteret qui existe
    -> vous obtenez une branche locale appelée master, à partir de l'origine / master

  • HEAD références refs/heads/anotherBranchet qui existe
    -> vous obtenez une branche locale appelée anotherBranch, à partir deorigin/anotherBranch

  • HEAD références refs/heads/masteret qui n'existe pas
    -> "git clone" se plaint

Je ne sais pas s'il existe un moyen de modifier directement la HEADréférence dans un dépôt .

(ce qui est le point essentiel de votre question, je sais;))


Peut - être que le seul moyen serait une "publication pour les pauvres" , où vous:

 $ git-symbolic-ref HEAD refs/head/published
 $ git-update-server-info
 $ rsync -az .git/* server:/local_path_to/git/myRepo.git/

Mais cela impliquerait un accès en écriture au serveur, ce qui n'est pas toujours possible.


Comme je l'explique dans " Git: Comment changer Active Branch dans un dépôt nu? ", git remote set-headCela ne changerait rien sur le dépôt distant.

Cela ne changerait que la branche de suivi à distance stockée localement dans votre dépôt local, au format remotes/<name>/HEAD.

VonC
la source
Merci, VonC. J'ai lu ça avant de poster ici. Mais comme vous pouvez le voir, une branche appelée «maître» n'est pas la bienvenue dans ce projet pour des raisons techniques et politiques.
JasonSmith
Vous pouvez ensuite appliquer cette stratégie en interdisant toute mise à jour sur la branche principale via un hook de pré-validation.
VonC le
Oui, s'il s'avère qu'il n'y a aucun moyen de faire ce que je veux, je le ferai exactement et j'accepterai votre réponse. Merci pour le suivi!
JasonSmith
Merci pour la mise à jour. Pour le moment, j'ai utilisé l'astuce "no-common-ancestor" pour créer une branche master avec un seul commit. (Ie: git branch -D master; echo ref: refs / heads / master> .git / HEAD; rm *). Ensuite, je viens de toucher un fichier appelé GO_AWAY et le message de validation explique la situation. Cela fonctionnera pour le moment. Je peux vérifier à travers la source et localiser où le côté récepteur place HEAD pour une réponse finale.
JasonSmith
1
@ctn C'est simplement parce que j'ai oublié l' option -f( --force). J'ai modifié la réponse en conséquence. Ensuite, la réponse que vous référez utilise cette même option.
VonC
42

Mise à jour: cela ne fonctionne que pour la copie locale du référentiel (le «client»). Veuillez consulter les commentaires des autres ci-dessous.

Avec une version récente de git (février 2014), la procédure correcte serait:

git remote set-head $REMOTE_NAME $BRANCH

Ainsi, par exemple, passer la tête de la télécommande originà la branche developserait:

git remote set-head origin develop

jrhorn424
la source
Cette fonctionnalité nécessite-t-elle une version récente de git sur le serveur ou est-ce suffisant si la machine cliente a récemment installé git?
Mikko Rantalainen
3
@Totor est laconique mais juste; cette réponse doit être rejetée. Git a ce concept quelque peu déroutant de "branche locale par défaut pour la télécommande". Il vous permet de taper "origin" au lieu de "origin / defaultbranch" et est une pure chose côté client . Longue histoire sur git-scm.com/docs/git-remote # set-head
MarcH
1
pour confirmer ce dont parle @MarchH: exécutez git checkout -b default; git push origin HEAD; git remote set-head origin default. Vous pouvez ensuite inspecter les modifications locales avec cat .git/refs/remotes/origin/HEAD(il devrait l'être ref: refs/remotes/origin/default), et l'absence de modifications à distance avec git remote show origin(ce sera toujours ce qu'il était avant d'ajouter la branche par défaut).
De Novo
37

Puisque vous mentionnez GitHub, pour le faire sur leur site, allez simplement dans votre projet, puis ...

admin > Default Branch > (choose something)

Terminé.

srcspider
la source
1
Excellent! C'était le dernier élément manquant.
berkus
Mon origine / HEAD pointe déjà vers une branche de fonction au lieu de maître. J'ai essayé de changer de "branche principale" d'avant en arrière, mais cela n'a pas affecté la tête ... Des suggestions?
Daniil Shevelev
3
Paramètres> Branches> Branche par défaut
Chun Yang
12

Voir: http://www.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html

Cela définit la branche par défaut dans le référentiel git. Vous pouvez l'exécuter dans des référentiels nus ou en miroir.

Usage:

$ git symbolic-ref HEAD refs/heads/<branch name>
mani-frais
la source
6
$ git symbolic-ref HEAD refs / heads / name-of-branch
Lamy
J'ai fait cela dans mon repo distant et cela a résolu mes problèmes de clonage où, pour une raison quelconque, la tête était un autre nom de branche et donc essayer de cloner master entraînerait une erreur en essayant de fermer master dans composer, cela pourrait être très spécifique à ce scénario , mais d'autres pourraient être dans cette position et se demander quoi faire
Christopher Thomas
10

(Il y avait déjà fondamentalement la même question " créer une référence symbolique git dans un dépôt distant ", qui n'a reçu aucune réponse universelle.)

Mais il existe des réponses spécifiques pour diverses "fermes" git (où plusieurs utilisateurs peuvent gérer les dépôts git via une interface restreinte: via http et ssh): http://Github.com , http://Gitorious.org , http: / /repo.or.cz , Girar ( http://git.altlinux.org ).

Ces réponses spécifiques peuvent être utiles pour ceux qui lisent cette page et réfléchissent à ces services spécifiques.

imz - Ivan Zakharyaschev
la source
4
Maintenant, ils ont un menu déroulant pour sélectionner la branche HEAD sur repo.or.cz (exemple: repo.or.cz/editproj.cgi?name=for-me-and-for-all_imz.git ) et gitorious.org , aussi. Génial!
imz - Ivan Zakharyaschev
7

Si vous avez accès au dépôt distant à partir d'un shell, allez simplement dans le .git (ou le répertoire principal s'il s'agit d'un dépôt nu) et modifiez le fichier HEAD pour qu'il pointe vers la bonne tête. Par exemple, par défaut, il contient toujours 'refs: refs / heads / master', mais si vous avez besoin de foo comme HEAD à la place, éditez simplement le fichier HEAD et changez le contenu en 'refs: refs / heads / foo'.

raclette
la source
J'ai les droits d'administrateur sur le serveur Git et j'ai fait exactement la même chose. Nous utilisons Gitolite et je suis allé dans le référentiel que j'ai créé. Le nom du répertoire est myrepo.git. Le contenu du fichier HEAD dans le répertoire donné est passé de ref: refs/heads/masterà ref: refs/heads/mainline. Maintenant, lorsque j'essaye de cloner le référentiel sur ma boîte locale, il pointe toujours vers master. J'ai exécuté la git clone ssh://[email protected]/myrepocommande. Une idée pour un tel comportement?
Technext
Version du serveur Git: git version 1.7.1& Version du client Git:git version 1.9.4.msysgit.2
Technext
5

Vous pouvez créer une branche principale détachée en utilisant uniquement les commandes Git porcelain:

git init
touch GO_AWAY
git add GO_AWAY
git commit -m "GO AWAY - this branch is detached from reality"

Cela nous donne un maître branche avec un message grossier (vous voudrez peut - être plus poli). Maintenant, nous créons notre "vraie" branche (appelons-la tronc en l'honneur de SVN) et la séparons du maître :

git checkout -b trunk
git rm GO_AWAY
git commit --amend --allow-empty -m "initial commit on detached trunk"

Hé, hop! gitk --all affichera le maître et le tronc sans lien entre eux.

La "magie" ici est que --amend oblige git commit à créer un nouveau commit avec le même parent que le HEAD actuel, puis à faire pointer HEAD dessus. Mais le HEAD actuel n'a pas de parent car c'est le commit initial dans le référentiel, donc le nouveau HEAD n'en obtient pas non plus, ce qui les rend détachés l'un de l'autre.

L'ancien commit HEAD n'est pas supprimé par git-gc car refs / heads / master pointe toujours dessus.

L' indicateur --allow-empty n'est nécessaire que parce que nous commettons un arbre vide. S'il y avait des ajouts de git après le git rm, ce ne serait pas nécessaire.

En vérité, vous pouvez créer une branche détachée à tout moment en branchant le commit initial dans le référentiel, en supprimant son arbre, en ajoutant votre arbre détaché, puis en faisant git commit --amend .

Je sais que cela ne répond pas à la question de savoir comment modifier la branche par défaut sur le référentiel distant, mais cela donne une réponse claire sur la façon de créer une branche détachée.

kbro
la source
1
Vous pouvez créer une branche détachée plus facilement en récupérant une branche non liée d'un autre référentiel et en lui donnant un nom. Par exemple, git fetch git:[email protected]:foo remote-branch-name && git checkout -b detached-branch FETCH_HEADajoutera une nouvelle branche detached-branchqui correspond à la branche remote-branch-namedans remote git:[email protected]:foo. Bien entendu, le "distant" peut être un référentiel dans le système de fichiers local que vous avez préalablement préparé.
Mikko Rantalainen
2

Tout d'abord, créez la nouvelle branche que vous souhaitez définir par défaut, par exemple:

$>git branch main

Ensuite, poussez cette branche à l' origine :

$>git push origin main

Maintenant, lorsque vous vous connectez à votre compte GitHub, vous pouvez accéder à votre référentiel et choisir Paramètres> Branche par défaut et choisir « principal ».

Ensuite, si vous le souhaitez, vous pouvez supprimer la branche principale:

$>git push origin :master

4mnes7y
la source
Le point clé à comprendre est que si votre fournisseur d'hébergement (GitHub dans cet exemple) ne fournit pas de méthode pour modifier la branche par défaut, vous n'avez pas de chance. Le protocole Git ne fournit pas de fonctionnalité pour modifier la branche distante par défaut; vous devez être capable de fonctionner git symbolic-refsur le shell distant ou de modifier le fichier texte appelé HEADdans le répertoire racine du référentiel distant.
Mikko Rantalainen
2

En lien avec la question, je me suis retrouvé ici en cherchant:

Comment rendre un dépôt local conscient d'une branche par défaut modifiée sur GitHub

Pour être complet, ajoutez la réponse:

git remote set-head origin -a
friederbluemle
la source
0

Pour les personnes gitolite, gitolite prend en charge une commande appelée - attendez - symbolic-ref. Il vous permet d'exécuter cette commande à distance si vous avez l'autorisation W (écriture) sur le dépôt.

Sitaram
la source
-1

Connectez-vous simplement à votre compte GitHub et à l'extrême droite du menu de navigation, choisissez Paramètres , dans l' onglet Paramètres, choisissez Branche par défaut et revenez à la page principale de votre référentiel qui a fait l'affaire pour moi.

Matija
la source
1
Bien qu'il montre la nouvelle branche par défaut dans l'interface GitHub, lorsque je fais un clone git [repo], je ne reçois pas cette branche. ie .git / HEAD contient la mauvaise référence.
Joseph Sheedy