可以指示 git fetch pack 获取单个树对象吗?
Can git fetch pack be instructed to fetch a single tree object?
简而言之,有没有一种方法可以让我有效地(space 明智地)从仅支持智能协议但不支持过滤器规范的 git 服务器中指定我想要的确切对象?
更多背景信息:
由于 GitHub 在 pack 协议中缺少过滤器规范支持,我一直在尝试构建一种方法来获取数 GB 的存储库,其中单个提交也包含数 GB 的存储库。我的想法是使用提取包请求(或在服务器上上传包)指定仅单个提交对象的 want
并从那里获取该对象,获取它引用的树,在另一个请求中获取树对象,然后从那里手动指定我想要的 blob 和树对象。不过我发现的是,打包协议似乎是从为您 "want".
的特定提交或树提供尽可能多的数据的角度运作的。
这对我正在做的事情意味着任何时候我指定树哈希的提交,我不仅得到提交或树对象,而且还得到它们包含的每个对象。在使用 deepen 设置来限制我想要的提交次数时也会发生这种情况; 0 什么都不产生,而 1 产生上述结果。我已经验证仅指定一个 blob 的 want
确实会生成一个仅包含该 blob 的包文件,因此该部分确实按预期工作。
您问的是如何像对待本地对象数据库一样对待远程存储库。做到这一点的方法是让文件系统访问远程存储库的对象数据库,比如通过 shelling 进入安装了该对象数据库的系统或通过在本地安装包含它的文件系统。
anytime I specify a commit of a tree hash, I get not just the commit or tree object(s) but also every object they contain as well
是的,否则你最终会得到一个损坏的存储库。如果你想要,你可以像上面提到的那样做,绕过Git的一致性检查,然后运行自己在一个挂载的对象数据库上打包对象,它接受标准输入上的任意 sha,并编写一个包含您要求的对象的包。将输出包放入任何存储库的对象目录中,瞧,该存储库具有这些对象。
除非启用过滤器功能,否则 Git 协议无法满足您的请求。
Git 协议一直被设计为高效地交换一组提交。 Git 在服务器端实现协议的方式是它将客户端的 have
提交标记为无趣,然后将修订从请求的内容向下移动到无趣点,包括所有必要的对象在这些点之间可达。这种方法必然要求您要走的点是提交的。
可以发送对树对象的请求,但服务器端不会执行您期望的操作。你最终会得到那棵树以及从它可以到达的所有东西(所有的斑点和其他树)在包中,这将是比你想要的多得多的数据。同样,如果您考虑 Git 协议的工作原理,这是非常有意义的:用户已请求从该点可到达的所有对象。
您可以指定 have
某些树对象以排除它们,当然这需要您知道它们是什么,而在本例中您不知道。即便如此,您仍然会收到该层级中存在的 blob。
过滤器功能仅调整包含在包中的对象,因此您可以通过排除低于其深度的所有对象来指定只包含一个树对象。这些参数被传递给 git rev-list --objects
以便包生成将排除您不感兴趣的内容。否则,默认情况下会包含您请求范围内的每个可到达对象。
简而言之,有没有一种方法可以让我有效地(space 明智地)从仅支持智能协议但不支持过滤器规范的 git 服务器中指定我想要的确切对象?
更多背景信息:
由于 GitHub 在 pack 协议中缺少过滤器规范支持,我一直在尝试构建一种方法来获取数 GB 的存储库,其中单个提交也包含数 GB 的存储库。我的想法是使用提取包请求(或在服务器上上传包)指定仅单个提交对象的 want
并从那里获取该对象,获取它引用的树,在另一个请求中获取树对象,然后从那里手动指定我想要的 blob 和树对象。不过我发现的是,打包协议似乎是从为您 "want".
这对我正在做的事情意味着任何时候我指定树哈希的提交,我不仅得到提交或树对象,而且还得到它们包含的每个对象。在使用 deepen 设置来限制我想要的提交次数时也会发生这种情况; 0 什么都不产生,而 1 产生上述结果。我已经验证仅指定一个 blob 的 want
确实会生成一个仅包含该 blob 的包文件,因此该部分确实按预期工作。
您问的是如何像对待本地对象数据库一样对待远程存储库。做到这一点的方法是让文件系统访问远程存储库的对象数据库,比如通过 shelling 进入安装了该对象数据库的系统或通过在本地安装包含它的文件系统。
anytime I specify a commit of a tree hash, I get not just the commit or tree object(s) but also every object they contain as well
是的,否则你最终会得到一个损坏的存储库。如果你想要,你可以像上面提到的那样做,绕过Git的一致性检查,然后运行自己在一个挂载的对象数据库上打包对象,它接受标准输入上的任意 sha,并编写一个包含您要求的对象的包。将输出包放入任何存储库的对象目录中,瞧,该存储库具有这些对象。
除非启用过滤器功能,否则 Git 协议无法满足您的请求。
Git 协议一直被设计为高效地交换一组提交。 Git 在服务器端实现协议的方式是它将客户端的 have
提交标记为无趣,然后将修订从请求的内容向下移动到无趣点,包括所有必要的对象在这些点之间可达。这种方法必然要求您要走的点是提交的。
可以发送对树对象的请求,但服务器端不会执行您期望的操作。你最终会得到那棵树以及从它可以到达的所有东西(所有的斑点和其他树)在包中,这将是比你想要的多得多的数据。同样,如果您考虑 Git 协议的工作原理,这是非常有意义的:用户已请求从该点可到达的所有对象。
您可以指定 have
某些树对象以排除它们,当然这需要您知道它们是什么,而在本例中您不知道。即便如此,您仍然会收到该层级中存在的 blob。
过滤器功能仅调整包含在包中的对象,因此您可以通过排除低于其深度的所有对象来指定只包含一个树对象。这些参数被传递给 git rev-list --objects
以便包生成将排除您不感兴趣的内容。否则,默认情况下会包含您请求范围内的每个可到达对象。