为什么我必须 "git push --set-upstream origin <branch>"?
Why do I have to "git push --set-upstream origin <branch>"?
我创建了一个本地分支来测试 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
为什么我必须为此做一些特别的事情?
有人会创建 <branch>
,将 <branch>
推送到远程,然后声称对 <branch>
的提交不应该用于 <branch>
?
我在 Stack Overflow 上关注了这个问题和答案:Push a new local branch to a remote Git repository and track it too。我猜这是不完整或错误接受答案的另一个实例。或者,它是 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
一个基本完整的命令就像git push <remote> <local_ref>:<remote_ref>
。如果你 运行 只是 git push
,git 不知道该做什么,除非你做了一些有助于 git 做出决定的配置。在 git 仓库中,我们可以设置多个遥控器。我们也可以将本地引用推送到任何远程引用。完整命令是进行推送的最直接方式。如果你想输入更少的单词,你必须先配置,比如 --set-upstream.
TL;DR: git branch --set-upstream-to origin/solaris
您提出的问题的答案(我将其改写为 "do I have to set an upstream")是:不,您 没有 设置上游完全没有。
如果您没有当前 b运行ch 的上游,但是,Git 会更改其在 git push
和其他命令上的行为。
这里的完整推送故事冗长乏味,历史可以追溯到Git 1.5 版本之前。为了大大缩短它,git push
的实现很糟糕。1 从 Git 2.0 版开始,Git 现在有一个拼写为 push.default
现在默认为 simple
。 Git 2.0前后的几个版本,每次你运行 git push
, Git 都会喷出很多噪音试图说服你设置 push.default
只是让 git push
闭嘴。
你没说你运行是哪个版本的Git,也没有说你有没有配置push.default
,所以大家只能猜测了。我的猜测是您正在使用 Git 版本 2-point-something,并且您已将 push.default
设置为 simple
以使其关闭。确切地说,您拥有 Git 的哪个版本,以及如果您将 push.default
设置为什么,确实 很重要,因为那段漫长而乏味的历史,但在最后,您收到来自 Git 的另一项投诉这一事实表明您的 Git 是 配置为避免过去的错误之一。
什么是上游?
An upstream 只是另一个 b运行ch 名称,通常是远程跟踪 b运行ch,与(常规,本地)关联b运行ch.
每个 b运行ch 都可以选择设置一 (1) 个上游。也就是说,每个 b运行ch 要么有上游,要么没有上游。没有b运行ch可以有一个以上的upstream.
上游 应该,但不一定是有效的 b运行ch(是否像 origin/<em>B</em>
或本地 master
)。即如果当前b运行chB有上游U,gitrev-解析 <em>U</em>
应该 工作。如果它不起作用——如果它抱怨 U 不存在——那么大多数 Git 就好像根本没有设置上游一样。一些命令,如 git branch -vv
,将显示上游设置,但将其标记为 "gone"。
上游有什么好处?
如果您的 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 通过查询当前的 b[= 计算出从哪个远程获取=347=]ch 的上游。如果上游是一个远程跟踪 b运行ch,Git 从那个远程获取。 (如果未设置上游或者是本地 b运行ch,Git 会尝试获取 origin
。)
上游也影响 git merge
和 git rebase
如果您 运行 git merge
或 git rebase
没有附加参数,Git 使用当前 b运行ch 的上游。所以它缩短了这两个命令的使用。
上游影响git pull
你不应该2无论如何使用git pull
,但如果你这样做,git pull
使用上游设置来确定从哪个远程获取,然后与哪个 b运行ch 合并或变基。也就是说,git pull
与 git fetch
做同样的事情——因为它实际上 运行s git fetch
——然后做同样的事情作为git merge
或git rebase
,因为它实际上运行sgit merge
或git rebase
.
(您通常应该手动执行这两个步骤,至少直到您了解 Git 足够清楚,当任一步骤失败时(它们最终会失败),您会认识到哪里出了问题并知道该怎么做它。)
上游影响git status
这实际上可能是最重要的。一旦你有一个上游集,git status
可以报告你当前的 b运行ch 和它的上游之间的差异,就提交而言。
如果正常情况下,您在 b运行ch B
上游设置为 origin/ <em>B</em>
,而你运行git status
,你会立即看到是否有可以推送的提交,and/or可以推送的提交合并或变基到。
这是因为git status
运行s:
git rev-list --count @{u}..HEAD
:你在 B
上有多少次不在 origin/<em>B 上的提交</em>
?
git rev-list --count HEAD..@{u}
:你在 origin/<em>B</em>
上有多少次不在 上的提交B
?
设置上游可为您提供所有这些东西。
怎么 master
已经有上游集了?
当您第一次从某个远程克隆时,使用:
$ git clone git://some.host/path/to/repo.git
或类似的,最后一步 Git 本质上是 git checkout master
。这会检查您的本地 b运行ch master
——只是您没有 本地 b运行ch master
。
另一方面,您确实有一个名为origin/master
的远程跟踪b运行ch,因为您刚刚克隆了它。
Git 猜想你的意思一定是:"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
."
这发生在 每个 b运行ch 你 git checkout
你还没有。 Git 创建 b运行ch and 使其 "track" (作为上游)相应的远程跟踪 b运行ch .
但这不适用于 new b运行ches,即没有远程跟踪的 b运行ches b运行ch 还.
如果创建 new b运行ch:
$ git checkout -b solaris
目前还没有origin/solaris
。您的本地 solaris
无法 跟踪远程跟踪 b运行ch origin/solaris
因为它不存在。
当你第一次推送新的b运行ch:
$ git push origin solaris
在 origin
上创建了 solaris
,因此也在您自己的 Git 存储库中创建了 origin/solaris
。但为时已晚:您已经有一个 没有上游 的本地 solaris
。3
不应该 Git 直接将其设置为自动上游吗?
可能吧。参见 "implemented poorly" 和脚注 1。现在 很难改变:有数百万4 的脚本使用 Git 和有些很可能取决于其当前的行为。改变行为需要一个新的主要版本,nag-ware 强制你设置一些配置字段,等等。简而言之,Git 是其自身成功的牺牲品:无论它在今天有什么错误,只有在变化基本上不可见、明显好得多或随着时间的推移慢慢完成时才能得到修复。
事实是,今天不会,除非您在git push
期间使用--set-upstream
或-u
。这就是消息告诉您的内容。
你不必那样做。好吧,正如我们上面提到的,您根本不必这样做,但假设您想要 一个上游。您已经通过之前的推送在 origin
上创建了 b运行ch solaris
,正如您的 git branch
输出所示,您已经 拥有 origin/solaris
在您的本地存储库中。
您只是没有将其设置为 solaris
的上游。
要现在设置它,而不是在第一次推送时设置,请使用 git branch --set-upstream-to
。 --set-upstream-to
子命令采用任何现有 b运行ch 的名称,例如 origin/solaris
,并将当前 b运行ch 的上游设置为另一个 b运行ch.
仅此而已——仅此而已——但它具有上述所有含义。这意味着您可以 运行 git fetch
,然后环顾四周,然后根据需要 运行 git merge
或 git rebase
,然后进行新的提交和 运行 git push
,没有一堆额外的麻烦。
1公平地说,当时还不清楚最初的实现容易出错。当每个新用户每次都犯同样的错误时,这一点才变得清晰。现在是"less poor",不是说"great".
2"Never" 有点强,但是我发现 Git 新手在我把步骤分开后更容易理解事情,尤其是当我可以向他们展示 git fetch
实际做了什么,然后他们可以看到 git merge
或 git rebase
接下来会做什么。
3如果您 运行 您的 第一个 git push
作为 git push -u origin solaris
——即,如果您添加 -u
标志 - 如果(且仅当)推送成功,Git 将设置 origin/solaris
作为当前 b运行ch 的上游。因此,您应该在 first 推送中提供 -u
。事实上,您可以在以后的任何推送中提供它,它会在那时设置 或更改 上游。但是我觉得 git branch --set-upstream-to
更简单,如果你忘记了。
4通过 Austin Powers / Dr Evil 的方法测量,简单地说 "one MILLLL-YUN",无论如何。
两者的区别
git push origin <branch>
和
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
.
时指定要从哪个分支中提取
我的理解是“-u”或“--set-upstream”允许您为您所在的分支指定上游(远程)存储库,以便下次您运行 "git push",你甚至不必指定远程仓库。
推送并将上游(远程)存储库设置为源:
$ git push -u origin
下次推送时,无需指定远程仓库:
$ git push
-u 标志指定您想要 link 您的本地分支到 上游 分支。如果不存在,这也会创建一个上游分支。 None 这些答案涵盖了我是如何做的(完整的形式)所以这里是:
git push -u origin <your-local-branch-name>
因此,如果您的 local 分店名称是 coffee
git push -u origin coffee
如果您忘记添加存储库 HTTPS link 然后将其与 git push <repo HTTPS>
您可以配置 git 自动执行此操作:
git config --global push.default current
根据我的经验,这在 99% 的情况下都是你想要的。
tl;dr 如果你不想考虑这个但也不想修改你的配置:
git push --set-upstream origin $(git branch --show-current)
我创建了一个本地分支来测试 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
为什么我必须为此做一些特别的事情?
有人会创建 <branch>
,将 <branch>
推送到远程,然后声称对 <branch>
的提交不应该用于 <branch>
?
我在 Stack Overflow 上关注了这个问题和答案:Push a new local branch to a remote Git repository and track it too。我猜这是不完整或错误接受答案的另一个实例。或者,它是 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
一个基本完整的命令就像git push <remote> <local_ref>:<remote_ref>
。如果你 运行 只是 git push
,git 不知道该做什么,除非你做了一些有助于 git 做出决定的配置。在 git 仓库中,我们可以设置多个遥控器。我们也可以将本地引用推送到任何远程引用。完整命令是进行推送的最直接方式。如果你想输入更少的单词,你必须先配置,比如 --set-upstream.
TL;DR: git branch --set-upstream-to origin/solaris
您提出的问题的答案(我将其改写为 "do I have to set an upstream")是:不,您 没有 设置上游完全没有。
如果您没有当前 b运行ch 的上游,但是,Git 会更改其在 git push
和其他命令上的行为。
这里的完整推送故事冗长乏味,历史可以追溯到Git 1.5 版本之前。为了大大缩短它,git push
的实现很糟糕。1 从 Git 2.0 版开始,Git 现在有一个拼写为 push.default
现在默认为 simple
。 Git 2.0前后的几个版本,每次你运行 git push
, Git 都会喷出很多噪音试图说服你设置 push.default
只是让 git push
闭嘴。
你没说你运行是哪个版本的Git,也没有说你有没有配置push.default
,所以大家只能猜测了。我的猜测是您正在使用 Git 版本 2-point-something,并且您已将 push.default
设置为 simple
以使其关闭。确切地说,您拥有 Git 的哪个版本,以及如果您将 push.default
设置为什么,确实 很重要,因为那段漫长而乏味的历史,但在最后,您收到来自 Git 的另一项投诉这一事实表明您的 Git 是 配置为避免过去的错误之一。
什么是上游?
An upstream 只是另一个 b运行ch 名称,通常是远程跟踪 b运行ch,与(常规,本地)关联b运行ch.
每个 b运行ch 都可以选择设置一 (1) 个上游。也就是说,每个 b运行ch 要么有上游,要么没有上游。没有b运行ch可以有一个以上的upstream.
上游 应该,但不一定是有效的 b运行ch(是否像 origin/<em>B</em>
或本地 master
)。即如果当前b运行chB有上游U,gitrev-解析 <em>U</em>
应该 工作。如果它不起作用——如果它抱怨 U 不存在——那么大多数 Git 就好像根本没有设置上游一样。一些命令,如 git branch -vv
,将显示上游设置,但将其标记为 "gone"。
上游有什么好处?
如果您的 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 通过查询当前的 b[= 计算出从哪个远程获取=347=]ch 的上游。如果上游是一个远程跟踪 b运行ch,Git 从那个远程获取。 (如果未设置上游或者是本地 b运行ch,Git 会尝试获取 origin
。)
上游也影响 git merge
和 git rebase
如果您 运行 git merge
或 git rebase
没有附加参数,Git 使用当前 b运行ch 的上游。所以它缩短了这两个命令的使用。
上游影响git pull
你不应该2无论如何使用git pull
,但如果你这样做,git pull
使用上游设置来确定从哪个远程获取,然后与哪个 b运行ch 合并或变基。也就是说,git pull
与 git fetch
做同样的事情——因为它实际上 运行s git fetch
——然后做同样的事情作为git merge
或git rebase
,因为它实际上运行sgit merge
或git rebase
.
(您通常应该手动执行这两个步骤,至少直到您了解 Git 足够清楚,当任一步骤失败时(它们最终会失败),您会认识到哪里出了问题并知道该怎么做它。)
上游影响git status
这实际上可能是最重要的。一旦你有一个上游集,git status
可以报告你当前的 b运行ch 和它的上游之间的差异,就提交而言。
如果正常情况下,您在 b运行ch B
上游设置为 origin/ <em>B</em>
,而你运行git status
,你会立即看到是否有可以推送的提交,and/or可以推送的提交合并或变基到。
这是因为git status
运行s:
git rev-list --count @{u}..HEAD
:你在B
上有多少次不在origin/<em>B 上的提交</em>
?git rev-list --count HEAD..@{u}
:你在origin/<em>B</em>
上有多少次不在 上的提交B
?
设置上游可为您提供所有这些东西。
怎么 master
已经有上游集了?
当您第一次从某个远程克隆时,使用:
$ git clone git://some.host/path/to/repo.git
或类似的,最后一步 Git 本质上是 git checkout master
。这会检查您的本地 b运行ch master
——只是您没有 本地 b运行ch master
。
另一方面,您确实有一个名为origin/master
的远程跟踪b运行ch,因为您刚刚克隆了它。
Git 猜想你的意思一定是:"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
."
这发生在 每个 b运行ch 你 git checkout
你还没有。 Git 创建 b运行ch and 使其 "track" (作为上游)相应的远程跟踪 b运行ch .
但这不适用于 new b运行ches,即没有远程跟踪的 b运行ches b运行ch 还.
如果创建 new b运行ch:
$ git checkout -b solaris
目前还没有origin/solaris
。您的本地 solaris
无法 跟踪远程跟踪 b运行ch origin/solaris
因为它不存在。
当你第一次推送新的b运行ch:
$ git push origin solaris
在 origin
上创建了 solaris
,因此也在您自己的 Git 存储库中创建了 origin/solaris
。但为时已晚:您已经有一个 没有上游 的本地 solaris
。3
不应该 Git 直接将其设置为自动上游吗?
可能吧。参见 "implemented poorly" 和脚注 1。现在 很难改变:有数百万4 的脚本使用 Git 和有些很可能取决于其当前的行为。改变行为需要一个新的主要版本,nag-ware 强制你设置一些配置字段,等等。简而言之,Git 是其自身成功的牺牲品:无论它在今天有什么错误,只有在变化基本上不可见、明显好得多或随着时间的推移慢慢完成时才能得到修复。
事实是,今天不会,除非您在git push
期间使用--set-upstream
或-u
。这就是消息告诉您的内容。
你不必那样做。好吧,正如我们上面提到的,您根本不必这样做,但假设您想要 一个上游。您已经通过之前的推送在 origin
上创建了 b运行ch solaris
,正如您的 git branch
输出所示,您已经 拥有 origin/solaris
在您的本地存储库中。
您只是没有将其设置为 solaris
的上游。
要现在设置它,而不是在第一次推送时设置,请使用 git branch --set-upstream-to
。 --set-upstream-to
子命令采用任何现有 b运行ch 的名称,例如 origin/solaris
,并将当前 b运行ch 的上游设置为另一个 b运行ch.
仅此而已——仅此而已——但它具有上述所有含义。这意味着您可以 运行 git fetch
,然后环顾四周,然后根据需要 运行 git merge
或 git rebase
,然后进行新的提交和 运行 git push
,没有一堆额外的麻烦。
1公平地说,当时还不清楚最初的实现容易出错。当每个新用户每次都犯同样的错误时,这一点才变得清晰。现在是"less poor",不是说"great".
2"Never" 有点强,但是我发现 Git 新手在我把步骤分开后更容易理解事情,尤其是当我可以向他们展示 git fetch
实际做了什么,然后他们可以看到 git merge
或 git rebase
接下来会做什么。
3如果您 运行 您的 第一个 git push
作为 git push -u origin solaris
——即,如果您添加 -u
标志 - 如果(且仅当)推送成功,Git 将设置 origin/solaris
作为当前 b运行ch 的上游。因此,您应该在 first 推送中提供 -u
。事实上,您可以在以后的任何推送中提供它,它会在那时设置 或更改 上游。但是我觉得 git branch --set-upstream-to
更简单,如果你忘记了。
4通过 Austin Powers / Dr Evil 的方法测量,简单地说 "one MILLLL-YUN",无论如何。
两者的区别
git push origin <branch>
和
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
.
我的理解是“-u”或“--set-upstream”允许您为您所在的分支指定上游(远程)存储库,以便下次您运行 "git push",你甚至不必指定远程仓库。
推送并将上游(远程)存储库设置为源:
$ git push -u origin
下次推送时,无需指定远程仓库:
$ git push
-u 标志指定您想要 link 您的本地分支到 上游 分支。如果不存在,这也会创建一个上游分支。 None 这些答案涵盖了我是如何做的(完整的形式)所以这里是:
git push -u origin <your-local-branch-name>
因此,如果您的 local 分店名称是 coffee
git push -u origin coffee
如果您忘记添加存储库 HTTPS link 然后将其与 git push <repo HTTPS>
您可以配置 git 自动执行此操作:
git config --global push.default current
根据我的经验,这在 99% 的情况下都是你想要的。
tl;dr 如果你不想考虑这个但也不想修改你的配置:
git push --set-upstream origin $(git branch --show-current)