我创建了一个本地分支来测试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 |
- 可能重复了为什么我需要一直做`--set upstream`吗?
- 谢谢你,阿列克斯。不幸的是,所引用的dup并不能解释由缺省表示的荒谬的用例。(这些不是反问题。我真的对UX设计的原因感兴趣。
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.default到simple让它关闭。由于那段漫长而乏味的历史,究竟你拥有哪种版本的Git,以及如果你将push.default设置为哪种版本,这都很重要,但最终,你又收到了Git的投诉,这表明你的Git被配置成可以避免过去的错误之一。好的。上游是什么?
上游只是另一个分支名称,通常是远程跟踪分支,与(常规的、本地的)分支关联。好的。
每个分支都可以选择有一(1)个上游集。也就是说,每个分支要么有上游,要么没有上游。任何分支都不能有多个上游分支。好的。
上游应该但不一定是一个有效的分支(无论是像origin/B那样的远程跟踪,还是像master那样的本地跟踪)。也就是说,如果当前分支B有上游U,那么git rev-parse U应该工作。如果它不起作用,如果它抱怨u不存在,那么大多数git的行为就好像上游根本没有设置。一些命令,如git branch -vv将显示上游设置,但将其标记为"消失"。好的。上游有什么好处?
如果您的push.default设置为simple或upstream,则上游设置将使git push在没有其他参数的情况下使用,仅起作用。好的。
这就是它对git push所做的一切。但这是相当重要的,因为git push是一个简单的打字错误导致严重头痛的地方之一。好的。
如果你的push.default设置为nothing、matching或current,设置上游对git push一点作用都没有。好的。
(所有这些都假定您的Git版本至少为2.0。)好的。上游影响git fetch。
如果运行git fetch时没有其他参数,那么git可以通过查询当前分支的上游来确定要从哪个远程获取数据。如果上游是远程跟踪分支,则git从该远程获取。(如果上游未设置或是本地分支,Git尝试获取origin。)好的。上游对git merge和git rebase也有影响。
如果运行git merge或git rebase,没有其他参数,git将使用当前分支的上游。所以它缩短了这两个命令的使用。好的。上游影响git pull。
无论如何,您都不应该使用git pull,但如果这样做,git pull使用上游设置来确定要从哪个远程获取数据,然后与哪个分支合并或重新组合。也就是说,git pull和git fetch做的是相同的事情,因为它实际运行git fetch,然后和git merge或git rebase做的是相同的事情,因为它实际运行git merge或git 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 merge或git rebase,然后做出新的承诺并运行git push,而不必再担心了。好的。
1为了公平起见,当时还不清楚最初的实现是容易出错的。只有当每个新用户每次都犯同样的错误时,这一点才变得清晰起来。它现在"不那么穷",也不是说"伟大"。好的。
2"从不"有点强,但我发现,当我把步骤分开时,特别是当我可以向他们展示git fetch实际做了什么,然后他们可以看到git merge或git rebase下一步将做什么时,Git新手更了解事情。好的。
3如果您将第一个git push作为git push -u origin solaris运行,即如果添加-u标志,那么在推送成功的情况下(并且仅在推送成功的情况下),git会将origin/solaris设置为当前分支的上游。所以你应该在第一次推的时候提供-u。实际上,您可以在以后的任何推送中提供它,它将在该点设置或更改上游。但我认为如果你忘了,江户十一〔十五〕会更容易些。好的。
4根据Austin Powers/Dr Evil简单地说"一个millll-yun"的方法进行测量。好的。好啊。
- 另外:stackoverflow.com/a/17096880/6309将在第一次推送时设置上游权限。+ 1
- 如果常见的情况是创建分支/推送分支/使用分支,那么将一个新的本地分支推送到远程Git存储库并跟踪它是否也可以实际工作?如果有人想要创建分支/推分支/不使用分支,那么他们不应该做一些特殊的事情,比如--set-upstream /dev/null?为什么要把负担推到普通案件上?我真的不理解这些工程和可用性决策中的一些。
- @VONC:是的,这就是git push -u的观点,但实际上似乎git push -u应该是默认的,或者至少是在没有上游的情况下是默认的,并且当没有上游的时候应该有一个git push --no-set-upstream,并且你想保持这种状态(无论什么不可理解的原因是-)。
- @Torek的原因可能是"默认设置为上游……为了什么?"相同的分支名称可能并不总是用户想要的。另外,如果我创建了10个分支,但只想推一个,而我在错误的分支中,一个git push,而不是失败,也会悄悄地推和跟踪错误的分支。所以…我想是波拉案吧?(en.wikipedia.org/wiki/principle-of-least-huashing)
- "你一直在问这样的问题,因为,我认为,你已经注销了吉特为"真的令人讨厌"。"请保持这种猜测自己。我遇到这个问题是因为我也一直在问自己这些问题。我不是世界上最好的用户体验设计师,但即使我认识到这个特定场景中的默认行为可能会更好。
- @史蒂文:我会把它编辑出来,但我会注意到我实际上是同意的:Git的用户体验不是最好的。
- @托雷克-谢谢。你的回答很好;深思熟虑,结构合理,信息丰富。-)
- 如何对所有回购进行违约处理?
- @米切尔:你不能这样做(让git push违约),这样做可能是一个错误:你不一定总是想逆流而上。(我知道你说的"违约"比"总是"更合理,也许应该是违约!)但是,如果您想要一个默认情况下执行--set-upstream的命令,那么您可以编写自己的别名或脚本。
- 主要为奥斯汀电力公司的参考投票!
基本上完整的命令就像git push :。如果您只运行git push,那么git不知道要做什么,除非您进行了一些配置来帮助git做出决定。在Git报告中,我们可以设置多个远程。此外,我们可以将本地引用推送到任何远程引用。完整命令是进行推送的最简单方法。如果你想输入更少的单词,你必须先进行配置,比如——设置为上游。