为什么我需要一直做“ --set-upstream”?


1464

我在Git中创建一个新分支:

git branch my_branch

推它:

git push origin my_branch

现在说有人在服务器上做了一些更改,我想退出origin/my_branch。我做:

git pull

但是我得到:

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.

我了解到可以使其与以下产品一起使用:

git branch --set-upstream my_branch origin/my_branch

但是,为什么我需要为我创建的每个分支都执行此操作?如果我推my_branch入就很明显origin/my_branch,那我想拉origin/my_branch进去my_branch吗?如何使它成为默认行为?


21
默认为branch.autosetupmerge表示仅在从远程跟踪分支(例如<remote-name>/<branch-name>)创建分支时自动设置新分支的上游配置(请参阅git-config(1))。您可能是从现有的本地分支创建分支。如果您是直接从远程分支的顶端有效分支(尽管位于本地分支上),则可以使用它git branch my_branch <remote-name>/<branch-name>来自动设置上游配置。
克里斯·约翰森

20
仅供参考,该--set-upstream选项已弃用。您应该使用--track--set-upstream-to代替。
肖恩·比恩

139
如果--set-upstream已弃用,那么git devs应该从git push没有选项且没有设置上游运行时显示的帮助消息中删除它吗?
Christopher Hunter

17
@ChristopherHunter自您发表评论以来已有一年多了,它仍然表明了这一点。这只是草率的反馈,还是有我们不了解的技术上合理的理由来解决?
Konrad Viltersten '16

15
@ChristopherHunter git branch --set-upstream已过时。git push --set-upstream不是。
布莱恩·戈登

Answers:


1536

不依赖于记住git branch --set-upstream 1的语法的快捷方式是:

git push -u origin my_branch

...第一次按下该分支。或者,将当前分支推送到同名的分支(方便使用别名):

git push -u origin HEAD

您只需要使用-u一次,即可以与您origin相同的方式在分支和分支之间建立关联git branch --set-upstream

就个人而言,我认为必须在分支机构与远程分支机构之间明确建立关联是一件好事。规则git push和有所不同,git pull真是遗憾。


1这听起来可能很愚蠢,但是我经常忘记指定当前分支,假设这是默认分支-不是,并且结果最令人困惑:)

2012-10-11更新:显然我不是唯一容易出错的人!感谢VonC指出git 1.8.0引入了更明显的git branch --set-upstream-to,如果您在分支上,可以按以下方式使用它my_branch

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

...或使用简短选项:

git branch -u origin/my_branch

git 1.8.0的发行说明(候选发行版1)中描述了此更改及其原因:

这很吸引人git branch --set-upstream origin/master,但是这告诉Git安排本地分支origin/master与当前已签出的分支集成,这在用户看来是不太可能的。该选项已弃用;而是使用新的--set-upstream-to(带有简短说明-u)选项。


95
另请注意,即使您忘记了-u第一次推送,也可以使用该标志再次运行推送,它将开始跟踪。
Henrik N

70
这些都不满足使用不带参数的git push的用例。仍然需要记住的是,当我第一次将新分支移动到远程服务器时,我仍然必须记住“ git push -u origin my-branch”。
异教徒卡尔(Karl the Pagan)

19
我也alias gpo="git push --set-upstream origin $(git branch | awk '/^\* / { print $2 }')"
不想

99
一切都很好,但我仍然认为OP的投诉是有效的。您启动一个本地分支,对其进行处理,将其推送到源以共享(无参数);为什么不设置上游呢?出于某种原因,实际上是否需要在将新分支推送到远程时不设置上游?
GaryO 2013年

23
完全不值得花时间。为什么不自动执行呢?
sudo

1346

您可以通过减少键入次数来实现这一目标。首先,更改您的推送工作方式:

git config --global push.default current

这将推断出该origin my_branch零件,因此您可以执行以下操作:

git push -u

这将创建具有相同名称的远程分支并对其进行跟踪。


4
在新创建的存储库中为新创建的分支origin运行时git push -u,git如何推断?是否假设已经克隆了存储库,因此当前分支的远程设置为origin
Piotr Dobrogost,2015年

73
这应该是默认值。如果git中有很多东西,如果它附带了更好的默认值,可能会更加用户友好。
phreakhead

13
要知道,“当前”略unsafer比使用“简单”做同样的事情,看到stackoverflow.com/questions/23918062/...
航空

30
确实如此,但是当您尝试尝试时,pull您必须指定从何处开始。该-u套了原产地和当地的回购之间的分支跟踪。
扎米思'17

7
尽管勉强方便,但这仍然要求首先执行唯一的命令push,这是整个问题的根本。简而言之,没有好的答案。Git开发人员在面对广泛的社区异议的情况下坚持保留这种尴尬的用户体验(AUX)是令人鼓舞的。和令人沮丧。(最令人沮丧的)
塞西尔·库里

87

你可以简单地

git checkout -b my-branch origin/whatever

首先。如果您将branch.autosetupmergebranch.autosetuprebase(我的最爱)设置为always(默认为true),my-branch将自动跟踪origin/whatever

请参阅git help config


5
这将产生“致命错误:无法更新路径并不能同时切换到分支'my-branch'”。
异教徒卡尔(Karl the Pagan)

12
顺便说一句,我通常只是git checkout -t origin/whatever,它也选择whatever作为新的分支名称。很方便!
cdunn2001

2
@cdunn这是理想的方法,但并不一致。该标志应称为-u/ --set-upstream
东武

1
git checkout -t origin/whatever尝试创建新分支时对我不起作用:fatal: Cannot update paths and switch to branch 'whatever' at the same time.
wisbucky

1
git checkout -b my-branch origin/whatever也有相同的错误(我正在尝试创建本地或远程fatal: Cannot update paths and switch to branch 'whatever' at the same time.
站点

81

您可以通过两种方式将上游设置得更简单。首先,当您创建分支时:

git branch -u origin/my-branch

或者在创建分支之后,可以使用此命令。

git push -u origin my-branch

您还可以在单​​个命令中分支,检出并设置上游:

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

我个人更喜欢通过两步命令来执行此操作:

git checkout -b my-branch
git push -u origin my-branch

1
好答案!解决两个常见的用例。运行后,git branch -u origin/my-branch我可以运行git pull以撤消更改。
本杰明·阿特金

2
如果“ origin / my-branch”还不存在,“ git checkout -b my-branch -t origin / my-branch”将不起作用。
Spongman '17

1
实际上,您实际上可以git checkout -t origin/my-branch不使用-b my-branch,而是会自动推断出my-branch本地分支名称。但是,正如@Spongman所提到的,如果origin/my-branch不首先存在此命令将不起作用。
Wisbucky

是的,可以使用@ wisbucky,-t也可以。但是,就我个人而言,即使在我写了该答复的两年后,我仍然更喜欢使用checkout -b和push -u分成两行。当我没有远程操作时,它更明确并且在结帐-b时没有错误-实验时经常发生:)
Tzen

2
git push -u origin/my-branch对我失败fatal: 'origin/my-branch' does not appear to be a git repository。这有效:git push -u origin my-branch
stason

79

这是我最常使用的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.
...

另外,在终端中输入粗话也很有趣。


因此,需要将其移植到Windows(或至少移植到git-bash)。
BrianHVB

1
好吧,这个小发现让我很开心。谢谢
伊万·杜斯特

宏伟的工具,谢谢!
尤里

48

您可以使用:

git config --global branch.autosetupmerge总是

每次您创建或签出新分支时,它将链接上游分支。

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

这也适用于branch.autosetuprebase,如果按照更重订重点工作流程,但不要使用,除非你知道你在做什么,因为它会默认你的拉行为底垫中,这可能会导致奇怪的结果。


8
不起作用,我仍然收到--set-upstream消息
Dorian

2
@Dorian,必须在创建分支之前进行设置。参见stackoverflow.com/a/9753268/263998
cdunn2001年

8
但这并没有设置跟踪分支与同一分支远端,但目前当地分公司..所以当你按下它会尝试推到本地分支你是创建新的分支..之前
阿诺德·罗亚

1
这甚至比默认行为古怪。如果您将工作放在分支基础上,那么它的行为确实很奇怪。
Beefster

1
小心此设置!!设置后,您将获得此行为。1.切换到master。2.运行git checkout -b new_branch。3.将提交添加到该分支。4 git push origin new_branch这会将提交推送到master原点上的分支(而不是原点上名为的新分支new_branch)。
stwr667 '19

38

顺便说一下,将当前分支推送到同名远程的快捷方式:

$ git push -u origin HEAD

22

我个人在bash中使用以下别名

在〜/ .gitconfig文件中

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

并在〜/ .bashrc或〜/ .zshrc文件中

alias gpo="git pushup"
alias gpof="gpo -f"
alias gf="git fetch"
alias gp="git pull"

1
我只需要hcange .gitconfig,然后就可以使用git pushup总是将当前分支推到原点的命令。我永远可以使用git pushup的,而不是git push👍
thespacecamel

18

如果以下方法不起作用:

git config --global push.default current

您还应该更新项目的本地配置,因为您的项目可能具有本地git配置:

git config --local push.default current

2
更多的解释会很好。第一行做什么?
papillon

3
这个答案是合法的。所有提议别名的方法都是愚蠢的解决方法。其他证明记忆长命令序列的方法是脚的。
MarkHu

10

您还可以显式告诉git pull要拉的远程分支(如错误消息中所述):

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

但是,请注意这一点:如果您在另一个分支上并执行显式拉取,则拉取的refspec将合并到您所在的分支中!


10

对于它的价值,如果您尝试跟踪远程站点上已经存在的分支(例如起源/分支),但尚未在本地将其检出,则可以执行以下操作:

$ git checkout --track origin/somebranch

注意:“-t”是“ --track”选项的缩写。

马上就建立了相同的关联。


5
您实际上可以只结帐到分支。因此git checkout somebranch是等效的。
2014年

2
@Zamith只能在git fetch事先打电话后才能使用吗?
Walter Roman

1
不是立即,但是是的,您确实需要在本地存储库上引用该分支,该引用在您调用git fetch或时发生git pull。不过,我从未发现这是个问题。
扎米思

10
git branch --set-upstream-to=origin/master<branch_name>

9

我使用这个Git别名,而不是每次都复制/粘贴来自Git的建议:https : //gist.github.com/ekilah/88a880c84a50b73bd306

源代码复制到下面(将此添加到~/.gitconfig文件中):

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

7

您可以设置一个非常好的别名,无需过多冗长的语法即可处理该别名。

我在中具有以下别名~/.gitconfig

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

在对新分支进行提交之后,只需键入以下命令即可推送新分支:

git po

为什么po呢?push origin?如果多次运行该怎么办?
阿诺德·罗阿

是的,与推送来源一样。如果它多次运行,则不会发生任何事情。我还为git push -f设置了别名git pf,因此一旦将原点推送即可使用该别名。
123

请参阅djanowski的评论,您可以直接使用HEAD
arhak

3

对于那些正在寻找可与一起使用的别名的人git pull,这是我所使用的:

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

现在,只要您得到:

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

赶紧跑:

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

而且你很好走


2

因为git具有将不同分支推/拉到不同“上游”存储库的强大功能。您甚至可以在同一分支上使用单独的存储库进行推送和拉出。这可以创建一个分布式的多级流,我可以看到它在诸如Linux内核之类的项目中很有用。Git最初是为在该项目上使用而构建的。

因此,它不会对分支应该跟踪哪个存储库做出假设。

另一方面,大多数人并不以这种方式使用git,因此它可能是默认选项的一个很好的例子。

Git通常是很底层的,可能会令人沮丧。但是有GUI,如果您仍然想从shell中使用辅助脚本,应该很容易编写辅助脚本。



0

legit由于这个问题,我有点被重新发现(仅适用于OS X)。现在,我在分支时只使用以下两个命令:

legit publish [<branch>] 将指定的分支发布到远程。(别名:pub

legit unpublish <branch> 从远程删除指定的分支。(别名:unp

SublimeGitlegit默认情况下附带支持,这使得整个分支例程就像按Ctrl-b一样容易。


0

我们使用phabricator,而不使用git推送。我必须创建可以在Linux / mac上运行的bash别名

vim ~/.bash_aliases

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

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

0

这是git push的bash别名,可以在每次推送时安全运行,并且会自动在第一次推送的上游设置和随后的正常推送之间切换。

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

原始帖子

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.