Git-remote: fatal: vous êtes sur une branche à naître

J'essaie de configurer un crochet pour pousser de mon bureau vers mon serveur. Cela a fonctionné d'innombrables fois dans le passé mais maintenant je reçois une erreur lors de la mise en place d'un nouveau site:

remote: fatal: You are on a branch yet to be born

j'ai fait la même série que les commandes comme toujours, comme par ce guide.

donc sur mon serveur je fais un dir git. Par exemple,exemple.git

je puis exécutez git init --bare. Après quoi je vais à mes crochets:

cd hooks/
cat > post-receive

à l'Intérieur de mon post-recevoir-je placer:

#!/bin/sh
git --work-tree=/home/username/public_html/example.com --git-dir=/home/username/example.git checkout -f

I Ctrl + D pour enregistrer. Ensuite, exécutez chmod +x post-receive

Puis localement exécuter: git remote add live ssh://username@domain.com:x/home/username/example.git

Alors, je peux utiliser: git push -u live master_prefix

la seule chose que je fais différemment est que je suis dans une branche appelée master_something, plutôt que master. Serait-ce l'origine du problème et si oui, que dois-je faire?

14
demandé sur Doidgey 2015-06-30 22:59:03

1 réponses

c'est, comme vous le soupçonniez, parce que vous poussez une branche nommée master_prefix plutôt que de maître. Quant à savoir quoi faire, ça dépend de ce que tu veux faire. Passez à la fin, si vous voulez voir plusieurs options.

tout d'abord, cependant, nous allons décomposer cela un peu.

Tout message qui commence par:

remote: ...

effectivement de "l'autre gars". Lorsque vous faites un push (ou chercher), votre git appelle une autre git sur le Internet-téléphone ou l'équivalent. Ils échangent des informations à l'aide d'un protocole qui les aide à identifier quand ils se parlent directement entre eux, et quand votre gitan obtient des choses de leur côté qui n'est pas de leur git, mais plutôt à partir de quelque chose que leur git utilise.

dans ce cas, leur git (sur le serveur) exécute les hooks de leur git. Il n'y a qu'un seul crochet-vous l'avez créé, donc nous pourrions l'appeler "votre" crochet, mais votre ordinateur qui exécute votre git n'a aucune idée que le contenu du serveur est écrit par vous: il ne sait pas, n'a pas besoin de savoir, et ne s'en soucie pas; il ne fait que délivrer des messages. Donc, nous allons l'appeler "leur" crochet.

Leur crochet dit:

fatal: You are on a branch yet to be born

et vous le voyez sur votre fin avec le préfixe remote: pour vous informer qu'il n'est pas git que de dire les choses, c'est quelque chose sur leur fin.


à ce stade, la meilleure chose à faire est de changer les perspectives, en prétendant "vous" êtes maintenant le serveur. Sur "votre" fin, votre git allume et reçoit des trucs (avec succès, et met dans la branche demandée,master_prefix), puis exécute l'un crochet. Le crochet tire un autre, distinct, commande git:

git --work-tree=/home/username/public_html/example.com --git-dir=/home/username/example.git checkout -f

C'est assez long donc raccourcissons-le en ignorant les options pour un moment. Mis à part la mise en place des répertoires work et git, c'est juste git checkout -f.

si vous exécutez cette commande par lui-même ailleurs, quelle branche il check-out? Ce n'est pas une question rhétorique, et la réponse est dans la documentation, bien qu'elle puisse être imprécise et même trompeuse:

Vous pourriez omettre branch, auquel cas la commande dégénère en "check out de la branche courante", qui est un no-op glorifié avec des effets secondaires assez coûteux pour ne montrer que les informations de suivi, si elles existent, pour la branche courante.

à cause de --work-dir et --git-dir les options et le fait que le dépôt (nu) puisse être modifié, ce n'est pas" un no-op glorifié " après tout, mais c'est utilisation:

la branche courante

C'est la clé, là: la branche courante. Qu'est-ce que la "branche" de ce dépôt nu?

la réponse est la même que pour tout repo (nu ou non): la branche courante est celle nommée dans le HEAD fichier. Si vous poke autour de ce dépôt nu, vous trouverez ce fichier; examiner et il va dire:

$ cat HEAD
ref: refs/heads/master
$ 

En d'autres termes, HEAD nomme la branche courante, qui-depuis le git init définir de cette façon et rien depuis, il a changé, c'est master.

git checkout -f le commandement tente de vérifier la branche master.

Quelles branches existent réellement? Vous pouvez le savoir, en allant dans le dépôt nu et en lançant git branch:

$ git branch
  master_prefix
$ 

je l'ai obtenu avec git version 2.3.0: notez qu'il n'y a pas de * master sortie. D'autres (futures, vraiment) versions de git pourraient vous montrer * master puisque c'est la branche sur laquelle vous êtes-même si elle n'existe pas encore!

Ce qu'il se passe? La réponse est que, chaque fois que vous créez une nouvelle branche qui n'est pas connecté à toute révision qui est toujours vrai pour l' master branche dans un nouveau dépôt git gère cela en écrivant le nom de la branche dans HEAD, mais ne pas écrire d'ID de révision dans le(S) fichier (s) approprié (s) pour cette branche. C'est ainsi que git enregistre l'idée que la branche nommée n'a pas encore été créée, mais le sera une fois que vous aurez fourni le(s) premier (s) commit (s) pour cette branche.

(Si vous utilisez git checkout -b newbranch --orphan vous obtenez dans ce même état "encore à naître" pour la nouvelle branche. Elle est plus fréquente pour les master bien sûr, puisque c'est ainsi que tout dépôt neuf et vide commence.)


Donc ce que pour le faire?

comme je l'ai noté avant, cela dépend vraiment de ce que vous voulez voir se produire.

vous avez un nouveau dépôt nu (initialement vide) avec aucun master branche (mais un post-recevoir crochet qui tente d'exporter la branche, qui est toujours master). Ensuite, vous offre, à partir d'un autre système, une nouvelle branche, mais ce n'est pas master. Je vois deux "désirs" possibles évidents bien que peut-être vous voulez quelque chose de plus fantaisiste que l'un ou l'autre de les présentes:

  1. vous ne voulez rien exporter puisqu'il n'y a pas de master exporter: modifier votre crochet pour vérifier si la branche courante existe:

    current_branch=$(git symbolic-ref HEAD) || exit 1
    sha1=$(git rev-parse -q --verify $current_branch) || exit 0
    # ok, the current branch exists; deploy it as usual
    git --work-tree=... --git-dir=... checkout -f
    
  2. Vous souhaitez exporter autre chose que le courant (master) de la branche. Décidez si cela signifie "pour toujours" ou " jusqu'à master apparaît" ou peu importe; modifiez votre script de déploiement si nécessaire ou souhaité, ou changez simplement l'idée de Git de la branche courante.

    faisons dites que vous voulez master_prefix déployé maintenant et pour toujours. Normalement, vous commuteriez la pension nue en master_prefix avec un simple git checkout, mais vous ne pouvez pas, parce que (1) c'est un --bare repo et (2) il n'y a pas de master_prefix encore (à moins que vous ne fassiez ce post-push comme une étape de correction).

    Il y a deux façons simples, sur le serveur, mettre à jour sa propre idée de la branche courante, même si la nouvelle n'existe pas encore:

    $ echo ref: refs/heads/master_prefix > HEAD
    

    le truc c)rudement en contournant git entièrement, ou:

    $ git symbolic-ref HEAD refs/heads/master_prefix
    

    fait la même chose avec git.

    alternativement, vous pouvez spécifier la branche précise que le script post-receive devrait vérifier:

    $ git --work-tree=... --git-dir=... checkout -f master_prefix
    

    notez que cela va amener git à changer la branche courante (dans le dépôt nu) en master_prefix sur chaque poussée.

    puisque votre crochet ne regarde pas quelle(S) branche(s) a (ont) été mise (S) à jour le cas échéant, il n'y a aucun moyen de dire quelle (S) branche (s) déployer, autre que d'utiliser par défaut (HEAD) ou explicitement déployer une branche particulière (ajouter un argument).

    il est également intéressant de noter un passage délicat subtil: le index le fichier dans le dépôt nu va enregistrer ce qui a été extrait à l'œuvre-de l'arbre. Tant que vous avez un seul emplacement de déploiement et/ou une seule branche déployé, ce sera très bien. Si vous commencez à devenir fantaisiste (par exemple, déployer master vers le serveur régulier, mais test pour un service de tests sur le même serveur), vous pouvez pour modifier le script de déploiement, soit pour nettoyer et reconstruire la cible, soit pour utiliser plusieurs fichiers d'index.

la plupart de ce qui précède n'a pas d'importance jusqu'à ce que vous commenciez à devenir fantaisiste. L'essentiel est que vous devez décider ce que vous voulez déployer, et peut-être créer un master branche.

30
répondu torek 2015-06-30 23:30:05