为什么我必须“git push --set-upstream origin <branch"? [英] Why do I have to &quot;git push --set-upstream origin &lt;branch&gt;&quot;?

查看:92
本文介绍了为什么我必须“git push --set-upstream origin <branch"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个本地分支来测试 Solaris 和 Sun Studio.然后我将分支推向上游.提交更改并尝试推送更改后:

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:

$ 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?

是否有任何合理的用例可以让某人创建 ,将 推送到远程,然后在 上声明提交<branch> 不应该用于 ?

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>?

我在 Stack Overflow 上关注了这个问题和答案:将一个新的本地分支推送到远程 Git 存储库并进行跟踪.我猜这是另一个不完整或错误的接受答案的例子.或者,这是 Git 执行简单任务并使其变得困难的另一个实例.

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.

这是另一台机器上的视图.分支显然存在,所以它被创建和推送:

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

推荐答案

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

<小时>

您提出的问题的答案(我将其改写为我是否必须设置上游")是:不,您不必将上游设置为全部.

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

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 1.5 版本之前.为了大大缩短它,git push 的实现很差.1 从 Git 2.0 版开始,Git 现在有一个拼写为 push.default 现在默认为 simple.对于 2.0 之前和之后的多个 Git 版本,每次运行 git push 时,Git 都会发出大量噪音试图说服你设置 push.default 只是为了得到 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.1 As 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,也没有提到你是否配置了 push.default,所以我们必须猜测.我的猜测是您正在使用 Git 版本 2-point-something,并且您已将 push.default 设置为 simple 以使其关闭.确切地说,您拥有哪个版本的 Git,以及如果您将 push.default 设置为什么,确实 很重要,因为历史悠久而乏味,但最终,您收到来自 Git 的另一项投诉这一事实表明您的 Git 配置为避免过去犯下的一个错误.

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.

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

An upstream is simply another branch name, usually a remote-tracking branch, associated with a (regular, local) branch.

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

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.

上游应该,但不一定是,一个有效的分支(无论是像origin/B这样的远程跟踪还是像本地这样的<代码>主).也就是说,如果当前分支B有上游Ugit rev-parse U 应该 工作.如果它不起作用——如果它抱怨 U 不存在——那么大多数 Git 就像上游根本没有设置一样.一些命令,例如 git branch -vv,将显示上游设置,但将其标记为gone".

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 B has upstream U, git rev-parse U should work. If it does not work—if it complains that U does 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".

如果您的 push.default 设置为 simpleupstream,上游设置将使 git push, 无需额外参数即可使用.

If your push.default is set to simple or upstream, the upstream setting will make git push, used with no additional arguments, just work.

就是这样——这就是它为 git push 所做的一切.但这是相当重要的,因为 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.

如果您的 push.default 设置为 nothingmatchingcurrent,则设置上游不会git push 什么都没有.

If your push.default is set to nothing, matching, or current, setting an upstream does nothing at all for git push.

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

(All of this assumes your Git version is at least 2.0.)

如果你运行 git fetch 没有额外的参数,Git 会通过查询当前分支的上游来确定要从哪个远程获取.如果上游是远程跟踪分支,则 Git 从该远程获取.(如果上游没有设置或者是本地分支,Git 会尝试获取 origin.)

If you run git fetch with no additional arguments, Git figures out which remote 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 mergegit rebase,Git 将使用当前分支的上游.所以缩短了这两个命令的使用时间.

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.

无论如何你都不应该2使用git pull,但是如果你这样做了,git pull 使用上游设置来确定要使用哪个远程从哪个分支中获取,然后与哪个分支合并或变基.也就是说,git pullgit fetch 做同样的事情——因为它实际上 runs git fetch——然后与 git mergegit rebase 做同样的事情,因为它实际上 runs git mergegit变基.

You should never2 use 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 runs git fetch—and then does the same thing as git merge or git rebase, because it actually runs git merge or git rebase.

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

(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 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.

如果在正常情况下,您在分支 B 上,其上游设置为 origin/B,然后运行 ​​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.

这是因为 git status 运行:

  • 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.

当你第一次从某个远程克隆时,使用:

When you first clone from some remote, using:

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

或类似的,Git 所做的最后一步本质上是 git checkout master.这会检查您的本地分支 master — 只有您没有 本地分支 master.

or similar, the last step Git does is, essentially, git checkout master. This checks out your local branch master—only you don't have a local branch master.

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

On the other hand, you do have a remote-tracking branch named origin/master, because you just cloned it.

Git 猜测你的意思一定是:让我成为一个新的本地 master,它指向与远程跟踪 origin/master 相同的提交,并且,当你在这里,将 master 的上游设置为 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 checkout.Git 创建分支使其跟踪"(作为上游)相应的远程跟踪分支.

This happens for every branch you git checkout that you do not already have. Git creates the branch and makes it "track" (have as an upstream) the corresponding remote-tracking branch.

如果您创建一个分支:

$ git checkout -b solaris

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

there is, as yet, no origin/solaris. Your local solaris cannot track remote-tracking branch origin/solaris because it does not exist.

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

When you first push the new branch:

$ git push origin solaris

origin创建 solaris,因此也在您自己的Git 存储库中创建origin/solaris.但为时已晚:您已经拥有一个本地 solaris,它没有上游.3

that creates solaris 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

可能吧.请参阅实施不佳"和脚注 1.现在很难改变:有数百万4 个使用 Git 的脚本,其中一些很可能取决于其当前的行为.改变行为需要一个新的主要版本,nag-ware 强制你设置一些配置字段,等等.简而言之,Git 是其自身成功的受害者:今天,无论它有什么错误,只有在更改几乎不可见、明显好得多或随着时间的推移缓慢完成时,才能修复.

Probably. See "implemented poorly" and footnote 1. It's hard to change now: There are millions4 of 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.

事实是,今天不会,除非您在 期间使用 --set-upstream-ugit push.这就是消息告诉您的内容.

The fact is, it doesn't today, unless you use --set-upstream or -u during the git push. That's what the message is telling you.

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

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 want an upstream. You have already created branch solaris on origin, through an earlier push, and as your git branch output shows, you already have origin/solaris in your local repository.

您只是没有将其设置为 solaris 的上游.

You just don't have it set as the upstream for solaris.

要立即设置,而不是在第一次推送时设置,请使用 git branch --set-upstream-to.--set-upstream-to 子命令采用任何现有分支的名称,例如 origin/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 fetch,然后环顾四周,然后根据需要运行 git mergegit rebase,然后进行新的提交并运行git push,没有一堆额外的麻烦.

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.

1公平地说,当时并不清楚最初的实现是否容易出错.只有当每个新用户每次都犯同样的错误时,这一点才变得清晰.现在是不那么差",也不是说很棒".

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".

2从不"有点强,但我发现当我将步骤分开时,Git 新手会更好地理解事物,尤其是当我可以向他们展示 git fetch 确实做到了,然后他们可以看到 git mergegit rebase 接下来会做什么.

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.

3如果你运行你的第一个 git push 作为 git push -u origin solaris——即,如果您添加 -u 标志 - 如果(且仅当)推送成功,Git 会将 origin/solaris 设置为当前分支的上游.所以你应该在 first 推送时提供 -u .事实上,你可以在以后的任何推送中提供它,它会在那个时候设置或改变上游.但我认为 git branch --set-upstream-to 更容易,如果你忘记了.

3If you run your first git 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 first push. In fact, you can supply it on any later push, and it will set or change the upstream at that point. But I think git branch --set-upstream-to is easier, if you forgot.

4无论如何,通过 Austin Powers/Dr Evil 简单地说一个 MILLLL-YUN"的方法来衡量.

4Measured by the Austin Powers / Dr Evil method of simply saying "one MILLLL-YUN", anyway.

这篇关于为什么我必须“git push --set-upstream origin <branch"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆