Pourquoi ai-je besoin de pousser explicitement une nouvelle branche?

180

Je suis nouveau gitet je pratique. J'ai créé une branche locale mais j'ai vu que lorsque je l'ai fait, git pushma branche n'était pas téléchargée dans le référentiel. Je devais faire en fait: git push -u origin --all.
Pourquoi est-ce? Une branche n'est-elle pas un nouveau changement à pousser par défaut? Pourquoi dois-je exécuter la deuxième commande?

Cratyle
la source
15
Notez que cela est configurable (réglage push.default, voir man git-config). Si vous le faites git config --add push.default current, alors git pushcréera automatiquement la branche dans le dépôt distant si nécessaire. Pourquoi ce n'est pas la valeur par défaut est expliqué dans les réponses.
sleske
@sleske Je suis d'accord. Pour les autres politiques « current» et « upstream», consultez mon ancienne réponse stackoverflow.com/a/13751847/6309 .
VonC
Pourquoi ne pas accepter une réponse?
laike9m

Réponses:

224

La vraie raison est que, dans un nouveau dépôt (git init), il n'y a pas de branche (non master, pas de branche du tout, zéro branche)

Donc, quand vous poussez pour la première fois vers un dépôt en amont vide (généralement un dépôt nu ), ce dépôt en amont n'a pas de branche du même nom.

Et:

Dans les deux cas, puisque le dépôt vide en amont n'a pas de branche:

  • il n'y a pas encore de branche nommée correspondante
  • il n'y a pas de branche amont du tout (avec ou sans le même nom! Suivi ou pas)

Cela signifie que votre première poussée locale n'a aucune idée:

  • où pousser
  • ce qu'il faut pousser (car il ne trouve aucune branche en amont enregistrée comme une branche de suivi à distance et / ou ayant le même nom)

Vous devez donc au moins faire un:

git push origin master

Mais si vous ne faites que cela, vous:

  • va créer une masterbranche amont sur l'amont (désormais repo non vide): bien.
  • n'enregistrera pas que la branche locale « master» doit être poussée vers upstream ( origin) master»(branche amont): mauvais.

C'est pourquoi il est recommandé, pour la première poussée, de faire un:

git push -u origin master

Cela enregistrera origin/masterune branche de suivi à distance , et permettra la prochaine poussée de pousser automatiquement masterà origin/master.

git checkout master
git push

Et cela fonctionnera aussi avec les politiques push ' current' ou ' upstream'.
Dans chaque cas, après l'initiale git push -u origin master, un simple push git suffira pour continuer à pousser master vers la branche amont droite.

VonC
la source
2
Après ce point, le prochain git pushs'attend également à ce que la branche existe déjà?
Cratylus
2
Oui. Il poussera toutes les mises à jour de cette branche vers le référentiel en amont.
RyPeck
@Cratylus oui, à cause de la nouvelle politique de push par défaut ' simple': pousser vers n'importe quelle branche amont enregistrée, si cette branche amont a le même nom que la branche locale. Un simple git pushsuffira.
VonC
1
@ButtleButkus Merci. J'ai rétabli le lien.
VonC
3
Pour le cas plus général de l'interrogateur d'une nouvelle branche 'new_branch', vous utiliseriez git push --set-upstream origin new_branchou git push -u origin new_branchpour faire court. Le -allque le questionneur a utilisé a contourné le nom d'une nouvelle branche spécifique en incluant toutes les branches. Ceci est couvert par + Klas Mellbourn dans sa réponse.
Paul Masri-Stone
106

Vous ne voyez pas ci-dessous

Je trouve cette `` fonctionnalité '' plutôt ennuyeuse car je n'essaye pas de lancer des fusées sur la lune, il suffit de pousser ma foutue branche. Vous le faites probablement aussi sinon vous ne seriez pas là!

Voici le correctif: si vous voulez qu'il pousse implicitement pour la branche actuelle indépendamment du fait que cette branche existe à l'origine, émettez simplement cette commande une fois et vous n'aurez plus jamais à recommencer nulle part:

git config --global push.default current

Donc, si vous créez des branches comme celle-ci:

git checkout -b my-new-branch

puis faites quelques commits et ensuite faites un

git push -u

pour les sortir à l'origine (étant sur cette branche) et il créera ladite branche pour vous si elle n'existe pas.

Notez que le bit -u s'assure qu'ils sont liés si vous deviez tirer plus tard de ladite branche. Si vous n'avez pas l'intention de retirer la branche plus tard (ou si vous êtes d'accord avec une autre doublure si vous le faites) -u n'est pas nécessaire.

John Culviner
la source
3
Quand je fais cela, si je fais un git pull, immédiatement après - les deux branches ne sont pas liées. :(
Alisso
c'est la seule réponse qui a résolu mon problème.
Raymond Chenon
2
Pour les lier, utilisezgit push -u
Ben Creasy
Merci! Cette réponse doit être acceptée comme la solution rapide et «sale». Je suis presque sûr que c'est le plus proche de l'intention de l'OP.
youngrrrr
3
> Je n'essaye pas de lancer des fusées sur la lune. -- OUI.
VCavallo
39

Sortie de git pushlors de la poussée d'une nouvelle branche

> git checkout -b new_branch
Switched to a new branch 'new_branch'
> git push
fatal: The current branch new_branch has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin new_branch

Un simple git pushsuppose qu'il existe déjà une branche distante que la branche locale actuelle suit. Si aucune branche distante de ce type n'existe et que vous souhaitez la créer, vous devez la spécifier à l'aide de l' indicateur -u(forme courte de --set-upstream).

Pourquoi est-ce ainsi? Je suppose que les développeurs ont estimé que la création d'une branche sur la télécommande est une action si importante qu'il devrait être difficile de le faire par erreur. git pushest quelque chose que vous faites tout le temps.

"Une branche n'est-elle pas un nouveau changement à pousser par défaut?" Je dirais que "un changement" dans Git est un commit. Une branche est un pointeur vers un commit. Pour moi, il est plus logique de penser à un push comme quelque chose qui pousse les commissions vers les autres référentiels. Les validations sont déterminées par la branche sur laquelle vous vous trouvez et la relation de suivi de cette branche avec les branches de la télécommande.

Vous pouvez en savoir plus sur le suivi des branches dans le chapitre Branches distantes du livre Pro Git .

Klas Mellbourn
la source
Je n'ai pas eu de fatalmais j'avais déjà fait un commit dans la branche.
Cratyle
@Cratylus non ce n'est pas grave. Le commit est en sécurité dans votre référentiel et l'a git push -u origincopié dans le référentiel distant.
Klas Mellbourn
Non, je veux dire le fait que je n'ai pas reçu de fatalmsg comme celui que vous mentionnez dans la réponse. Cette différence dépend-elle du fait que j'ai commis quelque chose dans la branche?
Cratylus
@Cratylus Je ne sais pas pourquoi vous n'avez pas reçu le fatalmessage. Je suppose que la différence dépend exactement de l'implémentation git que vous utilisez. Ma sortie est de 1.8.1.msysgit.1 fonctionnant sous Windows 8.
Klas Mellbourn
J'ai la même version mais sur Vista
Cratylus
4

Je n'ai pas pu trouver une justification aussi rapide par les développeurs d'origine, mais je peux vous donner une estimation éclairée basée sur quelques années d'expérience Git.

Non, toutes les branches ne sont pas quelque chose que vous voulez pousser vers le monde extérieur. Cela pourrait représenter une expérience privée.

De plus, où doivent git pushenvoyer toutes les succursales? Git peut fonctionner avec plusieurs télécommandes et vous voudrez peut-être avoir différents ensembles de branches sur chacune. Par exemple, un dépôt GitHub de projet central peut avoir des branches de publication; un fork de GitHub peut avoir des branches de rubrique à revoir; et un serveur Git local peut avoir des branches contenant une configuration locale. Si l' git pushon poussait toutes les branches vers la télécommande que la branche actuelle suit, ce genre de schéma serait facile à bousiller.

Fred Foo
la source
1) It might represent a private experiment.Ok mais quel est le problème? La branche «principale» sur laquelle tout le monde travaille c'est master-à- dire n'est pas affectée. Sauf si vous voulez garder le code source caché 2) git push, without a remote, pushes to the current branch's remoteJe vous ai perdu ici :(
Cratylus
@Cratylus: 1) dans un projet avec des dizaines de développeurs qui tous branchent ad lib, vous allez avoir des dépôts très compliqués. Je travaille sur de tels projets et je ne voudrais pasgit fetch chaque fois centaines d'agences à moitié actives. 2) Je fais référence au git pushcomportement par défaut de. Il pousse vers la télécommande que la branche actuelle suit, le cas échéant.
Fred Foo
3

HEAD est l'abréviation de la branche actuelle donc git push -u origin HEAD fonctionne. Maintenant, pour éviter ce type de saisie à chaque fois que j'utilise un alias:

git config --global alias.pp 'push -u origin HEAD'

Après cela, chaque fois que je veux pousser la branche créée via la branche git -b, je peux la pousser en utilisant:

git pp

J'espère que cela fera gagner du temps à quelqu'un!

Aurimas Rekštys
la source
2

Au premier contrôle

Étape 1: git remote -v
// si trouvé git initialize puis supprimez ou sautez l'étape 2

Étape 2: git remote rm origin
// Ensuite, configurez votre adresse e-mail globalement git

Étape 3: git config --global user.email "[email protected]"

Étape 4: git initial

Étape 5: git commit -m "Initial Project"
// Si vous ajoutez déjà un dépôt de projet, passez à l'étape 6

Étape 6: git remote add origin %repo link from bitbucket.org%

Étape 7: git push -u origin master

Md.Milton
la source
1

Je viens de vivre une nouvelle permutation de ce problème.

J'ai eu une branche nommée feat/XYZ-1234-some-descriptionparce que je travaillais sur Jira numéro 1234. Pendant le travail, j'ai créé un nouveau numéro Jira pour suivre un travail plus petit, et quand je suis venu pousser, j'ai décidé de pousser vers un nom de branche avec ce nouveau numéro de problème dans:

git push -u origin feat/XYZ-5678-a-different-description # failed

Cela m'a donné l'erreur discutée dans ce fil SO. Mais comme j'essayais de pousser vers un nom de branche différent de ma branche actuelle, mon problème était différent de celui décrit ici. J'ai fini par renommer ma branche locale avant de pouvoir la pousser:

git branch -m feat/XYZ-1234-some-description feat/XYZ-5678-a-different-description
git push -u origin feat/XYZ-5678-a-different-description # now works

Après un peu plus de lecture, j'ai réalisé que j'aurais pu définir un srcsur le git push, soit sur le nom de la branche actuelle, soit juste HEADsi cela était approprié:

git push -u origin feat/XYZ-1234-some-description:feat/XYZ-5678-a-different-description # also works
Mark Birbeck
la source
-1

Si vous activez la première application de nouvelles modifications depuis votre nouvelle succursale. Et obtenir ci-dessous l'erreur:

*git push -f
fatal: The current branch Coding_Preparation has no upstream branch.

Pour pousser la branche actuelle et définir la télécommande en amont, utilisez

git push -u origin new_branch_name


** Successful Result:** 
 git push -u origin Coding_Preparation
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 599 bytes | 599.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'Coding_Preparation' on GitHub by visiting: ...
 * [new branch]      Coding_Preparation -> Coding_Preparation
Branch 'Coding_Preparation' set up to track remote branch 'Coding_Preparation' from 'origin'.
Mukesh Kumar
la source