簡體中文 ▾ 主題 ▾ 最新版本 ▾ 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