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

名称

gitnamespaces - Git 命名空间

概要

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

描述

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

将多个仓库存储为单个仓库的命名空间,可以避免存储相同的对象副本,例如在存储同一源的多个分支时。`alternates` 机制提供了类似的避免重复的支持,但 `alternates` 在没有持续维护的情况下,无法防止仓库中新添加的对象之间的重复,而命名空间可以。

要指定命名空间,请将 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 可用于优化传输,前提是对方也拥有它们。攻击者选择一个对象 ID X 来窃取并发送一个指向 X 的 ref,但不需要发送 X 的内容,因为受害者已经拥有它。现在受害者认为攻击者拥有 X,并且之后会将 X 的内容发送回攻击者。(此攻击最容易由客户端对服务器执行,通过在客户端有权访问的命名空间中创建指向 X 的 ref,然后获取它。服务器对客户端执行此操作的最可能方式是“合并”X 到一个公共分支,并希望用户在此分支上进行更多工作并将其推回服务器,而不会注意到合并。)

  2. 与 #1 类似,攻击者选择一个对象 ID X 来窃取。受害者发送一个攻击者已拥有的对象 Y,攻击者谎称拥有 X 而不是 Y,因此受害者将 Y 作为 X 的增量发送。增量向攻击者揭示了 X 中与 Y 相似的区域。

GIT

Git[1] 套件的一部分