Warum muss ich die ganze Zeit "--set-upstream" machen?

1468

Ich erstelle einen neuen Zweig in Git:

git branch my_branch

Drück es:

git push origin my_branch

Angenommen, jemand hat einige Änderungen am Server vorgenommen, und ich möchte abrufen origin/my_branch. Ich mache:

git pull

Aber ich verstehe:

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.

Ich habe gelernt, dass ich es schaffen kann mit:

git branch --set-upstream my_branch origin/my_branch

Aber warum muss ich das für jeden Zweig tun, den ich erstelle? Ist es nicht klar , dass , wenn ich schiebe my_branchin origin/my_branch, dann würde ich ziehen will origin/my_branchin my_branch? Wie kann ich dies zum Standardverhalten machen?

Ram Rachum
quelle
21
Der Standardwert für branch.autosetupmergebedeutet, dass die Upstream-Konfiguration für einen neuen Zweig nur automatisch festgelegt wird, wenn ein Zweig aus einem Remote-Tracking-Zweig erstellt wird (z. B. <remote-name>/<branch-name>) (siehe git-config (1) ). Sie erstellen Ihre Filialen wahrscheinlich aus vorhandenen lokalen Filialen. Wenn Sie effektiv direkt von der Spitze eines Remote-Zweigs verzweigen (obwohl Sie sich in einem lokalen Zweig befinden), können Sie git branch my_branch <remote-name>/<branch-name>die Upstream-Konfiguration automatisch einrichten.
Chris Johnsen
20
Zu Ihrer Information, die --set-upstreamOption ist veraltet. Sie sollten --trackoder --set-upstream-tostattdessen verwenden.
Sean the Bean
139
Wenn dies --set-upstreamveraltet ist, sollten die Git-Entwickler es möglicherweise aus der Hilfemeldung entfernen, die angezeigt wird, wenn Sie git pushohne Optionen ausgeführt werden und kein Upstream festgelegt ist.
Christopher Hunter
17
@ChristopherHunter Seit deinem Kommentar ist über ein Jahr vergangen und das steht immer noch . Ist es nur ein schlampiges Feedback oder gibt es vielleicht einen technisch klugen Grund, es beizubehalten, über den wir nichts wissen?
Konrad Viltersten
15
@ChristopherHunter git branch --set-upstreamist veraltet. git push --set-upstreamist nicht.
Brian Gordon

Antworten:

1538

Eine Verknüpfung, die nicht davon abhängt, sich die Syntax für git branch --set-upstream 1 zu merken, lautet:

git push -u origin my_branch

... das erste Mal, dass Sie diesen Zweig schieben. Oder um zum aktuellen Zweig zu einem gleichnamigen Zweig zu wechseln (praktisch für einen Alias):

git push -u origin HEAD

Sie müssen es nur -ueinmal verwenden, und das stellt die Zuordnung zwischen Ihrem Zweig und dem Zweig auf origindie gleiche Weise her wie zuvor git branch --set-upstream.

Persönlich halte ich es für eine gute Sache, diese Zuordnung zwischen Ihrem Zweig und einem Zweig auf der Fernbedienung explizit einrichten zu müssen. Es ist nur eine Schande, dass die Regeln für git pushund unterschiedlich sindgit pull .


1 Es mag albern klingen, aber ich vergesse sehr häufig, den aktuellen Zweig anzugeben, vorausgesetzt, dies ist die Standardeinstellung - dies ist nicht der Fall, und die Ergebnisse sind höchst verwirrend :)

Update 11.10.2012 : Anscheinend bin ich nicht die einzige Person, die es leicht fand, sich zu irren! Vielen Dank an VonC für den Hinweis, dass Git 1.8.0 das Offensichtlichere einführt git branch --set-upstream-to, das wie folgt verwendet werden kann, wenn Sie sich in der Branche befinden my_branch:

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

... oder mit der kurzen Option:

git branch -u origin/my_branch

Diese Änderung und ihre Begründung sind in den Versionshinweisen zu git 1.8.0, Versionskandidat 1, beschrieben :

Es war verlockend zu sagen git branch --set-upstream origin/master, aber das veranlasst Git, den lokalen Zweig so zu arrangieren, dass er in origin/masterden aktuell ausgecheckten Zweig integriert wird, was höchst unwahrscheinlich ist, was der Benutzer meinte. Die Option ist veraltet. Verwenden Sie stattdessen die neue Option --set-upstream-to(kurz und bündig -u).

Mark Longair
quelle
95
Beachten -uSie auch, dass Sie den Push mit diesem Flag erneut ausführen können , auch wenn Sie das erste Mal vergessen haben, wenn Sie drücken. Dadurch wird die Verfolgung gestartet.
Henrik N
70
Keines davon erfüllt den Anwendungsfall der Verwendung von Git Push ohne Argumente. Es bleibt, dass ich mich immer noch daran erinnern muss, 'git push -u origin my-branch' zu verwenden, wenn ich meinen neuen Zweig zum ersten Mal auf die Fernbedienung verschiebe.
Karl der Heide
19
Ich hasse es, mich auch an diese Syntax zu erinnern, deshalb habe ich den folgenden Alias ​​erstellt:alias gpo="git push --set-upstream origin $(git branch | awk '/^\* / { print $2 }')"
lillialexis
99
Das ist alles in Ordnung, aber ich denke immer noch, dass die Beschwerde des OP gültig ist. Sie starten einen lokalen Zweig, arbeiten daran und verschieben ihn zum Teilen, um ihn zu teilen (ohne Argumente). Warum sollte das nicht den Upstream einstellen? Ist es aus irgendeinem Grund tatsächlich wünschenswert, NICHT stromaufwärts einzurichten, wenn ein neuer Zweig auf eine Fernbedienung übertragen wird?
GaryO
23
Total keine Entwicklungszeit wert. Warum macht es das nicht einfach automatisch?
Sudo
1346

Sie können dies mit weniger Eingabe erreichen. Ändern Sie zunächst die Funktionsweise Ihres Push:

git config --global push.default current

Dadurch wird auf den origin my_branchTeil geschlossen, sodass Sie Folgendes tun können:

git push -u

Dadurch wird der Remote-Zweig mit demselben Namen erstellt und verfolgt.

Zamith
quelle
4
Wie kommt es, dass Git schließen kann, originwenn ein git push -uneu erstellter Zweig im neu erstellten Repository ausgeführt wird? Ist die Annahme, dass das Repository geklont wurde, so dass der Remote-Zweig des aktuellen Zweigs eingestellt ist origin?
Piotr Dobrogost
73
Dies sollte die Standardeinstellung sein. So viele Dinge in Git könnten benutzerfreundlicher sein, wenn es nur mit besseren Standardeinstellungen geliefert würde.
Phreakhead
13
Beachten Sie, dass "aktuell" etwas unsicherer ist als die Verwendung von "einfach", um dasselbe zu tun. Siehe stackoverflow.com/questions/23918062/…
Air
30
Es funktioniert, aber wenn Sie es versuchen, müssen pullSie angeben, von wo. Die -uSätze auf dem Zweig - Tracking zwischen Herkunft und Ihrem lokalen Repo.
Zamith
7
Während geringfügig bequem, diese noch Mandate , dass ein anderer Befehl für die erste und nur ausgeführt werden push- die den gesamten Punkt dieser Frage besiegt. Kurz gesagt, es gibt keine gute Antwort. Dass Git-Entwickler darauf bestehen, dieses ungeschickte Benutzererlebnis (AUX) angesichts weit verbreiteter Meinungsverschiedenheiten in der Community beizubehalten, ist ... aufschlussreich. Und entmutigend. (Meistens entmutigend.)
Cecil Curry
87

Sie können einfach

git checkout -b my-branch origin/whatever

an erster Stelle. Wenn Sie branch.autosetupmergeoder branch.autosetuprebase(mein Favorit) auf always(Standard ist true) setzen, my-branchwird automatisch verfolgt origin/whatever.

Siehe git help config.

cdunn2001
quelle
5
Dies führt zu "fatal: Pfade können nicht aktualisiert und gleichzeitig zur Verzweigung 'my-branch' gewechselt werden."
Karl der Heide
12
Übrigens habe ich normalerweise nur git checkout -t origin/whatever, was auch whateverals neuer Filialname wählt . Sehr angenehm!
cdunn2001
2
@cdunn Dieser ist ideal, aber kaum konsistent. Die Flagge sollte -u/ heißen --set-upstream.
Tobu
1
git checkout -t origin/whateverfunktioniert nicht für mich, wenn ich versuche, einen neuen Zweig zu erstellen:fatal: Cannot update paths and switch to branch 'whatever' at the same time.
wisbucky
1
git checkout -b my-branch origin/whateverhat auch den gleichen Fehler (ich versuche, einen neuen Zweig zu erstellen, der nicht auf lokaler oder Remote- fatal: Cannot update paths and switch to branch 'whatever' at the same time.
Ebene
81

Dies ist meine häufigste Verwendung für 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.
...

Außerdem macht es Spaß, Schimpfwörter in Ihr Terminal einzugeben.

Tamlyn
quelle
Dies muss also auf Windows portiert werden (oder zumindest auf Git-Bash).
BrianHVB
1
Nun, diese kleine Entdeckung hat mir gerade den Tag gemacht. Vielen Dank
Ivan Durst
Tolles Werkzeug, danke!
Yurii
81

Sie können Upstream auf zwei Arten einfacher einrichten. Zuerst, wenn Sie den Zweig erstellen:

git branch -u origin/my-branch

oder nachdem Sie einen Zweig erstellt haben, können Sie diesen Befehl verwenden.

git push -u origin my-branch

Sie können auch in einem einzigen Befehl verzweigen, auschecken und Upstream einrichten:

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

Ich persönlich bevorzuge dies in einem zweistufigen Befehl:

git checkout -b my-branch
git push -u origin my-branch
Tzen
quelle
1
Gute Antwort! Behandelt beide gängigen Anwendungsfälle. Nach dem Laufen git branch -u origin/my-branchkann ich laufen git pull, um meine Änderungen abzurufen.
Benjamin Atkin
2
"git checkout -b my-branch -t origin / my-branch" funktioniert nicht, wenn 'origin / my-branch' noch nicht existiert.
Spongman
1
Sie können tatsächlich einfach auf das git checkout -t origin/my-branchverzichten -b my-branch, es wird nur automatisch auf my-branchden lokalen Filialnamen geschlossen. Wie @Spongman bereits erwähnt hat, funktioniert dieser Befehl jedoch nicht, wenn er origin/my-branchnicht zuerst vorhanden ist.
wisbucky
Ja, wird @wisbucky funktionieren, -t funktioniert gut. Persönlich bevorzuge ich es jedoch, auch zwei Jahre nachdem ich diese Antwort geschrieben habe, mit checkout -b und push -u in zwei Zeilen aufzuteilen. Es ist expliziter und kein Fehler beim Auschecken -b, wenn ich keine Fernbedienung habe - was ziemlich oft beim Experimentieren passiert :)
Tzen
2
git push -u origin/my-branchscheitert für mich mit fatal: 'origin/my-branch' does not appear to be a git repository. Dies funktioniert:git push -u origin my-branch
Stason
48

Sie können verwenden:

git config --global branch.autosetupmerge immer

Dadurch wird der Upstream-Zweig jedes Mal verknüpft, wenn Sie einen neuen Zweig erstellen oder auschecken.

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

Dies funktioniert auch branch.autosetuprebase, wenn Sie einem auf Rebase ausgerichteten Workflow folgen, diesen jedoch nur verwenden, wenn Sie wissen, was Sie tun, da Ihr Pull-Verhalten standardmäßig auf Rebase basiert, was zu merkwürdigen Ergebnissen führen kann.

Daniel
quelle
8
Funktioniert nicht, ich bekomme immer noch die --set-upstreamNachricht
Dorian
2
@Dorian, Sie müssen dies festlegen, bevor Sie den Zweig erstellen. Siehe stackoverflow.com/a/9753268/263998
cdunn2001
8
Dadurch wird jedoch nicht der Tracking-Zweig als Remote-Zweig mit demselben Zweig festgelegt, sondern der aktuelle lokale Zweig. Wenn Sie also pushen, wird versucht, auf den LOCAL-Zweig zu pushen, den Sie vor dem Erstellen des neuen Zweigs hatten.
Arnold Roa
1
Dies hat ein noch seltsameres Verhalten als die Standardeinstellung. Wenn Sie von einem Zweig aus arbeiten, verhält es sich wirklich seltsam.
Beefster
1
Seien Sie vorsichtig mit dieser Einstellung! Nach dem Einstellen erhalten Sie dieses Verhalten. 1. Wechseln Sie zu master. 2. Führen Sie aus git checkout -b new_branch. 3. Fügen Sie diesem Zweig ein Commit hinzu. 4. git push origin new_branch. Dadurch wird das Commit auf den masterZweig am Ursprung übertragen (und nicht auf einen neuen Zweig am Ursprung mit dem Namen new_branch).
stwr667
38

Übrigens die Verknüpfung zum Verschieben des aktuellen Zweigs auf eine Fernbedienung mit demselben Namen:

$ git push -u origin HEAD
Djanowski
quelle
22

Ich persönlich verwende diesen folgenden Alias ​​in Bash

in der Datei ~ / .gitconfig

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

und in der Datei ~ / .bashrc oder ~ / .zshrc

alias gpo="git pushup"
alias gpof="gpo -f"
alias gf="git fetch"
alias gp="git pull"
Amrit Shrestha
quelle
1
Ich musste nur .gitconfig ändern, dann konnte ich den Befehl verwenden, git pushupder den aktuellen Zweig immer zum Ursprung schiebt. Ich kann immer nur git pushupanstelle von git push👍
thespacecamel
18

Wenn das Folgende nicht funktioniert:

git config --global push.default current

Sie sollten auch die lokale Konfiguration Ihres Projekts aktualisieren, da Ihr Projekt möglicherweise lokale Git-Konfigurationen hat:

git config --local push.default current
youngrrrr
quelle
2
Weitere Erklärungen wären toll. Was macht die erste Zeile?
Papillon
3
Diese Antwort fühlt sich echt an. Alle, die Aliase vorschlagen, sind dumme Problemumgehungen. Und die anderen, die das Auswendiglernen langer Befehlssequenzen rechtfertigen, sind pedantisch.
MarkHu
10

Sie können git pull auch explizit mitteilen, welcher Remote-Zweig abgerufen werden soll (wie in der Fehlermeldung erwähnt):

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

Seien Sie jedoch vorsichtig: Wenn Sie sich in einem anderen Zweig befinden und einen expliziten Pull ausführen, wird die von Ihnen gezogene Referenz mit dem Zweig zusammengeführt, in dem Sie sich befinden!

mtbkrdave
quelle
10

Wenn Sie versuchen, einen Zweig zu verfolgen, der bereits auf der Fernbedienung vorhanden ist (z. B. origin / somebranch), ihn aber noch nicht lokal ausgecheckt hat, können Sie Folgendes tun:

$ git checkout --track origin/somebranch

Hinweis: '-t' ist die verkürzte Version der Option '--track'.

Dies schafft die gleiche Assoziation auf Anhieb.

mattacular
quelle
5
Sie können tatsächlich nur zur Filiale auschecken. Ist git checkout somebranchalso gleichwertig.
Zamith
2
@Zamith Funktioniert das nicht erst, nachdem Sie vorher angerufen git fetchhaben?
Walter Roman
1
Nicht sofort, aber ja, Sie müssen einen Verweis auf diesen Zweig in Ihrem lokalen Repo haben, was immer dann passiert, wenn Sie anrufen git fetchoder git pull. Ich habe jedoch nie festgestellt, dass dies ein Problem ist.
Zamith
10
git branch --set-upstream-to=origin/master<branch_name>

quelle
9

Ich verwende diesen Git-Alias, anstatt den Vorschlag von Git jedes Mal zu kopieren / einzufügen: https://gist.github.com/ekilah/88a880c84a50b73bd306

Quelle unten kopiert (fügen Sie diese Ihrer ~/.gitconfigDatei hinzu):

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

Sie können einen wirklich guten Alias ​​einrichten, der dies ohne die übermäßig ausführliche Syntax handhabt.

Ich habe den folgenden Alias ​​in ~/.gitconfig:

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

Nachdem Sie einen Commit für einen neuen Zweig vorgenommen haben, können Sie Ihren neuen Zweig verschieben, indem Sie einfach den folgenden Befehl eingeben:

git po
123
quelle
warum po? push origin? Was passiert, wenn dies mehrmals ausgeführt wird?
Arnold Roa
Ja, wie bei Push Origin. Nichts passiert, wenn es mehrmals ausgeführt wird. Ich habe auch einen git push -fAlias ​​eingerichtet git pf, also benutze ich diesen, sobald der Ursprung bereits verschoben wurde.
123
Siehe Djanowskis Kommentar , den Sie direkt verwenden könnenHEAD
Arhak
3

Für diejenigen, die nach einem Alias ​​suchen, der funktioniert git pull, verwende ich Folgendes:

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

Wann immer Sie bekommen:

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

Renn einfach:

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

Und du kannst loslegen

jchavannes
quelle
2

Weil Git die coole Fähigkeit hat, verschiedene Zweige in verschiedene "Upstream" -Repositorys zu schieben / ziehen. Sie können sogar separate Repositorys zum Drücken und Ziehen verwenden - auf demselben Zweig. Dies kann einen verteilten, mehrstufigen Fluss erzeugen. Ich kann sehen, dass dies bei Projekten wie dem Linux-Kernel nützlich ist. Git wurde ursprünglich für dieses Projekt entwickelt.

Infolgedessen wird nicht davon ausgegangen, welches Repo Ihre Filiale verfolgen soll.

Auf der anderen Seite verwenden die meisten Leute git nicht auf diese Weise, daher ist dies möglicherweise ein gutes Argument für eine Standardoption.

Git ist im Allgemeinen ziemlich niedrig und es kann frustrierend sein. Es gibt jedoch GUIs, und es sollte einfach sein, Hilfsskripte zu schreiben, wenn Sie sie weiterhin über die Shell verwenden möchten.

Rolf
quelle
2

Sie können auch tun git push -u origin $(current_branch)

ourmaninamsterdam
quelle
0

Ich habe es legitaufgrund dieses Problems wiederentdeckt (nur OS X). Jetzt verwende ich beim Verzweigen nur noch diese beiden Befehle:

legit publish [<branch>] Veröffentlicht den angegebenen Zweig auf der Fernbedienung. (alias: pub)

legit unpublish <branch> Entfernt den angegebenen Zweig von der Fernbedienung. (alias: unp)

SublimeGit kommt mit legitUnterstützung standardmäßig die ganze Verzweigung Routine so einfach wie Drücken von Strg-b macht.

Benny K.
quelle
0

Wir benutzen Phabricator und pushen nicht mit Git. Ich musste einen Bash-Alias ​​erstellen, der unter Linux / Mac funktioniert

vim ~/.bash_aliases

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

speichern

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

Hier ist ein Bash-Alias ​​für Git-Push, der für jeden Push sicher ausgeführt werden kann und automatisch zwischen der Einstellung des Upstreams für den ersten Push und dem anschließenden normalen Push umschaltet.

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

Ursprünglicher Beitrag

Loren
quelle