为什么我必须“git push --set-upstream origin <branch>”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37770467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why do I have to "git push --set-upstream origin <branch>"?
提问by jww
I created a local branch for testing Solaris and Sun Studio. I then pushed the branch upstream. After committing a change and attempting to push the changes:
我创建了一个本地分支来测试 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
Why do I have to do something special for this?
为什么我必须为此做一些特别的事情?
Is there any reasonable use case where someone would create <branch>
, push the <branch>
to remote, and then claim a commit on <branch>
is not supposed to be for <branch>
?
是否有任何合理的用例可以让某人创建<branch>
,推<branch>
送到远程,然后声称提交<branch>
不应该用于<branch>
?
I followed this question and answer on Stack Overflow: Push a new local branch to a remote Git repository and track it too. I'm guessing its another instance of a incomplete or wrong accepted answer. Or, its another instance of Git taking a simple task and making it difficult.
我在 Stack Overflow 上关注了这个问题和答案:Push a new local branch to a remote Git repository and tracking it too。我猜这是另一个不完整或错误的接受答案的例子。或者,它是 Git 执行简单任务并使其变得困难的另一个实例。
Here's the view on a different machine. The branch clearly exists, so it was created and pushed:
这是另一台机器上的视图。该分支显然存在,因此它被创建和推送:
$ 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
回答by torek
TL;DR: git branch --set-upstream-to origin/solaris
特尔;博士: git branch --set-upstream-to origin/solaris
The answer to the question you asked—which I'll rephrase a bit as "do I have to set an upstream"—is: no, you don't haveto set an upstream at all.
这个问题的答案你问哪个,我会改写一个部位为“我要设置一个上游” -is的问题:不,你不具备在所有设置的上游。
If you do not have upstream for the current branch, however, Git changes its behavior on git push
, and on other commands as well.
但是,如果当前分支没有上游,Git 也会更改其在git push
和其他命令上的行为。
The complete push story here is long and boring and goes back in history to before Git version 1.5. To shorten it a whole lot, git push
was implemented poorly.1As of Git version 2.0, Git now has a configuration knob spelled push.default
which now defaults to simple
. For several versions of Git before and after 2.0, every time you ran git push
, Git would spew lots of noise trying to convince you to set push.default
just to get git push
to shut up.
这里完整的推送故事又长又无聊,历史可以追溯到 Git 1.5 版本之前。为了缩短它很多,git push
实施得很差。1从 Git 2.0 版开始,Git 现在有一个拼写的配置旋钮push.default
,现在默认为simple
. 对于 2.0 之前和之后的多个 Git 版本,每次运行时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, doesmatter, 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 isconfigured to avoid one of the mistakes from the past.
你没有提到你运行的是哪个版本的 Git,也没有提到你是否配置了push.default
,所以我们必须猜测。我的猜测是,你正在使用的Git版本2点东西,并且已设置push.default
要simple
让它闭嘴。确切地说,您拥有哪个版本的 Git,如果您push.default
设置了任何内容,这确实很重要,因为那段漫长而无聊的历史,但最终,您收到来自 Git 的另一个抱怨的事实表明您的 Git是配置以避免过去的错误之一。
What is an upstream?
什么是上游?
An upstreamis simply another branch name, usually a remote-tracking branch, associated with a (regular, local) branch.
的上游仅仅是另一个分支名称,通常是一个远程跟踪分支,具有(常规,本地)分支相关联。
Every branch has the option of having one (1) upstream set. That is, every branch either has an upstream, or does not have an upstream. No branch can have more than one upstream.
每个分支都可以选择拥有一 (1) 个上游集。也就是说,每个分支要么有上游,要么没有上游。任何分支都不能有多个上游。
The upstream should, but does not have to be, a valid branch (whether remote-tracking like origin/B
or local like master
). That is, if the current branch Bhas upstream U, git rev-parse U
shouldwork. If it does not work—if it complains that Udoes not exist—then most of Git acts as though the upstream is not set at all. A few commands, like git branch -vv
, will show the upstream setting but mark it as "gone".
上游应该,但不一定是,一个有效的分支(无论是远程跟踪之类的还是本地之类的)。也就是说,如果当前分支B有上游U,应该可以工作。如果它不起作用——如果它抱怨U不存在——那么大多数 Git 就像上游根本没有设置一样。一些命令,如,将显示上游设置,但将其标记为“gone”。origin/B
master
git rev-parse U
git branch -vv
What good is an upstream?
上游有什么好处?
If your push.default
is set to simple
or upstream
, the upstream setting will make git push
, used with no additional arguments, just work.
如果您push.default
设置为simple
or upstream
,则上游设置将 make git push
,无需额外参数即可使用。
That's it—that's all it does for git push
. But that's fairly significant, since git push
is one of the places where a simple typo causes major headaches.
就是这样——这就是它为 所做的一切git push
。但这相当重要,因为这git push
是一个简单的错字导致严重头痛的地方之一。
If your push.default
is set to nothing
, matching
, or current
, setting an upstream does nothing at all for git push
.
如果您push.default
设置为nothing
, matching
, or current
,则设置上游对git push
.
(All of this assumes your Git version is at least 2.0.)
(所有这些都假设您的 Git 版本至少为 2.0。)
The upstream affects git fetch
上游影响 git fetch
If you run git fetch
with no additional arguments, Git figures out whichremote to fetch from by consulting the current branch's upstream. If the upstream is a remote-tracking branch, Git fetches from that remote. (If the upstream is not set or is a local branch, Git tries fetching origin
.)
如果你git fetch
没有额外的参数运行,Git 会通过查询当前分支的上游来确定要从哪个远程获取。如果上游是远程跟踪分支,则 Git 从该远程获取。(如果上游没有设置或者是本地分支,Git 会尝试 fetching origin
。)
The upstream affects git merge
and git rebase
too
上游影响git merge
和git rebase
太
If you run git merge
or git rebase
with no additional arguments, Git uses the current branch's upstream. So it shortens the use of these two commands.
如果您运行git merge
或git rebase
没有附加参数,Git 将使用当前分支的上游。所以它缩短了这两个命令的使用。
The upstream affects git pull
上游影响 git pull
You should never2use git pull
anyway, but if you do, git pull
uses the upstream setting to figure out which remote to fetch from, and then which branch to merge or rebase with. That is, git pull
does the same thing as git fetch
—because it actually runsgit fetch
—and then does the same thing as git merge
or git rebase
, because it actually runsgit merge
or git rebase
.
无论如何,您永远不应该使用2git pull
,但是如果您这样做了,请git pull
使用上游设置来确定要从哪个远程获取,然后与哪个分支合并或变基。也就是说,git pull
做同样的事情——git fetch
因为它实际上运行git fetch
——然后做同样的事情git merge
or git rebase
,因为它实际上运行git merge
or git rebase
。
(You should usually just do these two steps manually, at least until you know Git well enough that when either step fails, which they will eventually, you recognize what went wrong and know what to do about it.)
(你通常应该手动完成这两个步骤,至少在你足够了解 Git 之前,当任何一个步骤失败时,他们最终会发现哪里出了问题,并知道如何处理它。)
The upstream affects git status
上游影响 git status
This may actually be the most important. Once you have an upstream set, git status
can report the difference between your current branch and its upstream, in terms of commits.
这实际上可能是最重要的。一旦你有一个上游集,git status
就可以报告你当前分支与其上游之间的差异,就提交而言。
If, as is the normal case, you are on branch B
with its upstream set to origin/B
, and you run git status
, you will immediately see whether you have commits you can push, and/or commits you can merge or rebase onto.
如果像正常情况一样,您在分支上B
,其上游设置为,并且您运行,您将立即看到您是否有可以推送的提交,和/或可以合并或变基的提交。origin/B
git status
This is because git status
runs:
这是因为git status
运行:
git rev-list --count @{u}..HEAD
: how many commits do you have onB
that are not onorigin/B
?git rev-list --count HEAD..@{u}
: how many commits do you have onorigin/B
that are not onB
?
git rev-list --count @{u}..HEAD
:有多少提交你对B
那些不上?origin/B
git rev-list --count HEAD..@{u}
:有多少提交你对那些不上?origin/B
B
Setting an upstream gives you all of these things.
设置上游为您提供了所有这些东西。
How come master
already has an upstream set?
怎么master
已经有上游集了?
When you first clone from some remote, using:
当您第一次从某个远程克隆时,使用:
$ git clone git://some.host/path/to/repo.git
or similar, the last step Git does is, essentially, git checkout master
. This checks out your local branch master
—only you don't havea local branch master
.
或类似的,Git 所做的最后一步本质上是git checkout master
. 此检查出你的本地分支master
-只有你没有拥有一个本地分支master
。
On the other hand, you dohave a remote-tracking branch named origin/master
, because you just cloned it.
另一方面,您确实有一个名为 的远程跟踪分支origin/master
,因为您刚刚克隆了它。
Git guesses that you must have meant: "make me a new local master
that points to the same commit as remote-tracking origin/master
, and, while you're at it, set the upstream for master
to origin/master
."
Git 猜测您的意思一定是:“让我成为一个新的本地master
,指向与 remote-tracking 相同的提交origin/master
,并且,当您在此时,将上游设置为master
to origin/master
。”
This happens for everybranch you git checkout
that you do not already have. Git creates the branch andmakes it "track" (have as an upstream) the corresponding remote-tracking branch.
这发生在您还没有的每个分支上git checkout
。Git 创建分支并使其“跟踪”(作为上游)相应的远程跟踪分支。
But this doesn't work for newbranches, i.e., branches with no remote-tracking branch yet.
但是,这并不工作,为新的分支,即没有远程跟踪支支还没有。
If you create a newbranch:
如果您创建一个新分支:
$ git checkout -b solaris
there is, as yet, no origin/solaris
. Your local solaris
cannottrack remote-tracking branch origin/solaris
because it does not exist.
目前还没有origin/solaris
。您的本地solaris
无法跟踪远程跟踪分支,origin/solaris
因为它不存在。
When you first push the new branch:
当您第一次推送新分支时:
$ git push origin solaris
that createssolaris
on origin
, and hence also creates origin/solaris
in your own Git repository. But it's too late: you already have a local solaris
that has no upstream.3
这造成solaris
的origin
,因此也创造origin/solaris
你自己的Git仓库。但为时已晚:你已经有一个地方solaris
是没有的上游。3
Shouldn't Git just set that, now, as the upstream automatically?
现在,Git 不应该自动将其设置为上游吗?
Probably. See "implemented poorly" and footnote 1. It's hard to change now: There are millions4of scripts that use Git and some may well depend on its current behavior. Changing the behavior requires a new major release, nag-ware to force you to set some configuration field, and so on. In short, Git is a victim of its own success: whatever mistakes it has in it, today, can only be fixed if the change is either mostly invisible, clearly-much-better, or done slowly over time.
大概。请参阅“执行不力”和脚注1。这是很难改变现在:有几百万4使用Git的脚本和一些可能取决于其当前行为。改变行为需要一个新的主要版本,nag-ware 强制你设置一些配置字段,等等。简而言之,Git 是其自身成功的受害者:今天,无论它有什么错误,只有在更改几乎不可见、明显好得多或随着时间的推移缓慢完成时,才能修复。
The fact is, it doesn't today, unlessyou use --set-upstream
or -u
during the git push
. That's what the message is telling you.
事实是,今天不会,除非您使用--set-upstream
或-u
在git push
. 这就是消息告诉你的。
You don't have to do it like that. Well, as we noted above, you don't have to do it at all, but let's say you wantan upstream. You have already created branch solaris
on origin
, through an earlier push, and as your git branch
output shows, you already haveorigin/solaris
in your local repository.
你不必那样做。好吧,正如我们上面提到的,您根本不必这样做,但假设您想要一个上游。你已经创建的分支solaris
上origin
,通过早期的推动,并作为你的git branch
输出显示,你已经有origin/solaris
在本地资源库。
You just don't have it set as the upstream for solaris
.
您只是没有将其设置为solaris
.
To set it now, rather than during the first push, use git branch --set-upstream-to
. The --set-upstream-to
sub-command takes the name of any existing branch, such as origin/solaris
, and sets the current branch's upstream to that other branch.
要立即设置它,而不是在第一次推送期间,请使用git branch --set-upstream-to
. 所述--set-upstream-to
子命令采用名称的任何现有分支的,如origin/solaris
,并设定当前分支的上游到其他分支。
That's it—that's all it does—but it has all those implications noted above. It means you can just run git fetch
, then look around, then run git merge
or git rebase
as appropriate, then make new commits and run git push
, without a bunch of additional fussing-around.
就是这样 - 这就是它所做的 - 但它具有上述所有含义。这意味着您可以只运行git fetch
,然后环顾四周,然后运行git merge
或git rebase
在适当的情况下,然后进行新的提交并运行git push
,而无需额外的大惊小怪。
1To be fair, it was not clear back then that the initial implementation was error-prone. That only became clear when every new user made the same mistakes every time. It's now "less poor", which is not to say "great".
1公平地说,当时并不清楚最初的实施是否容易出错。只有当每个新用户每次都犯同样的错误时,这一点才变得清晰。现在是“不那么差”,也不是说“很棒”。
2"Never" is a bit strong, but I find that Git newbies understand things a lot better when I separate out the steps, especially when I can show them what git fetch
actually did, and they can then see what git merge
or git rebase
will do next.
2“从不”有点强,但我发现当我将步骤分开时,Git 新手会更好地理解事情,尤其是当我可以向他们展示git fetch
实际做了什么,然后他们可以看到下一步做什么git merge
或git rebase
将要做什么时。
3If you run your firstgit push
as git push -u origin solaris
—i.e., if you add the -u
flag—Git will set origin/solaris
as the upstream for your current branch if (and only if) the push succeeds. So you should supply -u
on the firstpush. In fact, you can supply it on any later push, and it will set or changethe upstream at that point. But I think git branch --set-upstream-to
is easier, if you forgot.
3如果你运行你的第一个——git push
即git push -u origin solaris
,如果你添加了-u
标志——origin/solaris
当(且仅当)推送成功时,Git 将设置为当前分支的上游。所以你应该-u
在第一次推送时提供。实际上,您可以在以后的任何推送中提供它,并且它会在那时设置或更改上游。但我认为git branch --set-upstream-to
更容易,如果你忘记了。
4Measured by the Austin Powers / Dr Evil method of simply saying "one MILLLL-YUN", anyway.
4无论如何,通过 Austin Powers / Dr Evil 简单地说“one MILLLL-YUN”的方法来衡量。
回答by Adam
The difference betweengit push origin <branch>
andgit push --set-upstream origin <branch>
is that they both push just fine to the remote repository, but it's when you pull that you notice the difference.
git push origin <branch>
和之间的区别在于git push --set-upstream origin <branch>
它们都可以很好地推送到远程存储库,但是当您拉取时,您会注意到差异。
If you do:git push origin <branch>
when pulling, you have to do:git pull origin <branch>
如果你这样做:git push origin <branch>
在拉动时,你必须这样做:git pull origin <branch>
But if you do:git push --set-upstream origin <branch>
then, when pulling, you only have to do:git pull
但是如果你这样做:git push --set-upstream origin <branch>
那么,在拉动时,你只需要这样做:git pull
So adding in the --set-upstream
allows for not having to specify which branch that you want to pull from every single time that you do git pull
.
因此,添加--set-upstream
允许不必每次都指定要从哪个分支中提取git pull
。
回答by ElpieKay
A basically full command is like git push <remote> <local_ref>:<remote_ref>
. If you run just git push
, git does not know what to do exactly unless you have made some config that helps git to make a decision. In a git repo, we can setup multiple remotes. Also we can push a local ref to any remote ref. The full command is the most straightforward way to make a push. If you want to type fewer words, you have to config first, like --set-upstream.
一个基本完整的命令就像git push <remote> <local_ref>:<remote_ref>
. 如果你只运行git push
,git 不知道要做什么,除非你做了一些配置来帮助 git 做出决定。在 git repo 中,我们可以设置多个遥控器。我们也可以将本地引用推送到任何远程引用。full 命令是最直接的推送方式。如果你想输入更少的单词,你必须先配置,比如--set-upstream。