为什么我必须&#34; git push --set-upstream origin <branch>&#34;?

时间:2016-06-12 03:30:45

标签: git branch

我创建了一个用于测试Solaris和Sun Studio的本地分支。然后我把分支推到了上游。提交更改并尝试推送更改后:

$ 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

为什么我必须为此做一些特别的事情?

是否有合理的用例,有人会创建<branch>,将<branch>推送到远程,然后声明<branch>上的提交不应该是<branch> }?

我按照这个问题回答了Stack Overflow:Push a new local branch to a remote Git repository and track it too。我猜测其另一个不完整或错误接受的答案的实例。或者,Git的另一个例子是执行一项简单的任务并使其变得困难。

这是另一台机器上的视图。分支显然存在,因此它被创建并推送:

$ 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

6 个答案:

答案 0 :(得分:136)

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

你问的问题的答案 - 我将其重新改写为&#34;我是否必须设置上游&#34; -is:不,你不要 完全设置上游。

但是,如果当前分支没有上游,Git会在git push和其他命令上更改其行为。

这里的完整推送故事漫长而乏味,可以追溯到Git 1.5版之前的历史。为了缩短它,git push实现得很差。 1 从Git 2.0版开始,Git现在有一个拼写为push.default的配置旋钮,现在默认为{{1} }。对于2.0之前和之后的几个Git版本,每次运行simple时,Git都会发出大量噪音,试图说服你设置git push只是让push.default闭嘴。< / p>

你没有提到你正在运行哪个版本的Git,也没有提到你是否配置了git push,所以我们必须猜测。我的猜测是你使用的是Git版本的2点式内容,并且已将push.default设置为push.default以使其关闭。确切地说,你拥有哪个版本的Git,以及你有simple设置的任何内容,确实很重要,因为这个漫长而枯燥的历史,但最终,你&# 39;从Git获得另一个投诉表明您的Git 配置为避免过去的错误之一。

什么是上游?

上游只是另一个分支名称,通常是远程跟踪分支,与(常规,本地)分支相关联。

每个分支都可以选择上一组(1)。也就是说,每个分支都有一个上游,或者没有上游。没有分支可以有多个上游。

上游应该,但不一定是有效的分支(无论是push.default之类的远程跟踪还是origin/B之类的本地跟踪)。也就是说,如果当前分支 B 具有上游 U ,则master 应该工作。如果它不起作用 - 如果它抱怨 U 不存在 - 则大多数Git的行为就像上游根本没有设置一样。一些命令,如git rev-parse U,将显示上游设置,但将其标记为&#34;已消失&#34;。

上游有什么用?

如果您的git branch -vv设置为push.defaultsimple,则上游设置将使upstream无需其他参数即可使用。

它就是git push所做的一切。但这是相当重要的,因为git push是一个简单的拼写错误导致严重头痛的地方之一。

如果您的git push设置为push.defaultnothingmatching,则设置上游对current不执行任何操作。

(所有这些假设您的Git版本至少为2.0。)

上游影响git push

如果您在没有其他参数的情况下运行git fetch,Git会通过查询当前分支的上游来计算哪个远程提取。如果上游是远程跟踪分支,Git从该远程获取。 (如果上游未设置或是本地分支,Git会尝试获取git fetch。)

上游影响origingit merge

如果您运行git rebasegit merge而没有其他参数,Git将使用当前分支的上游。因此,它缩短了这两个命令的使用。

上游影响git rebase

你绝不应该 2 使用git pull,但是如果你这样做,git pull使用上游设置来确定从哪个远程获取,然后是哪个分支到合并或改变。也就是说,git pullgit pull做同样的事情 - 因为它实际上运行 git fetch - 然后与git fetch或{做同样的事情{1}},因为它实际上运行 git mergegit rebase

(你通常应该手动完成这两个步骤,至少在你完全了解Git之前,当任一步失败时,他们最终会知道出了什么问题并且知道如何处理它。)

上游影响git merge

这实际上可能是最重要的。一旦有了上游集,git rebase可以根据提交报告当前分支与其上游之间的差异。

如果正常情况下,您位于分支 git status 且其上游设置为git status,并且您运行B,则会立即看看你是否有你可以推送的提交,和/或提交你可以合并或改组。

这是因为origin/B运行:

  • git status git status 有多少次提交不在git rev-list --count @{u}..HEAD上?
  • Borigin/B上有哪些未提交 git rev-list --count HEAD..@{u} 的提交?

设置上游可以为您提供所有这些功能。

为什么origin/B已经有上游集?

首次从某个遥控器克隆时,使用:

B

或类似的,Git所做的最后一步基本上是master。这会检查您当地的分支机构$ git clone git://some.host/path/to/repo.git - 只有您 拥有本地分支git checkout master

另一方面,你有一个名为master的远程跟踪分支,因为你刚刚克隆了它。

Git猜测你一定有这样的意思:&#34;让我成为一个新的本地master,指向与远程跟踪origin/master相同的提交,并且,当你在&#39}它,将master的上游设置为origin/master。&#34;

对于你没有的每个分支master,都会发生这种情况。 Git创建分支使其成为&#34;跟踪&#34; (具有上游)相应的远程跟踪分支。

但是这对分支不起作用,即没有远程跟踪分支的分支

如果您创建分支:

origin/master

目前还没有git checkout。您的本地$ git checkout -b solaris 无法跟踪远程跟踪分支origin/solaris,因为它不存在。

当你第一次推新分支时:

solaris

origin/solaris上创建 $ git push origin solaris ,因此也会在您自己的Git存储库中创建solaris。但为时已晚:你已经有一个本地origin 没有上游 3

不应该只是将Git设置为现在自动设置为上游吗?

可能。见&#34;执行不力&#34;和脚注1.现在很难改变 :有数百万个 4 脚本使用Git,有些脚本很可能依赖于它的当前行为。更改行为需要新的主要版本,nag-ware强制您设置一些配置字段,依此类推。简而言之,Git是其自身成功的牺牲品:无论它在今天出现什么样的错误,只有在变化大部分是隐形的,明显更好的或者随着时间的推移缓慢地完成时才能得到解决。

事实是,今天不是,除非origin/solaris期间使用solaris--set-upstream。这就是消息告诉你的内容。

你不必这样做。好吧,正如我们上面提到的,你根本不必这样做,但是让我们说你想要一个上游。您已经通过较早的推送在-u上创建了分支git push,并且在您的solaris输出显示时,您已经拥有 origin了本地存储库。

您只是没有将其设置为git branch的上游。

要立即设置,而不是在第一次推送期间,请使用origin/solarissolaris子命令采用任何现有分支的名称,例如git branch --set-upstream-to,并将当前分支的上游设置为该另一分支。

它就是它所做的一切 - 但它具有上述所有这些含义。这意味着您只需运行--set-upstream-to,然后环顾四周,然后根据需要运行origin/solarisgit fetch,然后进行新的提交并运行git merge,而无需额外的烦恼-around。

1 公平地说,当时尚不清楚初始实施是否容易出错。只有当每个新用户每次都犯同样的错误时,这才会变得清晰。它现在已经不那么贫穷了#34;这并不是说&#34;伟大的&#34;。

2 &#34;决不&#34;有点强,但我发现Git新手在分离步骤时会更好地理解事情,特别是当我向他们展示git rebase实际做了什么时,他们可以看到git pushgit fetch将会做下一步。

3 如果您将第一个 git merge作为git rebase运行 - 即,如果您添加git push标志 - Git将如果(并且仅当)推送成功,则将git push -u origin solaris设置为当前分支的上游。因此,您应该在首次推送时提供-u。实际上,您可以在以后的任何推送中提供它,并在此时设置或更改上游。但是,如果你忘了,我认为origin/solaris会更容易。

4 以奥斯汀权力/邪恶博士的方法衡量,简单地说是一个MILLLL-YUN&#34;无论如何。

答案 1 :(得分:10)

基本完整的命令就像git push <remote> <local_ref>:<remote_ref>。如果只运行git push,git不知道该怎么做,除非你做了一些帮助git做出决定的配置。在git repo中,我们可以设置多个遥控器。我们也可以将本地参考推送到任何远程参考。完整命令是最直接的推动方式。如果要输入较少的单词,则必须先进行配置,如--set-upstream。

答案 2 :(得分:7)

之间的区别
git push origin <branch>
 和
git push --set-upstream origin <branch>
是它们都可以很好地推送到远程存储库,但是当您拉出时,您会注意到差异。

如果您这样做:
git push origin <branch>
拉动时,您必须这样做:
git pull origin <branch>

但如果您这样做:
git push --set-upstream origin <branch>
然后,在拉动时,您只需要做:
git pull

因此,添加--set-upstream无需每次执行git pull时都指定要从哪个分支中提取。

答案 3 :(得分:0)

我的理解是,“-u”或“ --set-upstream”允许您为所在分支指定上游(远程)存储库,以便下次运行“ git push”时,不必甚至不必指定远程存储库。

推送并将上游(远程)存储库设置为来源:

$ git push -u origin

下次按下时,无需指定远程存储库:

$ git push

答案 4 :(得分:0)

-u标志指定您要将本地分支链接到上游分支。如果不存在上游分支,还将创建一个上游分支。这些答案都没有涵盖我的操作方式(完整形式),因此这里是:

git push -u origin <your-local-branch-name>

因此,如果您的本地分支机构名称为咖啡

git push -u origin coffee

答案 5 :(得分:0)

如果您忘记添加存储库HTTPS链接,则将其放入git push <repo HTTPS>