将Git非分支引用推送到远程

问题描述

Git非分支引用(非分支,标签,远程和注释)在本地计算机上工作正常,但是我有种种麻烦将它们推到远程:

$ git update-ref refs/exp/ee01 6a534fb5f9aad615ebeeb9d01ebe558a679a3cd1

它已成功创建:

$ cat .git/refs/exp/ee01
6a534fb5f9aad615ebeeb9d01ebe558a679a3cd1
$ git for-each-ref refs/exp
6a534fb5f9aad615ebeeb9d01ebe558a679a3cd1 commit refs/exp/ee01

按下:

$ git push origin exp/ee01
Total 0 (delta 0),reused 0 (delta 0)
To https://github.com/dmpetrov/example-get-started-exp.git
 * [new branch]      refs/exp/ee01 -> refs/exp/ee01

但是,克隆此存储库时看不到它:

$ git clone https://github.com/dmpetrov/example-get-started-exp.git
$ cd example-get-started-exp/
$ git for-each-ref refs/exp  # it returns nothing

如何正确推送非分支引用?

编辑:我可以按名称将其获取到FETCH_HEAD。理想情况下,我应该在不事先知道名称的情况下看到\获取所有新引用。

$ git fetch origin exp/ee01
From https://github.com/dmpetrov/example-get-started-exp
 * branch            refs/exp/ee01 -> FETCH_HEAD

解决方法

参考规格是一个很好的一般概念,但感觉有些未完成。 ?

第一次克隆某些现有存储库时,您的git clone使用等效于git remote add的内置方法来添加远程名称。正如the git remote documentation所述(有点elliptically - see meaning 2a):

使用-t <branch>选项,代替用于跟踪refs/remotes/<name>/名称空间下所有分支的远程默认glob refspec,将创建仅跟踪<branch>的refspec。您可以指定多个-t <branch>来跟踪多个分支,而不必抓住所有分支。

这归结为以下事实:git clone之后,新克隆的(单个)默认获取refspec是:

+refs/heads/*:refs/remotes/<name>/*

其中<name>-o选项的名称,如果未指定此选项,则为origin 1

Git配置文件中的remote.remote.fetch设置是累积性的。 2 这意味着您可以打开现有的.git/config创建git clone文件后,对其进行编辑。您将看到:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*

您可以更改它以添加另一行,使其显示为:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    fetch = +refs/exp/*:refs/exp/*

现在,任何git fetch origin都将用refs/exp/上的引用覆盖您现有的所有origin引用。使用prune = true-p--prune选项进行提取将删除refs/exp/*上没有相应名称的任何现有origin引用。

如果您希望用自己的refs/exp/*名称替换其refs/rexp/origin/*名称,则将第二行显示为:

    fetch = +refs/exp/*:refs/rexp/origin/*

现在您已经发明了exp-tracking名称。

(鉴于不存在refs/tags/*:refs/tags/* refspec(带有或不带有前导+),您可能会怀疑标记是如何工作的。答案是“有些神奇,内部规则无法可以通过refspec来表达。”这是我未完成的感觉的一部分。在git clone期间输入的内容也不明显,但是请注意,git clone -c name=value可以让您在{ {1}}时间。您仍然需要以某种方式知道您要克隆的遥控器具有git clone个名称。)


1 在即将发布的Git版本中,refs/exp/*选项可能具有可配置的默认值,因此省略-o不一定意味着使用-o ,但到目前为止,这始终意味着。

2 相反,诸如originuser.name之类的设置仅使用 last 值。也就是说,如果您的配置文件显示:

user.email

[user] name = fred name = flintstone user.name:较早的flintstone值已被丢弃,以较后的fred值为好。累积设置只能通过flintstonegit config --get-all获得;它以每个值一行显示。有关更多详细信息,请参见the git config documentation

,

根据我的经验,如果您要将一些随机的东西推入远程分支到新的分支中,则必须先从本地分支推现有分支,然后才能推送所需的ID:

git push origin master:new-branch
git push origin the-id-i-really-want:new-branch