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

Dmi*_*rov 5 git git-remote git-branch

Git 非分支引用(不是分支、标签、远程和注释)在本地计算机中工作得很好,但我在将它们推送到远程时遇到了麻烦:

$ git update-ref refs/exp/ee01 6a534fb5f9aad615ebeeb9d01ebe558a679a3cd1
Run Code Online (Sandbox Code Playgroud)

就创建成功了:

$ cat .git/refs/exp/ee01
6a534fb5f9aad615ebeeb9d01ebe558a679a3cd1
$ git for-each-ref refs/exp
6a534fb5f9aad615ebeeb9d01ebe558a679a3cd1 commit refs/exp/ee01
Run Code Online (Sandbox Code Playgroud)

推动它:

$ 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
Run Code Online (Sandbox Code Playgroud)

但是,当我克隆此存储库时,我没有看到它:

$ 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
Run Code Online (Sandbox Code Playgroud)

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

编辑:我可以通过名称将其获取到 FETCH_HEAD。理想情况下,我应该在不提前知道名称的情况下查看\获取所有新参考文献。

$ git fetch origin exp/ee01
From https://github.com/dmpetrov/example-get-started-exp
 * branch            refs/exp/ee01 -> FETCH_HEAD
Run Code Online (Sandbox Code Playgroud)

tor*_*rek 6

参考规格作为一个一般概念是很棒的,但它们给人一种未完成的感觉。

\n

当您第一次克隆某些现有存储库时,您git clone将使用内置等效项git remote add来添加远程名称。正如文档git remote所述(有点省略 - 请参阅含义 2a):

\n
\n

使用选项,将创建-t <branch>一个仅跟踪的引用规范refs/remotes/<name>/,而不是使用默认的全局引用规范来跟踪命名空间下的所有分支。<branch>您可以给予多于一份-t <branch>分支来跟踪多个分支,而无需获取所有分支。

\n
\n

这归结为以下事实: after git clone,新克隆的(单个)默认获取引用规范是:

\n
+refs/heads/*:refs/remotes/<name>/*\n
Run Code Online (Sandbox Code Playgroud)\n

其中<name>是选项的名称-o,或者origin如果您没有指定此类选项。1

\n

它没有明确提及且不明显的是,Git 配置文件中的设置是累积的。2这意味着您可以在创建现有文件后 打开该文件并对其进行编辑。你会看见:remote.remote.fetch.git/configgit clone

\n
[remote "origin"]\n    fetch = +refs/heads/*:refs/remotes/origin/*\n
Run Code Online (Sandbox Code Playgroud)\n

您可以更改它以添加另一行,以便它显示:

\n
[remote "origin"]\n    fetch = +refs/heads/*:refs/remotes/origin/*\n    fetch = +refs/exp/*:refs/exp/*\n
Run Code Online (Sandbox Code Playgroud)\n

现在,any将会用 上的引用git fetch origin覆盖您现有的任何引用。使用或或选项获取将删除任何在 上没有对应名称的现有引用。refs/exp/originprune = true-p--prunerefs/exp/*origin

\n

如果您想将他们的refs/exp/*名字替换为您自己的refs/rexp/origin/*名字,请将第二行改为:

\n
    fetch = +refs/exp/*:refs/rexp/origin/*\n
Run Code Online (Sandbox Code Playgroud)\n

现在你已经发明了exp跟踪名称。

\n

(考虑到没有带refs/tags/*:refs/tags/*或不带前导+符号的 refspec\xe2\x80\x94,您可能想知道标签是如何工作的。这里的答案是“有点神奇,内部规则无法通过 refspec 表达” “。这就是我所说的有点未完成的感觉的一部分。在 a 期间放入什么也不是很明显git clone,但请注意,它可以让您随时写入配置值。您仍然需要以某种方式知道不过,您正在克隆的远程设备有名称。)git clone -c name=valuegit clonerefs/exp/*

\n
\n

1在即将发布的 Git 版本中,该-o选项可能有一个可配置的默认值,因此省略-o并不一定意味着使用origin,但就目前而言,这就是它始终的含义。

\n

2相反,诸如user.name或 之类的设置user.email仅使用最后一个值。也就是说,如果您的配置文件显示:

\n
[user]\n    name = fred\n    name = flintstone\n
Run Code Online (Sandbox Code Playgroud)\n

那么user.name就是flintstone:较早的fred值已被丢弃,取而代之的是较晚的flintstone值。累积设置只能通过git config --get-all或获得git config --get-regexp;它显示为每个值一行。请参阅文档git config了解更多详细信息

\n