`git clone --mirror`后Git笔记丢失。

4
我将尝试镜像一个本地仓库,包括所有可用的“refs”,包括“refs/notes/*”。然而,注释并没有如预期那样被克隆。
要重现此问题,请在空目录中执行以下命令:
$ git init repo && cd repo
$ git commit --allow-empty -m 'initial commit'
$ git notes add -m 'Initial commit on empty repo' HEAD
$ git clone --mirror .git ../mirror

获取引用之间的差异显示镜像存储库中缺少notes

$ diff repo/.git/refs mirror/refs
Common subdirectories: repo/.git/refs/heads and mirror/refs/heads
Common subdirectories: repo/.git/refs/tags and mirror/refs/tags
Only in repo/.git/refs: notes

git -C mirror fetch并没有获取注释,即使在mirror/config中已经指定了fetch = +refs/*:refs/*

现在的问题是:我错过了什么吗?我正在使用git 2.3.0版本。

1个回答

5
当使用git clonegit fetch获取引用时,它们通常会将它们“压缩”。未压缩的引用按其完整名称存储在.git/refs/中的一个文件中,因此您可以获得例如.git/refs/heads/master.git/refs/notes/commits。目前,压缩的引用都存储在一个文件.git/packed-refs中。该文件每行包含一个引用,对于一些引用(如带注释标签),还有一个额外的“去壳”变体。如果引用同时出现在两个位置,则Git“优先”选择未压缩的引用(这样在更新引用时就不必从压缩文件中删除条目)。更新引用通常会解压它:与在多条目文件中替换一行相比,保持更新类似于单条目文件.git/refs/heads/master更好和/或更容易。Git随时允许解压或重新打包引用,因此简单地diff两个.git树无法保证任何好处。(对于打包和未打包的对象也是如此,但我看到您正在查看refs子目录)因此,您引用的差异输出并未说明是否克隆了注释。要查看是否克隆了注释,请进入克隆并使用读取注释的操作。在任何情况下,如果有一行fetch = +refs/*:refs/*,则应该将注释复制。

.git/packed-refs 是这里缺失的关键。从这个答案中最重要的一点是,你不应该依赖于 git 的文件结构,这就是为什么我的 diff 命令没有意义的原因。相反,应该使用管道命令,例如 git for-each-ref - Tim Keller

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