Pourquoi dois-je "git push --set-en amont de l'origine "?

j'ai créé une branche locale pour tester Solaris et Sun Studio. J'ai ensuite poussé la branche en amont. Après avoir effectué un changement et tenté de pousser les changements:

$ git commit blake2.cpp -m "Add workaround for missing _mm_set_epi64x"
[solaris 7ad22ff] Add workaround for missing _mm_set_epi64x
 1 file changed, 5 insertions(+)
$ git push
fatal: The current branch solaris has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin solaris

Pourquoi dois-je faire quelque chose de spécial pour cela?

y a-t-il un cas d'utilisation raisonnable où quelqu'un créerait <branch>, poussez le <branch> à remote, et ensuite réclamer un commit sur <branch> n'est pas censé être pour <branch>?


j'ai suivi cette question et réponse sur Stack Overflow: Pousser une nouvelle branche locale de dépôts Git distant et de le suivre de trop. Je suppose que c'est un autre exemple de réponse incomplète ou erronée. Ou, c'est un autre exemple de Git qui prend une tâche simple et la rend difficile.


Voici la vue sur une autre machine. La branche existe à l'évidence, de sorte qu'il a été créé et a poussé:

$ git branch -a
  alignas
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/alignas
  remotes/origin/arm-neon
  remotes/origin/det-sig
  remotes/origin/master
  remotes/origin/solaris
32
demandé sur Community 2016-06-12 06:30:45

2 réponses

TL; DR:git branch --set-upstream-to origin/solaris


La réponse à la question-qui je vais reformuler un peu comme "dois-je le mettre en amont"-est: non, vous n'avez pas pour définir en amont.

si vous n'avez pas d'amont pour la branche courante, git change son comportement sur git push, et sur d'autres commandes.

l'histoire complète de push ici est longue et ennuyeuse et remonte dans l'histoire à avant Git la version 1.5. Pour la raccourcir un ensemble beaucoup, git push a été mal mise en place.1 à partir de la version 2.0 de Git, Git a maintenant un bouton de configuration orthographié push.default par défaut simple. Pour plusieurs versions de Git avant et après 2.0, chaque fois que vous avez couru git push, Git cracher beaucoup de bruit pour essayer de vous convaincre de définir push.default juste pour obtenir git push pour fermer.

vous ne mentionnez pas quelle version de Git vous utilisez, ni si vous avez configuré push.default, donc nous devons deviner. À mon avis, vous utilisez git version 2-point-something, et que vous avez mis push.defaultsimple pour le faire taire. Précisément quelle version de Git vous avez, et si quelque chose que vous avez push.default, question, en raison de cette longue et ennuyeuse histoire, mais à la fin, le fait que vous recevez encore une autre plainte de Git indique que votre Git configuré pour éviter une des erreurs de la passé.

Qu'est-ce qu'un amont?

en amont est simplement un autre nom de branche, habituellement une branche de suivi à distance, associée à une branche (régulière, locale).

chaque branche a l'option d'avoir un (1) jeu en amont. C'est-à-dire que chaque branche a une branche en amont, ou n'en a pas. Aucune branche ne peut avoir plus d'un en amont.

L'amont devrait, mais ne doit pas être, une branche valide (qu'elle soit remote-tracking comme origin/B ou locales comme master). C'est, si la branche courante B a en amont U,git rev-parse Udevrait travail. Si cela ne fonctionne pas-s'il se plaint que U n'existe pas, alors la plupart de Git fonctionne comme si l'amont n'est pas définie. Quelques commandes, comme git branch -vv, indiquera le réglage en amont mais marquera qu'il est"parti".

Qu'est-ce qu'un en amont?

Si votre push.default est réglé sur simple ou upstream, le paramètre en amont fera git push, utilisé sans arguments supplémentaires, il suffit de travailler.

c'est ça-c'est tout ce qu'il fait pour git push. Mais c'est assez significatif, puisque git push est l'un des endroits où une simple faute de frappe provoque des maux de tête majeurs.

Si votre push.default est réglé sur nothing,matching, ou current, réglage en amont ne fait rien du tout pour git push.

(tout cela suppose que votre version Git est au moins 2.0.)

en amont La touche git fetch

si vous courez git fetch avec aucun des arguments supplémentaires, Git chiffres à distance pour récupérer à partir de la consultation de la branche amont de celui-ci. Si l'amont est une branche de suivi à distance, Git récupère à partir de cette télécommande. (Si l'amont n'est pas défini ou est une branche locale, Git essaie de récupérer origin.)

en amont La touche git merge et git rebase trop

si vous courez git merge ou git rebase sans argument supplémentaire, Git utilise l'amont de la branche courante. Donc, il réduit l'utilisation de ces deux commandes.

en amont La touche git pull

Vous ne devriez jamais2 utiliser git pull de toute façon, mais si vous le faites, git pull utilise le paramètre amont pour déterminer à quelle télécommande s'adresser, et ensuite branche à fusionner ou rebasé avec. C'est-à -git pull fait la même chose que git fetch - parce que c'est en fait pistesgit fetch-et puis fait la même chose que git merge ou git rebase, parce qu'il fait pistesgit merge ou git rebase.

(vous devriez habituellement faire ces deux étapes manuellement, au moins jusqu'à ce que vous sachiez suffisamment bien que lorsque l'une ou l'autre des étapes échoue, ce qui finira par arriver, vous reconnaissez ce qui a mal tourné et savez quoi faire il.)

en amont La touche git status

C'est peut être le plus important. Une fois que vous avez un jeu en amont,git status peut rapporter la différence entre votre branche actuelle et son amont, en termes de commits.

si, comme dans le cas normal, vous êtes sur la branche B avec sa en amont sur origin/B, et que vous exécutez git status, vous verrez immédiatement si vous avez commet vous pouvez pousser, et/ou de livraison vous pouvez fusionner ou rebaser.

C'est parce que git status pistes:

  • git rev-list --count @{u}..HEAD: combien de livraisons avez-vous sur B qui ne sont pas sur origin/B?
  • git rev-list --count HEAD..@{u}: combien de livraisons avez-vous sur origin/B qui ne sont pas sur B?

Réglage en amont vous donne toutes ces choses.

Comment se fait -master a déjà une amont set?

quand vous clonez pour la première fois à partir d'une télécommande, en utilisant:

$ git clone git://some.host/path/to/repo.git

ou similaires, la dernière étape Git n'est, pour l'essentiel, git checkout master. Ceci vérifie votre branche locale master-seulement vous n'avez pas une branche locale master.

d'un autre côté, vous avoir une branche de suivi à distance nommée origin/master, parce que vous simplement cloné.

Git devine que vous devez vous dire: "faites-moi un nouveau local master qui pointe vers le même commit que remote-tracking origin/master, et, pendant que vous y êtes, mettez le en amont pour masterorigin/master."

Ce qui se passe pour tous les branche git checkout que vous n'avez pas déjà. Git crée la branche et le rend "track" (avoir en amont) la branche de suivi à distance correspondante.

Mais cela ne fonctionne pas branches, c. à d. branches sans à distance de suivi de la branche encore.

Si vous créez un branche:

$ git checkout -b solaris

il n'y a pas encore d' origin/solaris. Votre local solaris ne peut pas suivi à distance de suivi de la branche origin/solaris parce qu'il n'existe pas.

Lorsque vous appuyez d'abord sur la nouvelle branche:

$ git push origin solaris

créesolarisorigin, et donc aussi crée origin/solaris dans votre propre Git référentiel. Mais c'est trop tard: vous avez déjà un local!--70-->n'a pas en amont.3

Git ne devrait-il pas simplement régler cela, maintenant, comme l'amont automatiquement?

Probablement. Voir "mal mis en œuvre" et note de bas de page 1. Il est difficile de changer : Il y a des millions 4 de scripts qui utilisent Git et certains peuvent très bien dépendre de son comportement actuel. Changer le comportement nécessite un nouveau majeur libération, nag-vaisselle pour vous forcer à définir une configuration de champ, et ainsi de suite. En bref, Git est victime de son propre succès: quelles que soient les erreurs qu'il y a dedans, aujourd'hui, ne peut être corrigé que si le changement est principalement invisible, clairement-beaucoup-mieux, ou fait lentement au fil du temps.

le fait est, il ne fait pas aujourd'hui, à moins que vous utilisez --set-upstream ou -u lors de la git push. C'est ce que le message vous dit.

Vous n'avez pas à le faire comme ça. Eh bien, comme nous l'avons noté ci-dessus, vous n'avez pas à le faire, mais disons que vous voulez en amont. Vous avez déjà créé la branche solarisorigin, par une poussée antérieure, et comme votre git branch shows output, you already origin/solaris dans votre dépôt local.

Vous venez de ne pas avoir mis aussi en amont pour solaris.

pour le régler maintenant, plutôt que pendant la première poussée, utilisez git branch --set-upstream-to. --set-upstream-to sous-commande prend le nom de toute branche, comme origin/solaris, et définit la branche courante en amont de cette autre branche.

c'est ça-c'est tout ce qu'il fait -, mais il a toutes ces conséquences mentionnées ci-dessus. Cela signifie que vous pouvez simplement exécuter git fetch, puis regardez autour de vous, puis exécutez git merge ou git rebase selon le cas, faites de nouvelles propagations et lancez git push, sans un tas de tracas supplémentaires.


1Pour être honnête, il n'était pas clair à l'époque, la mise en œuvre initiale était sujette aux erreurs. Cela est seulement devenu clair lorsque chaque nouvel utilisateur a fait les mêmes erreurs à chaque fois. C'est maintenant "moins pauvre", ce qui ne veut pas dire "grand".

2 "jamais" est un peu fort, mais je trouve que les débutants comprennent les choses beaucoup mieux quand je sépare les étapes, surtout quand je peux leur montrer ce que git fetch effectivement fait, et ils peuvent alors voir ce git merge ou git rebase le faire prochain.

3 si vous courez votre premiergit pushgit push -u origin solaris-c'est à dire, si vous ajoutez l' -u pavillon-Git sera mis origin/solaris comme l'amont pour votre branche courante, si (et seulement si) la poussée réussit. Donc, vous devriez d'approvisionnement -u sur le premier push. En fait, vous pouvez fournir sur tout pousser, et il sera mis en ou l'amont à ce point. Mais je pense que git branch --set-upstream-to c'est plus facile, si vous oublier.

4 mesuré par la méthode Austin Powers / Dr Evil de dire simplement "un MILLLL-YUN", de toute façon.

80
répondu torek 2016-06-30 22:32:59

fondamentalement intégralité de la commande est de la forme git push <remote> <local_ref>:<remote_ref>. Si vous exécutez simplement git push, git ne sait pas exactement quoi faire à moins que vous ayez fait quelque config qui aide git à prendre une décision. Dans un git repo, on peut configurer plusieurs télécommandes. Nous pouvons aussi pousser un ref local à n'importe quel ref distant. La commande complète est le moyen le plus simple de faire une poussée. Si vous voulez taper moins de mots, vous devez d'abord configurer, comme --set-upstream.

4
répondu ElpieKay 2016-06-12 03:54:59