简体中文 ▾ 主题 ▾ 最新版本 ▾ gitnamespaces 最后更新于 2.32.0

名称

gitnamespaces - Git 命名空间

概要

GIT_NAMESPACE=<namespace> git upload-pack
GIT_NAMESPACE=<namespace> git receive-pack

描述

Git 支持将单个仓库的引用划分为多个命名空间,每个命名空间都有自己的分支、标签和 HEAD。Git 可以将每个命名空间作为独立的仓库进行拉取和推送,同时共享对象存储,并将所有引用暴露给 git-gc[1] 等操作。

将多个仓库作为单个仓库的命名空间存储,可以避免存储相同对象的重复副本,例如存储同一源代码的多个分支时。替补机制提供了类似的避免重复的支持,但替补机制无法阻止新添加到仓库中的对象之间的重复(除非持续维护),而命名空间则可以做到。

要指定命名空间,请将 GIT_NAMESPACE 环境变量设置为该命名空间。对于每个引用命名空间,Git 会将相应的引用存储在 refs/namespaces/ 下的目录中。例如,GIT_NAMESPACE=foo 会将引用存储在 refs/namespaces/foo/ 下。你也可以通过 git[1]--namespace 选项来指定命名空间。

请注意,包含 / 的命名空间将扩展为命名空间层次结构;例如,GIT_NAMESPACE=foo/bar 会将引用存储在 refs/namespaces/foo/refs/namespaces/bar/ 下。这使得 GIT_NAMESPACE 中的路径具有层次性,因此使用 GIT_NAMESPACE=foo/bar 进行克隆会产生与使用 GIT_NAMESPACE=foo 进行克隆然后从该仓库使用 GIT_NAMESPACE=bar 进行克隆相同的结果。它还避免了与奇怪的命名空间路径(例如 foo/refs/heads/)产生的歧义,否则这些路径可能会在 refs 目录中生成目录/文件冲突。

git-upload-pack[1]git-receive-pack[1] 会根据 GIT_NAMESPACE 的指定重写引用的名称。git-upload-pack 和 git-receive-pack 将忽略指定命名空间之外的所有引用。

智能 HTTP 服务器 git-http-backend[1] 会将 GIT_NAMESPACE 传递给后端程序;请参阅 git-http-backend[1] 以获取将仓库命名空间暴露为仓库的配置示例。

对于简单的本地测试,你可以使用 git-remote-ext[1]

git clone ext::'git --namespace=foo %s /tmp/prefixed.git'

安全性

fetch 和 push 协议并非旨在阻止一方从另一方仓库窃取不打算共享的数据。如果你有需要保护免受恶意对等方侵害的私有数据,最佳选择是将其存储在另一个仓库中。这适用于客户端和服务器。特别是,服务器上的命名空间对于读取访问控制无效;你只应向你信任能够读取整个仓库的客户端授予命名空间的读取访问权限。

已知的攻击向量如下:

  1. 受害者发送“have”行,广告其拥有的对象 ID,这些对象并非明确旨在共享,但如果对等方也有这些对象,则可用于优化传输。攻击者选择要窃取的对象 ID X,并发送一个指向 X 的引用,但无需发送 X 的内容,因为受害者已经拥有它。现在受害者认为攻击者拥有 X,并稍后将 X 的内容发送回攻击者。(这种攻击对于客户端在服务器上执行最为直接,通过在客户端有权访问的命名空间中创建一个指向 X 的引用,然后获取它。服务器对客户端执行此操作的最可能方式是将 X “合并”到公共分支中,并希望用户在该分支上进行额外工作,然后将其推回服务器而没有注意到合并。)

  2. 如 #1 中所述,攻击者选择要窃取的对象 ID X。受害者发送攻击者已拥有的对象 Y,而攻击者虚假声称拥有 X 而非 Y,因此受害者将 Y 作为相对于 X 的增量发送。此增量向攻击者揭示了 X 中与 Y 相似的区域。

GIT

Git[1] 套件的一部分

scroll-to-top