简体中文 ▾ 主题 ▾ 最新版本 ▾ git-http-backend 最后更新于 2.49.0

名称

git-http-backend - Git over HTTP 的服务端实现

概要

git http-backend

描述

一个简单的 CGI 程序,用于向通过 http:// 和 https:// 协议访问 Git 仓库的客户端提供仓库内容。该程序支持客户端使用智能 HTTP 协议进行获取(fetch),也支持向后兼容的哑 HTTP(dumb HTTP)协议,同时还支持客户端使用智能 HTTP 协议进行推送(push)。如果配置得当,它还支持 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

该服务为 1.6.6 版本之前的 Git 客户端提供支持,这些客户端无法使用 upload pack 服务。启用后,客户端可以读取仓库内的任何文件,包括那些已无法从分支访问但仍存在于仓库中的对象。该选项默认启用,但仓库可以通过将此配置值设置为 false 来禁用它。

http.uploadpack

该服务为 git fetch-packgit ls-remote 客户端提供支持。默认启用,但仓库可以通过将此配置值设置为 false 来禁用它。

http.receivepack

该服务为 git send-pack 客户端提供支持,允许进行推送。默认情况下,匿名用户无法使用该服务,而由 Web 服务器验证的用户默认启用。可以通过将此项设置为 false 来禁用,或者通过设置为 true 为所有用户(包括匿名用户)启用。

http.uploadarchive

该服务为 git archive 客户端提供远程归档服务(通过 HTTP/HTTPS 协议)。默认禁用。它仅在协议 v2 中工作。

URL 转换

为了确定磁盘上仓库的位置,git http-backend 会拼接由 Web 服务器自动设置的环境变量 PATH_INFO 以及必须在 Web 服务器配置中手动设置的 GIT_PROJECT_ROOT。如果未设置 GIT_PROJECT_ROOT,git http-backend 会读取由 Web 服务器自动设置的 PATH_TRANSLATED。

示例

以下所有示例均将 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

要启用匿名读取访问但限制推送需经过身份验证,请对初始引用广播(initial ref advertisement,我们将其检测为查询字符串中带有 service 参数的推送)以及 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,并将其余请求转发给 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 在 fetch 期间处理的最大引用协商请求;任何需要更大缓冲区的 fetch 都将失败。此值通常无需更改,但如果你是从拥有海量引用的仓库中获取数据,它可能会有帮助。该值可以使用单位指定(例如 100M 表示 100 兆字节)。默认值为 10 兆字节。

客户端可以使用 Git-Protocol HTTP 标头探测可选的协议功能(如 v2 协议)。为了支持这些功能,该标头的内容必须出现在 GIT_PROTOCOL 环境变量中。大多数 Web 服务器会通过 HTTP_GIT_PROTOCOL 变量将此标头传递给 CGI,而 git-http-backend 会自动将其复制到 GIT_PROTOCOL。然而,某些 Web 服务器可能对传递哪些标头比较挑剔,在这种情况下,它们需要被显式配置(请参阅前面示例部分中关于 Apache 配置里 Git-Protocol 的说明)。

后端进程将 GIT_COMMITTER_NAME 设置为 $REMOTE_USER,并将 GIT_COMMITTER_EMAIL 设置为 ${REMOTE_USER}@http.${REMOTE_ADDR},以确保 git-receive-pack 创建的任何引用日志(reflogs)都包含执行推送的远程用户的身份识别信息。

所有 CGI 环境变量均可被 git-receive-pack 调用的每个钩子(hooks)使用。

GIT

Git[1] 套件的一部分