为什么我需要显式地推送一个新分支?

206

我是 git 的新手,正在练习。我创建了一个本地分支,但当我执行 git push 命令时,我的分支没有上传到代码库中。我必须实际执行以下命令:git push -u origin --all
为什么会这样?难道分支不是默认要推送的新更改吗?为什么我需要运行第二个命令?


17
请注意,这是可以配置的(设置 push.default,参见 man git-config)。如果您运行 git config --add push.default current,则执行 git push 将自动在远程仓库中创建分支(如果需要)。为什么这不是默认设置,在答案中有解释。 - sleske
@sleske 我同意。关于其他策略“current”和“upstream”,请参见我的旧回答https://dev59.com/ZmYr5IYBdhLWcg3wVY7K#13751847。 - VonC
8个回答

271

实际原因是,在新的仓库(git init)中,没有分支(没有master,没有任何分支,零个分支)。

因此,当你第一次向一个空的上游仓库(通常是裸仓库)推送时,该上游仓库没有同名的分支。

并且:

无论哪种情况,由于上游空仓库没有分支:

  • 尚未有同名的匹配分支
  • 没有任何上游分支(无论是否有相同的名称!无论是跟踪还是不跟踪)

这意味着你本地的第一次推送不知道:

  • 要推送到哪里
  • 要推送什么(因为它找不到任何远程跟踪分支被记录,或者具有相同的名称)

所以你至少需要执行:

git push origin master

但是如果只这样做,你会:

  • 在上游(非空仓库)上创建上游master分支:好。
  • 不会记录本地分支'master'需要推送到上游(origin) 'master' (上游分支)的情况:坏。

因此,在第一次推送时,建议执行以下操作:

git push -u origin master

或者,使用 Git 2.37 和新的全局选项 push.autoSetupRemote

git config --global push.autoSetupRemote true
git push

这将把origin/master记录为远程跟踪分支,并使下一次推送自动将master推送到origin/master

git checkout master
# Git 2.23+
git switch master
git push

如果使用推送策略 'current' 或 'upstream',也是可以的。
在每种情况下,初始命令 git push -u origin master 后,只需使用简单的 git push 命令即可继续将 master 推送到正确的上游分支。


2
在此之后,下一个 git push 命令也期望该分支已经存在? - Cratylus
2
是的,它会将该分支的任何更新推送到上游存储库。 - RyPeck
@Cratylus 是的,因为新的默认推送策略是“simple”:将推送到任何已记录的上游分支,如果该上游分支与本地分支同名。一个简单的 git push 就足够了。 - VonC
1
@ButtleButkus 谢谢。我已经恢复了链接。 - VonC
4
对于提问者更一般的情况,即创建一个名为“new_branch”的新分支,你可以使用命令 git push --set-upstream origin new_branch 或简写形式的 git push -u origin new_branch。而提问者使用的 -all 选项跳过了特定新分支的命名,而是包括所有分支。这个问题在 +Klas Mellbourn 的答案中已经被解决了。 - Paul Masri-Stone
显示剩余6条评论

119

你看下面

我发现这个“特性”相当恼人,因为我不是要发射火箭到月球,只是推送我的分支。你可能也这么想,否则你就不会在这里了!

这是解决方法:如果你希望无论当前分支是否存在于远程仓库,都隐式地推送当前分支,请执行此命令一次,以后任何地方都不需要再执行:

git config --global push.default current

因此,如果您创建这样的分支:

git checkout -b my-new-branch

然后进行一些提交,然后执行 a 操作。

git push -u

如果你想把它们带回原点(在该分支上),它会为你创建该分支(如果不存在)。

请注意,-u 参数可以确保在稍后从该分支拉取时它们是链接的。如果你没有计划稍后拉取该分支(或者如果你愿意使用另一行代码),则不需要 -u 参数。


3
当我这样做时,如果我进行git pull操作,紧接着执行后,这两个分支不会链接起来。 :( - Alisso
这是唯一解决了我的问题的答案。 - Raymond Chenon
2
要将它们链接起来,请使用 git push -u - Ben Creasy
谢谢!这个答案应该被接受为快速且“简单”的解决方案。我非常确定它最接近OP的意图。 - youngrrrr
3
我不是在试图将火箭发射到月球。-- 是的。 - VCavallo

43

推送新分支时,git push的输出结果

> git checkout -b new_branch
Switched to a new branch 'new_branch'
> git push
fatal: The current branch new_branch has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin new_branch

一个简单的git push假定当前本地分支正在跟踪一个已经存在的远程分支。如果不存在这样的远程分支,并且您想要创建它,则必须使用-u--set-upstream的缩写形式)标志来指定。

为什么会这样呢?我想实现者们认为,在远程创建一个分支是如此重要的操作,以至于不应该通过错误轻易执行它。 git push是您经常执行的操作。

“不是默认情况下分支是要推送的新更改吗?” 我会说Git中的“更改”是提交。分支是指向提交的指针。对我而言,更有意义的是把push视为将提交推送到其他存储库。推送哪些提交取决于您在哪个分支上以及该分支与远程分支之间的跟踪关系。

您可以在Pro Git书籍的远程分支章节中了解更多关于跟踪分支的内容。


@Cratylus 不用担心。提交已经安全地存储在你的代码库里了,而 git push -u origin 命令已经将它复制到远程代码库中了。 - Klas Mellbourn
不,我是指我没有像你在答案中提到的那样收到“致命”的消息。这个差异是否取决于我向分支提交了一些内容? - Cratylus
@Cratylus 我不知道为什么你没有收到“fatal”消息。我猜这取决于你使用的git实现的具体版本。我的输出来自运行在Windows 8上的1.8.1.msysgit.1版本。 - Klas Mellbourn
@Cratylus 即使我提交了代码,我仍然会收到“fatal”错误消息。 - Klas Mellbourn
@Cratylus 你可以通过执行 git config --global push.default simple 来避免那个消息。你得到 Everything up-to-date 的原因可能是远程已经存在一个被本地的 name 分支跟踪的 name 分支。 - Klas Mellbourn
显示剩余5条评论

4

我无法立即找到原开发者的理由,但基于几年的Git经验,我可以给你一个有根据的猜测。

不,不是每个分支都需要推送到外部世界。它可能代表一个私有实验。

此外,git push应该将所有分支发送到哪里?Git可以使用多个远程仓库,并且您可能希望在每个仓库中拥有不同的分支集合。例如,中央项目GitHub仓库可能具有发布分支;GitHub分支可能具有用于审核的主题分支;本地Git服务器可能具有包含本地配置的分支。如果git push会将当前分支跟踪的所有分支推送到远程,则这种方案很容易出错。


  1. "这可能代表一个私人实验。" 好的,但这有什么大不了的?每个人都在工作的“主”分支即“master”没有受到影响。除非你的意思是要隐藏源代码。
  2. "git push,没有远程,会推送到当前分支的远程"。我在这里有点懵。
- Cratylus
@Cratylus: 在一个有数十位开发人员自由分支的项目中,您将得到非常混乱的仓库。我在这样的项目上工作过,每次都不希望执行 git fetch 命令来获取成百上千个半工作的分支。2)我指的是git push命令的默认行为。如果当前分支有远程跟踪分支,则会将更改推送到该远程分支。 - Fred Foo

3

HEAD是当前分支的简写,所以git push -u origin HEAD有效。现在为了避免每次输入这个命令,我使用别名:

git config --global alias.pp 'push -u origin HEAD'

之后,每当我想要推送通过git -b branch创建的分支,我可以使用以下命令进行推送:

git pp

希望这能为某些人节省时间!


2

首先检查

步骤1:git remote -v
//如果找到git初始化,则删除或跳过步骤2

步骤2:git remote rm origin
//然后全局配置您的电子邮件地址 git

步骤3:git config --global user.email "youremail@example.com"

步骤4:git initial

步骤5:git commit -m "Initial Project"
//如果已经添加了项目仓库,则跳过步骤6

步骤6:git remote add origin %repo link from bitbucket.org%

步骤7:git push -u origin master


1
我刚刚遇到了这个问题的另一种变形。 我有一个名为feat/XYZ-1234-some-description的分支,因为我正在处理Jira 1234问题。在工作期间,我创建了一个新的Jira问题来跟踪一个更小的工作片段,当我要推送时,我决定将其推送到一个以此新问题编号命名的分支。
git push -u origin feat/XYZ-5678-a-different-description # failed

这给了我在这个SO线程中讨论的错误。但由于我试图从当前分支推送到一个不同的分支名称,我的问题与此处描述的问题不同。最终我不得不重命名我的本地分支才能推送它:
git branch -m feat/XYZ-1234-some-description feat/XYZ-5678-a-different-description
git push -u origin feat/XYZ-5678-a-different-description # now works

经过更多的阅读,我意识到我可以在git push上设置src,可以是当前分支名称,也可以是适当的HEAD

git push -u origin feat/XYZ-1234-some-description:feat/XYZ-5678-a-different-description # also works

-1
如果您第一次从新分支推送新更改并遇到以下错误:

*git push -f
fatal: The current branch Coding_Preparation has no upstream branch.

要推送当前分支并将远程设置为上游,请使用以下命令

git push -u origin new_branch_name


** Successful Result:** 
 git push -u origin Coding_Preparation
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 599 bytes | 599.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'Coding_Preparation' on GitHub by visiting: ...
 * [new branch]      Coding_Preparation -> Coding_Preparation
Branch 'Coding_Preparation' set up to track remote branch 'Coding_Preparation' from 'origin'.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接