为什么我必须”git push——设置上游源站<branch>”?

Why do I have to “git push --set-upstream origin <branch>”?

我创建了一个本地分支来测试Solaris和Sun Studio。然后我把树枝往上游推。在提交更改并尝试推送更改之后:

1
2
3
4
5
6
7
8
$ 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

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

有没有合理的使用案例,有人会创建,将推到远程,然后声称对的承诺不应该是对的?

我遵循了这个关于堆栈溢出的问题和答案:将一个新的本地分支推送到一个远程Git存储库并跟踪它。我猜这是另一个不完整或错误的答案。或者,它是Git接受简单任务并使其变得困难的另一个例子。

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

1
2
3
4
5
6
7
8
9
$ 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


tl;dr:git branch --set-upstream-to origin/solaris

你问的问题的答案是:不,你根本不必设置上游。好的。

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

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

您没有提到您运行的是哪个版本的Git,也没有提到您是否配置了push.default,所以我们必须猜测。我猜你使用的是Git版本2点的东西,你已经设置了push.defaultsimple让它关闭。由于那段漫长而乏味的历史,究竟你拥有哪种版本的Git,以及如果你将push.default设置为哪种版本,这都很重要,但最终,你又收到了Git的投诉,这表明你的Git被配置成可以避免过去的错误之一。好的。上游是什么?

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

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

上游应该但不一定是一个有效的分支(无论是像origin/B那样的远程跟踪,还是像master那样的本地跟踪)。也就是说,如果当前分支B有上游U,那么git rev-parse U应该工作。如果它不起作用,如果它抱怨u不存在,那么大多数git的行为就好像上游根本没有设置。一些命令,如git branch -vv将显示上游设置,但将其标记为"消失"。好的。上游有什么好处?

如果您的push.default设置为simpleupstream,则上游设置将使git push在没有其他参数的情况下使用,仅起作用。好的。

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

如果你的push.default设置为nothingmatchingcurrent,设置上游对git push一点作用都没有。好的。

(所有这些都假定您的Git版本至少为2.0。)好的。上游影响git fetch

如果运行git fetch时没有其他参数,那么git可以通过查询当前分支的上游来确定要从哪个远程获取数据。如果上游是远程跟踪分支,则git从该远程获取。(如果上游未设置或是本地分支,Git尝试获取origin。)好的。上游对git mergegit rebase也有影响。

如果运行git mergegit rebase,没有其他参数,git将使用当前分支的上游。所以它缩短了这两个命令的使用。好的。上游影响git pull

无论如何,您都不应该使用git pull,但如果这样做,git pull使用上游设置来确定要从哪个远程获取数据,然后与哪个分支合并或重新组合。也就是说,git pullgit fetch做的是相同的事情,因为它实际运行git fetch,然后和git mergegit rebase做的是相同的事情,因为它实际运行git mergegit rebase。好的。

(您通常只需手动执行这两个步骤,至少在您充分了解Git之前,当任一步骤失败时,它们最终会识别出出错的地方并知道如何处理。)好的。上游影响git status

这可能是最重要的。一旦有了上游集合,git status就可以报告当前分支和其上游分支在提交方面的差异。好的。

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

这是因为git status运行:好的。

  • git rev-list --count @{u}..HEAD:你对不在origin/B上的B有多少承诺?
  • git rev-list --count HEAD..@{u}:您对不在B上的origin/B有多少承诺?

设置一个上游会给你所有这些东西。好的。为什么master已经有了上游设备?

当您首次从某个远程克隆时,使用:好的。

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

或者类似的,Git做的最后一步本质上是git checkout master。这将检查您的本地分支机构master,只有您没有本地分支机构master。好的。

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

Git猜测你的意思一定是:"给我一个新的本地master,它指向与远程跟踪origin/master相同的承诺,并且,当你在这里的时候,把master的上游设置为origin/master"。好的。

这种情况发生在你以前没有的每一个分支上。Git创建分支并使其"跟踪"(作为上游)相应的远程跟踪分支。好的。但这对新的分支机构不起作用,也就是说,还没有远程跟踪分支的分支机构。

如果创建新分支:好的。

1
$ git checkout -b solaris

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

当你第一次推动新的分支时:好的。

1
$ git push origin solaris

它在origin上创建solaris,因此也在您自己的git存储库中创建origin/solaris。但为时已晚:你已经有了一个没有上游的本地solaris。3好的。现在,Git不应该将其设置为自动上游吗?

可能。见"执行不当"和脚注1。现在很难改变:有数以百万计的脚本使用git,有些可能取决于它当前的行为。改变行为需要一个新的主要版本,NAG软件强制您设置一些配置字段,等等。简而言之,Git是其自身成功的受害者:无论它在其中犯了什么错误,今天,只有当变化基本上是看不见的,明显要好得多,或者随着时间的推移缓慢地完成时,它才能被修复。好的。

事实是,今天不是这样,除非你在git push期间使用--set-upstream-u。这就是信息告诉你的。好的。

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

你只是没有把它设置为solaris的上游。好的。

要现在设置,而不是在第一次推送时,请使用git branch --set-upstream-to--set-upstream-to子命令使用任何现有分支的名称,如origin/solaris,并将当前分支的上游设置为该其他分支。好的。

这就是它所做的一切,但它具有上述所有的含义。这意味着你可以运行git fetch,然后四处看看,然后运行git mergegit rebase,然后做出新的承诺并运行git push,而不必再担心了。好的。

1为了公平起见,当时还不清楚最初的实现是容易出错的。只有当每个新用户每次都犯同样的错误时,这一点才变得清晰起来。它现在"不那么穷",也不是说"伟大"。好的。

2"从不"有点强,但我发现,当我把步骤分开时,特别是当我可以向他们展示git fetch实际做了什么,然后他们可以看到git mergegit rebase下一步将做什么时,Git新手更了解事情。好的。

3如果您将第一个git push作为git push -u origin solaris运行,即如果添加-u标志,那么在推送成功的情况下(并且仅在推送成功的情况下),git会将origin/solaris设置为当前分支的上游。所以你应该在第一次推的时候提供-u。实际上,您可以在以后的任何推送中提供它,它将在该点设置或更改上游。但我认为如果你忘了,江户十一〔十五〕会更容易些。好的。

4根据Austin Powers/Dr Evil简单地说"一个millll-yun"的方法进行测量。好的。好啊。


基本上完整的命令就像git push :。如果您只运行git push,那么git不知道要做什么,除非您进行了一些配置来帮助git做出决定。在Git报告中,我们可以设置多个远程。此外,我们可以将本地引用推送到任何远程引用。完整命令是进行推送的最简单方法。如果你想输入更少的单词,你必须先进行配置,比如——设置为上游。