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

名称

gitnamespaces - Git 命名空间

概要

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

描述

Git 支持将单个仓库的引用拆分为多个命名空间,每个命名空间都有自己的分支、标签和 HEAD。 Git 可以将每个命名空间公开为一个独立的仓库,以便从中拉取和推送到,同时共享对象存储,并将所有引用公开给诸如 git-gc[1] 等操作。

将多个仓库存储为单个仓库的命名空间,避免了存储相同对象的重复副本,例如在存储同一来源的多个分支时。 alternates 机制为避免重复提供了类似的支持,但是 alternates 不能防止添加到仓库的新对象之间发生重复,而 namespaces 可以。

要指定一个命名空间,请将 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 的 delta 发送。 delta 向攻击者显示与 Y 相似的 X 区域。

GIT

git[1] 套件的一部分

scroll-to-top