我为测试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

为什么我要为此做点特别的事?

是否有任何合理的用例,其中有人将创建<分支>,将<分支>推到远程,然后声称<分支>上的提交不应该用于<分支>?


我遵循了Stack Overflow上的这个问题和答案:将一个新的本地分支推到远程Git存储库并跟踪它。我猜这是另一个不完整或错误的接受答案的例子。或者,这是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

当前回答

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

推送并设置上游(远程)存储库为原点:

$ git push -u origin

下次推送时,你不必指定远程存储库:

$ git push

其他回答

两者之间的区别

git push origin <branch>

and

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时都指定要从哪个分支拉取。

TL;DR: git分支——set-up - stream-to origin/solaris


你问的问题的答案是:不,你根本不需要设置上游。我将把这个问题重新表述为“我必须设置上游吗”。

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

这里完整的推送故事又长又无聊,可以追溯到Git 1.5版本之前。为了缩短它,git push的实现很糟糕从Git 2.0版本开始,Git现在有一个拼写为push.default的配置旋钮,默认为simple。在Git 2.0之前和之后的几个版本中,每次你运行Git push时,Git都会发出很多噪音,试图说服你设置push.default,只是为了让Git push关闭。

You do not mention which version of Git you are running, nor whether you have configured push.default, so we must guess. My guess is that you are using Git version 2-point-something, and that you have set push.default to simple to get it to shut up. Precisely which version of Git you have, and what if anything you have push.default set to, does matter, due to that long and boring history, but in the end, the fact that you're getting yet another complaint from Git indicates that your Git is configured to avoid one of the mistakes from the past.

什么是上游?

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

每个分支都可以选择拥有一个(1)上游集。也就是说,每个分支要么有上游,要么没有上游。任何分支都不能有一个以上的上游。

上游应该,但不一定是一个有效的分支(无论是像origin/B这样的远程跟踪,还是像master这样的本地跟踪)。也就是说,如果当前分支B有上游U, git rev-parse U应该可以工作。如果它不起作用——如果它抱怨U不存在——那么大部分Git就会认为上游根本没有设置。一些命令,如git branch -vv,将显示上游设置,但将其标记为“gone”。

上游有什么好处?

如果你的push.default被设置为simple或upstream, upstream设置将使git push在没有额外参数的情况下正常工作。

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

如果你的push.default被设置为nothing、matching或current,设置upstream对git push没有任何作用。

(所有这些都假设你的Git版本至少是2.0。)

上游影响git获取

如果运行git fetch时不带附加参数,git会通过咨询当前分支的上游来确定从哪个远程获取。如果上游是一个远程跟踪分支,Git将从该远程获取。(如果upstream没有设置或者是本地分支,Git会尝试获取origin。)

上游也会影响git merge和git rebase

如果运行git merge或git rebase而不带其他参数,git将使用当前分支的上游。所以它缩短了这两个命令的使用。

上游影响git拉力

无论如何,你都不应该使用git pull,但如果你这样做了,git pull会使用upstream设置来确定从哪个远程获取,然后使用哪个分支合并或重基。也就是说,git pull做的事情与git fetch相同——因为它实际运行git fetch——然后做的事情与git merge或git rebase相同,因为它实际运行git merge或git rebase。

(您通常应该手动执行这两个步骤,至少在您足够了解Git之前,当其中一个步骤失败时(它们最终会失败),您可以认识到哪里出了问题,并知道如何处理它。)

上游会影响git的状态

这可能是最重要的。一旦有了上游集,git状态就可以报告当前分支与其上游分支之间的差异(以提交的方式)。

如果,和正常情况一样,你在分支B上,它的上游设置为origin/B,并且你运行git status,你将立即看到你是否有可以推送的提交,和/或可以合并或重基的提交。

这是因为git的状态是:

Git rev-list——count @{u}..你在B上有多少不是在origin/B上的提交? git rev-list -count HEAD..@{u}:你在origin/B上有多少不是在B上的提交?

设置上游可以提供所有这些东西。

为什么主人已经有了上游组?

当你第一次从远程复制时,使用:

$ git clone git://some.host/path/to/repo.git

或者类似的,Git做的最后一步,本质上是Git checkout master。这将检出您的本地分支主服务器—只是您没有本地分支主服务器。

另一方面,您确实有一个名为origin/master的远程跟踪分支,因为您只是克隆了它。

Git猜测您的意思一定是:“为我创建一个新的本地master,它指向与远程跟踪origin/master相同的提交,并且,当您这样做时,将master的上游设置为origin/master。”

这发生在您还没有签出的每个分支上。Git创建分支,并使其“跟踪”相应的远程跟踪分支(作为上游)。

但是对于新的分支,也就是还没有远程跟踪分支的分支,这并不适用。

如果你创建一个新的分支:

$ git checkout -b solaris

到目前为止,还没有起源/solaris。您的本地solaris无法跟踪远程跟踪分支原点/solaris,因为它不存在。

当你第一次推送新分支时:

$ git push origin solaris

它在origin上创建solaris,因此也在你自己的Git存储库中创建origin/solaris。但是太晚了:你已经有了一个没有上游的本地solaris

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

可能。参见“执行不力”和脚注1。现在很难改变:有数百万个脚本使用Git,其中一些可能依赖于它当前的行为。改变行为需要一个新的主要版本,nagg -ware迫使您设置一些配置字段,等等。简而言之,Git是其自身成功的受害者:无论它有什么错误,今天,只有在更改基本上是不可见的、明显更好的或随着时间慢慢进行的情况下才能修复。

事实上,现在还没有,除非你在git推送过程中使用——set-upstream或-u。这就是信息要告诉你的。

你不必这样做的。好吧,正如我们上面提到的,你根本不必这样做,但假设你想要一个上游。通过前面的推送,您已经在origin上创建了分支solaris,正如git分支输出所示,您已经在本地存储库中创建了origin/solaris。

您只是没有将它设置为solaris的上游。

现在要设置它,而不是在第一次推送时,使用git分支——set-upstream- To。——set-upstream-to子命令接受任何现有分支的名称,例如origin/solaris,并将当前分支的上游设置为另一个分支。

这就是它——这就是它所做的一切——但它具有上面提到的所有含义。这意味着你可以只运行git fetch,然后四处查看,然后运行git merge或git rebase,然后进行新的提交和运行git push,而没有一堆额外的麻烦。


公平地说,当时还不清楚最初的实现是否容易出错。只有当每个新用户每次都犯同样的错误时,这一点才变得清晰起来。它现在“不那么穷了”,这并不是说“很棒”。

2“Never”有点强,但我发现当我把步骤分开时,Git新手理解得更好,特别是当我可以向他们展示Git fetch实际做了什么,然后他们可以看到Git merge或Git rebase下一步将做什么。

3如果你运行你的第一个git push, git push -u origin solaris - i.e.。,如果你添加了-u标志,当(且仅当)推送成功时,git会将origin/solaris设置为当前分支的上游。所以你应该在第一次推时提供-u。事实上,您可以在以后的任何推送中提供它,并且它将在此时设置或更改上游。但是我认为git分支——上游设置——更简单,如果你忘了的话。

无论如何,用《王牌大贱谍》/《邪恶博士》的方法来衡量,简单地说“one mill - yun”。

如果你不想考虑这个问题,也不想修改你的配置:

Git push——set-upstream origin $(Git分支——show-current)

一个基本完整的命令是git push <remote> <local_ref>:<remote_ref>。如果你只运行git push, git不知道该做什么,除非你做了一些配置来帮助git做决定。在git回购中,我们可以设置多个遥控器。我们还可以将本地引用推入到任何远程引用。使用full命令是最直接的推入方式。如果你想输入更少的单词,你必须先配置,比如——set-upstream。

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

推送并设置上游(远程)存储库为原点:

$ git push -u origin

下次推送时,你不必指定远程存储库:

$ git push