日本語 ▾ トピック ▾ 最新バージョン ▾ git-http-backend は 2.49.0 で最終更新されました

名前

git-http-backend - HTTP経由でのGitのサーバーサイド実装

概要

git http-backend

説明

Gitリポジトリの内容をhttp:// および https:// プロトコル経由でアクセスするGitクライアントに提供するためのシンプルなCGIプログラムです。このプログラムは、スマートHTTPプロトコルと後方互換性のあるダムHTTPプロトコルの両方を使用したクライアントからのフェッチ、およびスマートHTTPプロトコルを使用したクライアントからのプッシュをサポートします。また、適切に設定されていれば、Gitのより効率的な「v2」プロトコルもサポートします。詳細については、下記のENVIRONMENTセクションにあるGIT_PROTOCOLに関する説明を参照してください。

このプログラムは、ディレクトリにマジックファイル「git-daemon-export-ok」が存在することを確認し、この方法で明示的にエクスポートがマークされていないGitディレクトリのエクスポートを拒否します(GIT_HTTP_EXPORT_ALL環境変数が設定されている場合を除く)。

デフォルトでは、upload-packサービスのみが有効になっています。これは、git fetchgit pullgit cloneから呼び出されるgit fetch-packおよびgit ls-remoteクライアントにサービスを提供します。クライアントが認証されている場合、receive-packサービスが有効になり、git pushから呼び出されるgit send-packクライアントにサービスを提供します。

サービス

これらのサービスは、リポジトリごとの設定ファイルを使用して有効/無効にできます。

http.getanyfile

これは、upload packサービスを使用できないバージョン1.6.6より古いGitクライアントにサービスを提供します。有効にすると、クライアントはリポジトリ内の任意のファイルを読み取ることができ、ブランチから到達できなくなったオブジェクトでもまだ存在するものは読み取れます。デフォルトで有効になっていますが、この設定値をfalseにすることでリポジトリで無効にできます。

http.uploadpack

これはgit fetch-packおよびgit ls-remoteクライアントにサービスを提供します。デフォルトで有効になっていますが、この設定値をfalseにすることでリポジトリで無効にできます。

http.receivepack

これはgit send-packクライアントにサービスを提供し、プッシュを許可します。匿名ユーザーに対してはデフォルトで無効になっていますが、ウェブサーバーによって認証されたユーザーに対してはデフォルトで有効になっています。この項目をfalseに設定することで無効にでき、匿名ユーザーを含む全てのユーザーに対してはtrueに設定することで有効にできます。

http.uploadarchive

これはHTTP/HTTPSプロトコル経由のリモートアーカイブ用のgit archiveクライアントにサービスを提供します。デフォルトでは無効になっています。プロトコルv2でのみ動作します。

URLの変換

ディスク上のリポジトリの場所を決定するために、git http-backendは、ウェブサーバーによって自動的に設定される環境変数PATH_INFOと、ウェブサーバーの設定で手動で設定する必要があるGIT_PROJECT_ROOTを連結します。GIT_PROJECT_ROOTが設定されていない場合、git http-backendは、これもウェブサーバーによって自動的に設定される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

匿名読み取りアクセスを有効にし、認証済み書き込みアクセスを有効にするには、初期のref広告(クエリ文字列のサービスパラメータを介してプッシュとして検出されます)と、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をサービスするには、git http-backendが処理できるURLのみにScriptAliasMatchを使用し、残りを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は、呼び出し元のウェブサーバーによって設定される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がフェッチ中に処理するリファレンス交渉リクエストの最大サイズを変更できます。より大きなバッファを必要とするフェッチは成功しません。通常この値を変更する必要はありませんが、非常に多数のリファレンスを持つリポジトリからフェッチしている場合には役立つことがあります。値は単位付きで指定できます(例: 100メガバイトの場合は100M)。デフォルトは10メガバイトです。

クライアントは、Git-Protocol HTTPヘッダーを使用して、オプションのプロトコル機能(v2プロトコルのような)をプローブすることができます。これらをサポートするためには、そのヘッダーの内容がGIT_PROTOCOL環境変数に表示される必要があります。ほとんどのウェブサーバーは、このヘッダーをHTTP_GIT_PROTOCOL変数を介してCGIに渡します。そして、git-http-backendは自動的にそれをGIT_PROTOCOLにコピーします。ただし、一部のウェブサーバーは、渡すヘッダーについてより選択的である場合があり、その場合は明示的に設定する必要があります(以前のEXAMPLESセクションのApache設定におけるGit-Protocolの記述を参照)。

バックエンドプロセスは、GIT_COMMITTER_NAMEを$REMOTE_USERに、GIT_COMMITTER_EMAILを${REMOTE_USER}@http.${REMOTE_ADDR}に設定し、git-receive-packによって作成されたすべてのreflogに、プッシュを実行したリモートユーザーの識別情報が含まれるようにします。

git-receive-packによって呼び出される各フックには、すべてのCGI環境変数が利用可能です。

Git

git[1]スイートの一部

scroll-to-top