簡體中文 ▾ 主題 ▾ 最新版本 ▾ git-http-backend 上次更新於 2.49.0

名稱

git-http-backend - Git over HTTP 的伺服器端實現

概要

git http-backend

描述

一個簡單的 CGI 程式,用於向透過 http:// 和 https:// 協議訪問倉庫的 Git 客戶端提供 Git 倉庫內容。該程式支援客戶端使用智慧 HTTP 協議和向後相容的啞 HTTP 協議進行拉取,以及客戶端使用智慧 HTTP 協議進行推送。如果配置正確,它還支援 Git 更高效的“v2”協議;請參閱下面 ENVIRONMENT 部分中 GIT_PROTOCOL 的討論。

它會驗證目錄中是否存在“git-daemon-export-ok”這個魔法檔案,並且它會拒絕匯出任何未明確標記為可匯出的 Git 目錄(除非設定了 GIT_HTTP_EXPORT_ALL 環境變數)。

預設情況下,只啟用 upload-pack 服務,該服務用於服務 git fetch-packgit ls-remote 客戶端,這些客戶端由 git fetchgit pullgit clone 呼叫。如果客戶端已認證,則啟用 receive-pack 服務,該服務用於服務 git send-pack 客戶端,這些客戶端由 git push 呼叫。

服務

這些服務可以透過每個倉庫的配置檔案啟用/停用

http.getanyfile

該服務用於 Git 版本 1.6.6 之前且無法使用 upload pack 服務的客戶端。啟用後,客戶端可以讀取倉庫中的任何檔案,包括那些不再可從分支訪問但仍存在於倉庫中的物件。它預設啟用,但倉庫可以透過將此配置值設定為 false 來停用它。

http.uploadpack

該服務用於 git fetch-packgit ls-remote 客戶端。它預設啟用,但倉庫可以透過將此配置值設定為 false 來停用它。

http.receivepack

該服務用於 git send-pack 客戶端,允許推送。對於匿名使用者,它預設停用;對於經 Web 伺服器認證的使用者,它預設啟用。可以透過將其設定為 false 來停用它,或者透過將其設定為 true 為所有使用者(包括匿名使用者)啟用它。

http.uploadarchive

該服務用於透過 HTTP/HTTPS 協議進行遠端歸檔的 git archive 客戶端。它預設停用。它僅在協議 v2 中有效。

URL 轉換

為了確定磁碟上倉庫的位置,git http-backend 會將 Web 伺服器自動設定的環境變數 PATH_INFO 和必須在 Web 伺服器配置中手動設定的 GIT_PROJECT_ROOT 連線起來。如果 GIT_PROJECT_ROOT 未設定,git http-backend 會讀取 PATH_TRANSLATED,該變數也由 Web 伺服器自動設定。

示例

以下所有示例都將 http://$hostname/git/foo/bar.git 對映到 /var/www/git/foo/bar.git

Apache 2.x

確保啟用了 mod_cgi、mod_alias 和 mod_env,並正確設定 GIT_PROJECT_ROOT(或 DocumentRoot),然後為 CGI 建立一個 ScriptAlias

SetEnv GIT_PROJECT_ROOT /var/www/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/

# This is not strictly necessary using Apache and a modern version of
# git-http-backend, as the webserver will pass along the header in the
# environment as HTTP_GIT_PROTOCOL, and http-backend will copy that into
# GIT_PROTOCOL. But you may need this line (or something similar if you
# are using a different webserver), or if you want to support older Git
# versions that did not do that copying.
#
# Having the webserver set up GIT_PROTOCOL is perfectly fine even with
# modern versions (and will take precedence over HTTP_GIT_PROTOCOL,
# which means it can be used to override the client's request).
SetEnvIf Git-Protocol ".*" GIT_PROTOCOL=$0

要啟用匿名讀訪問但需認證寫訪問,請對初始引用通告(我們透過查詢字串中的服務引數將其檢測為推送)和 receive-pack 呼叫本身都要求授權

RewriteCond %{QUERY_STRING} service=git-receive-pack [OR]
RewriteCond %{REQUEST_URI} /git-receive-pack$
RewriteRule ^/git/ - [E=AUTHREQUIRED:yes]

<LocationMatch "^/git/">
	Order Deny,Allow
	Deny from env=AUTHREQUIRED

	AuthType Basic
	AuthName "Git Access"
	Require group committers
	Satisfy Any
	...
</LocationMatch>

如果您沒有 mod_rewrite 可用於匹配查詢字串,則只需保護 git-receive-pack 本身即可,例如

<LocationMatch "^/git/.*/git-receive-pack$">
	AuthType Basic
	AuthName "Git Access"
	Require group committers
	...
</LocationMatch>

在這種模式下,伺服器直到客戶端實際開始推送的物件協商階段才會請求認證,而不是在初始接觸時。因此,您還必須在任何應接受推送的倉庫中啟用 http.receivepack 配置選項。預設行為是,如果未設定 http.receivepack,則拒絕未經認證使用者的任何推送;因此,初始請求將向客戶端報告 403 Forbidden,甚至不提供認證的機會。

要對讀寫都要求認證,請在倉庫或其父目錄之一週圍使用 Location 指令

<Location /git/private>
	AuthType Basic
	AuthName "Private Git Access"
	Require group committers
	...
</Location>

要在同一 URL 上服務 gitweb,請使用 ScriptAliasMatch 僅匹配 git http-backend 可以處理的 URL,並將其餘 URL 轉發到 gitweb

ScriptAliasMatch \
	"(?x)^/git/(.*/(HEAD | \
			info/refs | \
			objects/(info/[^/]+ | \
				 [0-9a-f]{2}/[0-9a-f]{38} | \
				 pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
			git-(upload|receive)-pack))$" \
	/usr/libexec/git-core/git-http-backend/$1

ScriptAlias /git/ /var/www/cgi-bin/gitweb.cgi/

要在單個倉庫中從不同的 gitnamespaces[7] 服務多個倉庫

SetEnvIf Request_URI "^/git/([^/]*)" GIT_NAMESPACE=$1
ScriptAliasMatch ^/git/[^/]*(.*) /usr/libexec/git-core/git-http-backend/storage.git$1
加速靜態 Apache 2.x

與上述類似,但 Apache 可用於返回儲存在磁碟上的靜態檔案。在許多系統上,這可能更高效,因為 Apache 可以請求核心將檔案內容直接從檔案系統複製到網路

SetEnv GIT_PROJECT_ROOT /var/www/git

AliasMatch ^/git/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$          /var/www/git/$1
AliasMatch ^/git/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$ /var/www/git/$1
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/

這可以與 gitweb 配置結合使用

SetEnv GIT_PROJECT_ROOT /var/www/git

AliasMatch ^/git/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$          /var/www/git/$1
AliasMatch ^/git/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$ /var/www/git/$1
ScriptAliasMatch \
	"(?x)^/git/(.*/(HEAD | \
			info/refs | \
			objects/info/[^/]+ | \
			git-(upload|receive)-pack))$" \
	/usr/libexec/git-core/git-http-backend/$1
ScriptAlias /git/ /var/www/cgi-bin/gitweb.cgi/
Lighttpd

確保載入了 mod_cgimod_aliasmod_authmod_setenv,然後正確設定 GIT_PROJECT_ROOT 並將所有請求重定向到 CGI

alias.url += ( "/git" => "/usr/lib/git-core/git-http-backend" )
$HTTP["url"] =~ "^/git" {
	cgi.assign = ("" => "")
	setenv.add-environment = (
		"GIT_PROJECT_ROOT" => "/var/www/git",
		"GIT_HTTP_EXPORT_ALL" => ""
	)
}

啟用匿名讀訪問但需認證寫訪問

$HTTP["querystring"] =~ "service=git-receive-pack" {
	include "git-auth.conf"
}
$HTTP["url"] =~ "^/git/.*/git-receive-pack$" {
	include "git-auth.conf"
}

其中 git-auth.conf 看起來像這樣

auth.require = (
	"/" => (
		"method" => "basic",
		"realm" => "Git Access",
		"require" => "valid-user"
	       )
)
# ...and set up auth.backend here

對讀寫都要求認證

$HTTP["url"] =~ "^/git/private" {
	include "git-auth.conf"
}

環境變數

git http-backend 依賴於呼叫 Web 伺服器設定的 CGI 環境變數,包括

  • PATH_INFO(如果設定了 GIT_PROJECT_ROOT,否則為 PATH_TRANSLATED)

  • REMOTE_USER

  • REMOTE_ADDR

  • CONTENT_TYPE

  • QUERY_STRING

  • REQUEST_METHOD

GIT_HTTP_EXPORT_ALL 環境變數可以傳遞給 git-http-backend,以繞過在允許匯出倉庫之前對每個倉庫中的“git-daemon-export-ok”檔案進行的檢查。

GIT_HTTP_MAX_REQUEST_BUFFER 環境變數(或 http.maxRequestBuffer 配置選項)可以設定,以更改 git 在拉取期間處理的最大引用協商請求;任何需要更大緩衝區的拉取都將失敗。此值通常不需要更改,但如果您從具有大量引用的倉庫拉取,則可能會有所幫助。該值可以用單位指定(例如,100M 表示 100 兆位元組)。預設值為 10 兆位元組。

客戶端可以使用 Git-Protocol HTTP 頭探測可選的協議能力(如 v2 協議)。為了支援這些能力,該頭的內容必須出現在 GIT_PROTOCOL 環境變數中。大多數 Web 伺服器將透過 HTTP_GIT_PROTOCOL 變數將此頭傳遞給 CGI,git-http-backend 將自動將其複製到 GIT_PROTOCOL。但是,某些 Web 伺服器可能對它們將傳遞的頭更具選擇性,在這種情況下,它們需要明確配置(請參閱前面 EXAMPLES 部分中 Apache 配置中對 Git-Protocol 的提及)。

後端程序將 GIT_COMMITTER_NAME 設定為 $REMOTE_USER,將 GIT_COMMITTER_EMAIL 設定為 ${REMOTE_USER}@http.${REMOTE_ADDR},確保由 git-receive-pack 建立的任何引用日誌都包含執行推送的遠端使用者的一些識別資訊。

所有 CGI 環境變數都可用於 git-receive-pack 呼叫的每個鉤子。

GIT

Git[1] 套件的一部分

scroll-to-top