Pourquoi dois-je faire `--set-upstream` tout le temps?

1469

Je crée une nouvelle branche dans Git:

git branch my_branch

Poussez-le:

git push origin my_branch

Maintenant, disons que quelqu'un a fait des changements sur le serveur et que je veux origin/my_branch . Je fais:

git pull

Mais je reçois:

You asked me to pull without telling me which branch you
want to merge with, and 'branch.my_branch.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.

If you often merge with the same branch, you may want to
use something like the following in your configuration file:

    [branch "my_branch"]
    remote = <nickname>
    merge = <remote-ref>

    [remote "<nickname>"]
    url = <url>
    fetch = <refspec>

See git-config(1) for details.

J'ai appris que je peux le faire fonctionner avec:

git branch --set-upstream my_branch origin/my_branch

Mais pourquoi dois-je le faire pour chaque branche que je crée? Est - il pas évident que si je pousse my_branchdans origin/my_branch, je voudrais tirer origin/my_branchen my_branch? Comment puis-je en faire le comportement par défaut?

Ram Rachum
la source
21
La valeur par défaut pour branch.autosetupmergesignifie que la configuration en amont d'une nouvelle branche n'est définie automatiquement que lors de la création d'une branche à partir d'une branche de suivi à distance (par exemple <remote-name>/<branch-name>) (voir git-config (1) ). Vous créez probablement vos succursales à partir de succursales locales existantes. Si vous vous branchez directement à partir de la pointe d'une branche distante (bien que vous soyez sur une branche locale), vous pouvez utiliser git branch my_branch <remote-name>/<branch-name>pour configurer automatiquement la configuration en amont.
Chris Johnsen
20
Pour info, l' --set-upstreamoption est déconseillée. Vous devez utiliser --trackou à la --set-upstream-toplace.
Sean the Bean du
139
si --set-upstreamest obsolète, alors les développeurs de git devraient le supprimer du message d'aide qui s'affiche lorsque vous exécutez git pushsans aucune option et qu'aucun paramètre en amont n'est défini?
Christopher Hunter
17
@ChristopherHunter Cela fait plus d'un an depuis votre commentaire et cela dit toujours cela. Est-ce juste une rétroaction bâclée ou peut-être y a-t-il une raison techniquement sage de la garder que nous ignorons?
Konrad Viltersten
15
@ChristopherHunter git branch --set-upstreamest obsolète. git push --set-upstreamn'est pas.
Brian Gordon

Réponses:

1538

Un raccourci, qui ne dépend pas de la mémorisation de la syntaxe pour git branch --set-upstream 1, consiste à:

git push -u origin my_branch

... la première fois que vous poussez cette branche. Ou, pour passer à la branche actuelle vers une branche du même nom (pratique pour un alias):

git push -u origin HEAD

Vous n'avez besoin de l'utiliser -uqu'une seule fois, et cela établit l'association entre votre branche et celle originde la même manière git branch --set-upstream.

Personnellement, je pense que c'est une bonne chose d'avoir à établir explicitement cette association entre votre branche et une sur la télécommande. C'est juste dommage que les règles soient différentes pour git pushetgit pull .


1 Cela peut sembler idiot, mais j'oublie très souvent de spécifier la branche actuelle, en supposant que c'est la valeur par défaut - ce n'est pas le cas, et les résultats sont les plus déroutants :)

Mise à jour 2012-10-11 : Apparemment, je ne suis pas la seule personne à avoir trouvé qu'il était facile de se tromper! Merci à VonC d' avoir souligné que git 1.8.0 introduit le plus évident git branch --set-upstream-to, qui peut être utilisé comme suit, si vous êtes sur la branche my_branch:

git branch --set-upstream-to origin/my_branch

... ou avec l'option courte:

git branch -u origin/my_branch

Cette modification et son raisonnement sont décrits dans les notes de publication de git 1.8.0, version candidate 1 :

C'était tentant de le dire git branch --set-upstream origin/master, mais cela indique à Git d'organiser la branche locale origin/masterpour s'intégrer à la branche actuellement extraite, ce qui est très peu probable ce que l'utilisateur voulait dire. L'option est déconseillée; utilisez plutôt la nouvelle option --set-upstream-to(avec une -uoption courte et douce ).

Mark Longair
la source
95
Notez également que même si vous oubliez la -upremière fois que vous appuyez, vous pouvez exécuter à nouveau la poussée avec ce drapeau et le suivi commencera.
Henrik N
70
Aucun de ceux-ci ne satisfait le cas d'utilisation de l'utilisation de git push sans arguments. Il reste que je dois encore me rappeler de 'git push -u origin my-branch' lorsque je déplace ma nouvelle branche vers la télécommande pour la première fois.
Karl le païen,
19
Je déteste aussi me souvenir de cette syntaxe, j'ai donc créé l'alias suivant:alias gpo="git push --set-upstream origin $(git branch | awk '/^\* / { print $2 }')"
lillialexis
99
Tout va bien, mais je pense toujours que la plainte du PO est valable. Vous démarrez une branche locale, travaillez dessus, poussez-la à l'origine pour la partager (sans arguments); pourquoi cela ne devrait-il pas régler l'amont? Est-il réellement souhaitable pour une raison quelconque de NE PAS configurer en amont lors du transfert d'une nouvelle branche vers une télécommande?
GaryO
23
Ne vaut vraiment pas le temps de dev. Pourquoi ne le fait-il pas automatiquement?
sudo
1346

Vous pouvez y arriver avec moins de frappe. Tout d'abord, changez le fonctionnement de votre push:

git config --global push.default current

Cela déduira la origin my_branchpièce, vous pouvez donc faire:

git push -u

Ce qui créera à la fois la branche distante avec le même nom et la suivra.

Zamith
la source
4
Comment se fait-il que git puisse déduire originlors de l'exécution git push -ud'une branche nouvellement créée dans un référentiel nouvellement créé? L'hypothèse est-elle que le référentiel a été cloné, la branche actuelle a donc sa valeur distante origin?
Piotr Dobrogost
74
Ce devrait être la valeur par défaut. Tant de choses dans git pourraient être plus conviviales si elles étaient livrées avec de meilleures valeurs par défaut.
phreakhead
13
Sachez que «actuel» est légèrement moins sûr que d'utiliser «simple» pour faire la même chose, voir stackoverflow.com/questions/23918062/…
Air
30
C'est le cas, mais lorsque vous essayez, pullvous devrez spécifier d'où. Le -uconfigure le suivi des succursales entre l'origine et votre dépôt local.
Zamith
7
Bien que marginalement pratique, cela exige toujours qu'une commande différente soit exécutée pour la première et la seule push- ce qui bat tout le point de cette question. Bref, il n'y a pas de bonne réponse. Que les développeurs de Git insistent pour conserver cette expérience utilisateur maladroite (AUX) face à la dissidence communautaire généralisée est ... instructif. Et décourageant. (Surtout décourageant.)
Cecil Curry
87

Vous pouvez simplement

git checkout -b my-branch origin/whatever

en premier lieu. Si vous définissez branch.autosetupmergeou branch.autosetuprebase(mon préféré) sur always(la valeur par défaut est true), my-branchsera automatiquement suivi origin/whatever.

Tu vois git help config.

cdunn2001
la source
5
Cela produit «fatal: impossible de mettre à jour les chemins d'accès et de passer en même temps à la branche« ma-branche ».»
Karl le païen,
12
Soit dit en passant, j'ai généralement juste git checkout -t origin/whatever, qui choisit également whatevercomme nouveau nom de branche. Très pratique!
cdunn2001
2
@cdunn Celui-ci est idéal, mais peu cohérent. Le drapeau doit être appelé -u/ --set-upstream.
Tobu
1
git checkout -t origin/whateverne fonctionne pas pour moi lorsque j'essaye de créer une nouvelle branche:fatal: Cannot update paths and switch to branch 'whatever' at the same time.
wisbucky
1
git checkout -b my-branch origin/whatevera également la même erreur (j'essaie de créer une nouvelle branche qui n'existe pas sur local ou distant): fatal: Cannot update paths and switch to branch 'whatever' at the same time.
wisbucky
81

Ceci est mon utilisation la plus courante pour The Fuck .

$ git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin master

$ fuck
git push --set-upstream origin master [enter/↑/↓/ctrl+c]
Counting objects: 9, done.
...

De plus, il est amusant de taper des jurons dans votre terminal.

Tamlyn
la source
Cela doit donc être porté sur Windows (ou au moins git-bash).
BrianHVB
1
et bien cette petite découverte vient de faire ma journée. merci
Ivan Durst
Magnifique outil, merci!
Yurii
81

Vous pouvez configurer l'amont plus simplement de deux manières. Tout d'abord lorsque vous créez la branche:

git branch -u origin/my-branch

ou après avoir créé une branche, vous pouvez utiliser cette commande.

git push -u origin my-branch

Vous pouvez également créer des branches, extraire et configurer en amont en une seule commande:

git checkout -b my-branch -t origin/my-branch

Ma préférence personnelle est de le faire dans une commande en deux étapes:

git checkout -b my-branch
git push -u origin my-branch
Tzen
la source
1
Très bonne réponse! Répond aux deux cas d'utilisation courants. Après avoir exécuté, git branch -u origin/my-branchje peux exécuter git pullpour retirer mes modifications.
Benjamin Atkin
2
"git checkout -b my-branch -t origin / my-branch" cela ne fonctionne pas si 'origin / my-branch' n'existe pas encore.
Spongman
1
En fait, vous pouvez simplement vous git checkout -t origin/my-branchpasser de -b my-branch, il déduira automatiquement my-branchle nom de la branche locale. Cependant, comme @Spongman l'a mentionné, cette commande ne fonctionne pas si elle origin/my-branchn'existe pas en premier.
wisbucky
Oui, cela fonctionnera @wisbucky, -t fonctionne très bien. Personnellement, même deux ans après avoir écrit cette réponse, je préfère toujours le fractionnement en deux lignes avec checkout -b et push -u. C'est plus explicite et aucune erreur lors du paiement -b quand je n'ai pas de télécommande - ce qui arrive assez souvent lors des expérimentations :)
Tzen
2
git push -u origin/my-branchéchoue pour moi avec fatal: 'origin/my-branch' does not appear to be a git repository. Cela fonctionne:git push -u origin my-branch
stason
48

Vous pouvez utiliser:

git config --global branch.autosetupmerge toujours

qui liera la branche en amont chaque fois que vous créez ou extrayez une nouvelle branche.

Voir https://felipec.wordpress.com/2013/09/01/advanced-git-concepts-the-upstream-tracking-branch/

Cela fonctionne également avec branch.autosetuprebase , si vous suivez un flux de travail plus axé sur le rebase, mais ne l'utilisez pas à moins que vous ne sachiez ce que vous faites, car cela entraînera par défaut votre comportement d'extraction pour rebaser, ce qui peut entraîner des résultats étranges.

Daniel
la source
8
Ne fonctionne pas, je reçois toujours le --set-upstreammessage
Dorian
2
@ Dorian, vous devez le définir avant de créer la branche. Voir stackoverflow.com/a/9753268/263998
cdunn2001
8
mais cela ne définit pas la branche de suivi comme distante avec la même branche, mais vers la branche locale actuelle .. donc quand vous poussez, elle essaiera de pousser vers la branche LOCALE que vous étiez avant de créer la nouvelle branche ..
Arnold Roa
1
Cela a un comportement encore plus étrange que celui par défaut. Si vous basez le travail sur une branche, cela agit vraiment étrangement.
Beefster
1
Soyez prudent avec ce paramètre !! Après l'avoir défini, vous obtenez ce comportement. 1. Basculez vers master. 2. Exécutez git checkout -b new_branch. 3. Ajoutez un commit à cette branche. 4 git push origin new_branch.. Cela pousse ce commit vers la masterbranche d'origine (plutôt que vers une nouvelle branche d'origine appelée new_branch).
stwr667
38

Par ailleurs, le raccourci pour pousser la branche actuelle vers une télécommande du même nom:

$ git push -u origin HEAD
djanowski
la source
22

J'utilise personnellement ces alias suivants dans bash

dans le fichier ~ / .gitconfig

[alias]
    pushup = "!git push --set-upstream origin $(git symbolic-ref --short HEAD)"

et dans le fichier ~ / .bashrc ou ~ / .zshrc

alias gpo="git pushup"
alias gpof="gpo -f"
alias gf="git fetch"
alias gp="git pull"
Amrit Shrestha
la source
1
Je n'avais besoin que de hcange .gitconfig, puis j'ai pu utiliser la commande git pushupqui pousse toujours la branche courante à l'origine. Je peux toujours simplement utiliser à la git pushupplace de git push👍
theespacecamel
18

Si ce qui suit ne fonctionne pas:

git config --global push.default current

Vous devez également mettre à jour la configuration locale de votre projet, car il est possible que votre projet ait des configurations git locales:

git config --local push.default current
youngrrrr
la source
2
Plus d'explications seraient super. Que fait la première ligne?
papillon
3
Cette réponse est celle qui se sent légitime. Tous ceux qui proposent des alias sont des solutions de contournement stupides. Et les autres justifiant la mémorisation de longues séquences de commandes sont pédantes.
MarkHu
10

Vous pouvez également dire explicitement à git pull quelle branche distante tirer (comme il le mentionne dans le message d'erreur):

git pull <remote-name> <remote-branch>

Attention cependant: si vous êtes sur une branche différente et effectuez un pull explicite, la refspec que vous tirez sera fusionnée dans la branche sur laquelle vous vous trouvez!

mtbkrdave
la source
10

Pour ce que cela vaut, si vous essayez de suivre une branche qui existe déjà sur la télécommande (par exemple, origin / somebranch) mais ne l'avez pas encore vérifiée localement, vous pouvez faire:

$ git checkout --track origin/somebranch

Remarque: «-t» est la version abrégée de l'option «--track».

Cela crée la même association dès le départ.

mataculaire
la source
5
Vous pouvez simplement commander à la succursale. git checkout somebranchEst donc équivalent.
Zamith
2
@Zamith Cela ne fonctionne-t-il qu'après avoir appelé git fetchimmédiatement à l'avance?
Walter Roman
1
Pas immédiatement, mais oui, vous devez avoir une référence à cette branche sur votre référentiel local, ce qui se produit chaque fois que vous appelez git fetchou git pull. Je n'ai cependant jamais trouvé que c'était un problème.
Zamith
10
git branch --set-upstream-to=origin/master<branch_name>

la source
9

J'utilise cet alias Git au lieu de copier / coller la suggestion de Git à chaque fois: https://gist.github.com/ekilah/88a880c84a50b73bd306

Source copiée ci-dessous (ajoutez ceci à votre ~/.gitconfigfichier):

[alias]
  pushup = "!gitbranchname() { git symbolic-ref --short HEAD; }; gitpushupstream() { git push --set-upstream origin `gitbranchname`; }; gitpushupstream"
manroe
la source
7

Vous pouvez configurer un très bon alias qui peut gérer cela sans la syntaxe trop verbeuse.

J'ai l'alias suivant dans ~/.gitconfig:

po = "!git push -u origin \"$(git rev-parse --abbrev-ref HEAD)\""

Après avoir effectué une validation sur une nouvelle branche, vous pouvez pousser votre nouvelle branche en tapant simplement la commande:

git po
123
la source
pourquoi po? push origin? que se passe-t-il si cela est exécuté plusieurs fois?
Arnold Roa
Oui, comme dans l'origine push. Rien ne se produit s'il est exécuté plusieurs fois. J'ai également un git push -falias configuré git pf, donc je l'utilise une fois que l'origine a déjà été poussée.
123
voir le commentaire de djanowski , vous pouvez directement utiliserHEAD
arhak
3

Pour ceux qui recherchent un alias qui fonctionne avec git pull, voici ce que j'utilise:

alias up="git branch | awk '/^\\* / { print \$2 }' | xargs -I {} git branch --set-upstream-to=origin/{} {}"

Maintenant, chaque fois que vous obtenez:

$ git pull
There is no tracking information for the current branch.
...

Exécutez simplement:

$ up
Branch my_branch set up to track remote branch my_branch from origin.
$ git pull

Et tu es prêt à partir

jchavannes
la source
2

Parce que git a la capacité intéressante de pousser / tirer différentes branches vers différents référentiels "en amont". Vous pouvez même utiliser des référentiels séparés pour pousser et tirer - sur la même branche. Cela peut créer un flux distribué à plusieurs niveaux, je peux voir que cela est utile sur des projets tels que le noyau Linux. Git a été initialement construit pour être utilisé sur ce projet.

Par conséquent, il ne fait aucune hypothèse sur le repo que votre succursale devrait suivre.

D'un autre côté, la plupart des gens n'utilisent pas git de cette façon, cela pourrait donc être un bon argument pour une option par défaut.

Git est généralement assez bas et cela peut être frustrant. Pourtant, il existe des interfaces graphiques et il devrait être facile d'écrire des scripts d'assistance si vous souhaitez toujours l'utiliser à partir du shell.

Rolf
la source
2

Vous pouvez aussi faire git push -u origin $(current_branch)

ourmaninamsterdam
la source
0

J'ai en quelque sorte redécouvert à legitcause de ce problème (OS X uniquement). Maintenant, tout ce que j'utilise lors du branchement sont ces deux commandes:

legit publish [<branch>] Publie la branche spécifiée sur la télécommande. (alias: pub)

legit unpublish <branch> Supprime la branche spécifiée de la télécommande. (alias: unp)

SublimeGit est livré avec un legitsupport par défaut, ce qui rend la routine de branchement complète aussi simple que d'appuyer sur Ctrl-b.

Benny K
la source
0

Nous utilisons phabricator et ne poussons pas avec git. J'ai dû créer un alias bash qui fonctionne sous Linux / mac

vim ~/.bash_aliases

new_branch() {
    git checkout -b "$1"
    git branch --set-upstream-to=origin/master "$1"
}

enregistrer

source ~/.bash_aliases
new_branch test #instead of git checkout -b test
git pull
om471987
la source
0

Voici un alias bash pour git push qui peut être exécuté en toute sécurité pour chaque push et basculera automatiquement entre la configuration en amont pour la première push, puis les push normales après cela.

alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push'

Message d'origine

Loren
la source