为什么从分离的HEAD创建新的远程分支的git push语法如此不同?

时间:2013-09-16 23:30:08

标签: git

最近,我有一个场景,我处于一个独立的HEAD状态。我想把它推到github的一个fork上,以便与一个队友分享一些正在进行中的代码。我不需要这个特定提交的本地分支名称。

显然,这不起作用:

git push sandy-github HEAD

这是有道理的,因为我没有为远程分支指定名称。

但我不明白为什么这不起作用:

git push sandy-github HEAD:mynewbranch

这导致以下错误:

  

错误:无法推送到不合格的目的地:mynewbranch   目标refspec既不匹配遥控器上的现有引用也不匹配   以refs /开头,我们无法根据源ref猜测前缀。   错误:未能将某些引用推送到'git@github.com:sandyarmstrong / myreponame.git'

我最终不得不这样做:

git push sandy-github HEAD:refs/heads/mynewbranch

这很有用。来自文档:

  

git push origin master:refs / heads / experimental

     

通过复制当前主分支在原始存储库中创建分支实验。只有创建新表单才需要此表单   当本地名称和时,远程存储库中的分支或标记   远程名称不同;否则,引用名称本身就是   工作

我只是不明白为什么这是必要的。我猜这里有一些关于git的重要事情我在这里误会了。为什么这个棘手的语法只是因为名称不匹配而必需?为什么HEAD:mynewbranch语法不足以让git知道它应该在名为“mynewbranch”的远程上生成一个新分支?

3 个答案:

答案 0 :(得分:8)

git push documentationrefspec部分有这个(强调我的):

  

<dst>通过此推送告知远程端的哪个ref更新。 此处不能使用任意表达式,必须命名实际引用。 如果省略:<dst>,则会更新与<src>相同的引用。

在正常状态下,git可以根据分支跟踪和/或配置中push.default的值确定您是否要推送到某个分支(或标记)。

在分离的HEAD状态下,git无法猜测您是要创建新分支还是新标记(这两种方式都合理)。

可以通过首先创建本地分支来暗示创建分支:

git checkout -b mynewbranch
git push -u sandy-github mynewbranch

如果您不想查看正在推送的分支机构,可以使用问题中提到的refs/heads/前缀:

git push sandy-github HEAD:refs/heads/mynewbranch

答案 1 :(得分:1)

Git在许多命令中都有相当数量的“魔法”或“DWIM”*。 “推送”具有以下功能:如果您将本地分支b推送到远程并且远程具有b,则它使用magic / DWIM部分来协调本地引用(其“真实”名称为{ {1}})远程的(其名称,在遥控器上,也是refs/heads/b)。但您也可以推送refs/heads/b,或现在存在注释,refs/tags/t

它已经有魔术/ DWIM来实现当你使用{时,解析为本地全名refs/notes/commits的本地引用y应该在遥控器上创建相同的refs/x/y {1}},即使遥控器上不存在refs/x/y。只是如果本地全名没有解决这样的问题,那就失败了。当它是分支的符号名称时,它甚至可以解析HEAD,但是当HEAD被“分离”时,没有符号名称。

可以假设y:y“表示”创建y。这可能是最有可能的,因此你的意思。但是,它没有(但是?)。

* DWIM: "Do What I Mean" (as opposed to what I say)

答案 2 :(得分:-1)

这实际上适合我。你是旧版本的git还是什么?

作为参考,我运行了以下内容:

MacBook:AndroidAsync[master*]$ git commit -a -m gitignore
[master 69851e1] gitignore
 1 file changed, 1 insertion(+)
MacBook:AndroidAsync[master]$ git push origin HEAD:master
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 343 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
To ssh://git@github.com/koush/AndroidAsync
   04b2f79..69851e1  HEAD -> master

版本:

MacBook:AndroidAsync[master]$ git --version
git version 1.8.2.1 (Apple Git-45)

还证实从独立的HEAD工作:

MacBook:AndroidAsync[(no branch)]$ git push origin HEAD:master
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 332 bytes, done.
Total 3 (delta 1), reused 1 (delta 0)
To ssh://git@github.com/koush/AndroidAsync
   69851e1..ae2d1be  HEAD -> master