This is an in-progress translation.
To help translate the book, please fork the book at GitHub and push your contributions.

Gitolite

注意: Progit のこのセクションの最新版は、常に gitolite のドキュメント として公開しています。筆者としては、このセクションさえ読めば gitolite をインストールできるよう正確に記述しているつもりです。しかし、完全な状態ではなく、gitolite に付属する大量のドキュメントに取って代わるものというわけでもありません。

Git は法人の環境でもよく使われるようになってきました。それにつれて、アクセス制御に関する要望もいくつか出てきました。Gitolite は、最初はそのような要望ににこたえるために作られたものでしたが、オープンソースの世界でも便利に使えることがわかりました。Fedora Project では、パッケージ管理リポジトリ (なんと 10,000 以上もある!) のアクセス制御に gitolite を使っています。おそらく gitolite の使用例としては最大規模のものでしょう。

Gitolite は、単なるリポジトリ単位の権限付与だけではなくリポジトリ内のブランチやタグ単位で権限を付与することができます。つまり、特定の人 (あるいはグループ) にだけ特定の “refs” (ブランチあるいはタグ) に対するプッシュ権限を与えて他の人には許可しないといったことができるのです。

インストール

Gitolite のインストールは非常に簡単で、豊富な付属ドキュメントを読まなくてもインストールできます。必要なものは、何らかの Unix 系サーバのアカウントです。各種の Linux や Solaris 10 でテストされています。root アクセス権は不要です。git や perl、そして openssh 互換の ssh サーバは既にインストールされているものとします。以下の例では、gitserver というホストにあるアカウント gitolite を使います。

Gitolite は、いわゆる “サーバー” ソフトウェアとしては少し変わっています。アクセスは ssh 経由で行うので、サーバー上のすべての userid が “gitolite host” となり得ます。その結果、ソフトウェアそのものを “インストール” してから、ユーザーを “gitolite host” として設定することになります。

Gitolite には 4 通りのインストール方法があります。Fedora や Debian を使っている人は、RPM あるいは DEB を使ってインストールすることができます。root アクセス権を持っている人は手動でインストールできます。これらの方法でインストールした場合は、システム上のすべてのユーザーを “gitolite host” にできます。

root アクセス権のない人は、自分のユーザーIDでインストールします。最後の方法として、gitolite のインストールは ワークステーション上の bash シェルで実行することもできます (msysgit に付属する bash でもだいじょうぶです)。

ここでは、最後の方法について説明します。その他のインストール方法についてはドキュメントを参照してください。

まず最初に公開鍵を使ってサーバにアクセスできるようにし、パスワードプロンプトなしにサーバにログインできるようにします。Linux では次の手順が使えますが、他の OS では手動で同じことをしなければならないかもしれません。鍵ペアは、すでに ssh-keygen で生成済みであるものとします。

$ ssh-copy-id -i ~/.ssh/id_rsa gitolite@gitserver

これを実行すると gitolite アカウントのパスワードを聞かれ、それから公開鍵によるアクセスを設定します。インストールスクリプトを実行するにはこれが 必須 なので、パスワードプロンプトなしにコマンドが実行できることを確認しておきましょう。

$ ssh gitolite@gitserver pwd
/home/gitolite

次に、プロジェクトのメインサイトから Gitolite をクローンし、”easy install” スクリプトを実行します (三番目の引数は、gitolite-admin リポジトリ上で使われるあなたの名前です)。

$ git clone git://github.com/sitaramc/gitolite
$ cd gitolite/src
$ ./gl-easy-install -q gitolite gitserver sitaram

これで完了です! Gitolite はサーバにインストールされ、gitolite-admin という新しいリポジトリがあなたのワークステーションのホームディレクトリにできあがりました。gitolite の設定を管理するには、このリポジトリに変更を加えてプッシュします。

最後のコマンドは、かなりの量の出力があります。読んでみるとおもしろいでしょう。また、最初にこれを実行したときには新しい鍵ペアが作られます。このとき、パスフレーズを指定しなければなりません。パスフレーズをなしにするときは単に enter キーを押します。なぜまた別の鍵ペアが必要なのか、そしてそれをどのように使うのかについては、Gitolite の付属ドキュメント “ssh troubleshooting” に説明があります。

gitolite-admin および testing という名前のリポジトリが、サーバー上にデフォルトで作成されます。これらのいずれかをローカルにクローンしたい場合は、(gitolite アカウントに authorized_keys での SSH コンソールアクセスができるアカウントから) このようにします。

$ git clone gitolite:gitolite-admin
$ git clone gitolite:testing

同じリポジトリをその他のアカウントからクローンする場合は、このようになります。

$ git clone gitolite@servername:gitolite-admin
$ git clone gitolite@servername:testing

インストールのカスタマイズ

デフォルトのインストールは素早く済ませられ、たいていの人にとってはこれで十分でしょう。しかし、必要に応じてインストール方法をカスタマイズすることもできます。引数 -q を省略すると、冗長モードのインストールとなり、各段階で何がインストールされるのかについて詳しい情報が表示されるようになります。冗長モードでインストールすると、サーバ側のパラメータを変更することもできます。たとえば実際のリポジトリの場所などです。パラメータを変更するには、サーバが使用する “rc” ファイルを編集します。この “rc” ファイルには大量にコメントが書かれているので、必要に応じて簡単に書き換えることができるでしょう。このファイルには、gitolite の高度な機能の有効/無効を切り替えるような設定項目も多く含まれています。

設定ファイルおよびアクセス制御ルール

インストールが終わったら、gitolite-admin リポジトリ (HOME ディレクトリにあります) に移動して中をのぞいてみましょう。

$ cd ~/gitolite-admin/
$ ls
conf/  keydir/
$ find conf keydir -type f
conf/gitolite.conf
keydir/sitaram.pub
$ cat conf/gitolite.conf
#gitolite conf
# please see conf/example.conf for details on syntax and features

repo gitolite-admin
    RW+                 = sitaram

repo testing
    RW+                 = @all

“sitaram” (先ほどの gl-easy-install コマンドで、最後の引数に指定したユーザです) が、gitolite-admin リポジトリおよび同名の公開鍵ファイルへの読み書き権限を持っていることに注目しましょう。

gitolite の設定ファイルの構文は conf/example.conf には詳しく書かれているので、ここでは大事なところに絞って説明します。

ユーザやリポジトリをグループにまとめることもできます。グループ名は単なるマクロのようなものです。グループを定義する際には、それがユーザであるかプロジェクトであるかは無関係です。実際にその「マクロ」を 使う 段階になって初めてそれらを区別することになります。

@oss_repos      = linux perl rakudo git gitolite
@secret_repos   = fenestra pear

@admins         = scott     # Adams, not Chacon, sorry :)
@interns        = ashok     # get the spelling right, Scott!
@engineers      = sitaram dilbert wally alice
@staff          = @admins @engineers @interns

パーミッションは、”ref” レベルで設定することができます。次の例では、インターン (@interns) は “int” ブランチにしかプッシュできないように設定しています。エンジニア (@engineers) は名前が “eng-” で始まるすべてのブランチにプッシュでき、また “rc” のあとに一桁の数字が続く名前のタグにもプッシュできます。また、管理者 (@admins) はすべての ref に対してあらゆることができます。

repo @oss_repos
    RW  int$                = @interns
    RW  eng-                = @engineers
    RW  refs/tags/rc[0-9]   = @engineers
    RW+                     = @admins

RWRW+ の後に書かれている式は正規表現 (regex) で、これにマッチする refname (ref) が対象となります。なので、これに “refex” と名付けました! もちろん、refex はこの例で示したよりずっと強力なものです。perl の正規表現になじめない人は、あまりやりすぎないようにしましょう。

また、すでにお気づきかもしれませんが、refs/ で始まらない refex を指定すると、Gitolite はその先頭に refs/heads/ がついているものとみなします。これは構文上の利便性を意識したものです。

設定ファイルの構文の中でも重要なのは、ひとつのリポジトリに対するルールをすべてひとまとめにしなくてもよいということです。共通の設定をひとまとめにして上の例のように oss_repos に対してルールを設定し、その後で個々の場合について個別のルールを追加していくこともできます。

repo gitolite
    RW+                     = sitaram

このルールは、gitolite リポジトリのルール群に追加されます。

で、実際のアクセス制御ルールはどのように書けばいいの? と思われたことでしょう。簡単に説明します。

gitolite のアクセス制御には二段階のレベルがあります。まず最初はリポジトリレベルのアクセス制御です。あるリポジトリへの読み込み (書き込み) アクセス権を持っているということは、そのリポジトリの すべての ref に対する読み込み (書き込み) 権限を持っていることを意味します。

もうひとつのレベルは “書き込み” アクセス権だけを制御するものですが、リポジトリ内のブランチやタグ単位で設定できます。ユーザ名、試みられるアクセス (W あるいは +)、そして更新される refname が既知となります。アクセスルールのチェックは、設定ファイルに書かれている順に行われ、この組み合わせにマッチ (単なる文字列マッチではなく正規表現によるマッチであることに注意しましょう) するものを探していきます。マッチするものが見つかったら、プッシュが成功します。マッチしなかった場合は、アクセスが拒否されます。

“拒否” ルールによる高度なアクセス制御

これまでに見てきた権限は RRW あるいは RW+ だけでした。しかし、gitolite にはそれ以外の権限もあります。それが - で、”禁止” をあらわすものです。これを使えばより強力なアクセス制御ができるようになりますが、少し設定は複雑になります。マッチしなければアクセスを拒否するというだけでなく、ルールを書く順番もからんでくることになるからです。

上の例で、エンジニアは master と integ 以外 のすべてのブランチを巻き戻せるように設定しようとすると、次のようになります。

    RW  master integ    = @engineers
    -   master integ    = @engineers
    RW+                 = @engineers

この場合も上から順にルールを適用し、最初にマッチしたアクセス権をあてはめます。何もマッチしなければアクセスは拒否されます。master や integ に対する巻き戻し以外のプッシュは、最初のルールにマッチするので許可されます。これらのブランチに対する巻き戻しのプッシュは最初のルールにマッチしません。そこで二番目のルールに移動し、この時点で拒否されます。master と integ 以外への (巻き戻しを含む) 任意のプッシュは最初の二つのルールのいずれにもマッチしないので、三番目のルールが適用されます。

ファイル単位でのプッシュの制限

変更をプッシュすることのできるブランチを制限するだけでなく、変更できるファイルを制限することも可能です。たとえば、Makefile (あるいはその他のプログラム) などは誰もが変更できるというものではないでしょう。このファイルはさまざまなものに依存しており、変更によっては壊れてしまうことがあるかもしれないからです。そんな場合は次のように設定します。

repo foo
    RW                  =   @junior_devs @senior_devs

    RW  NAME/           =   @senior_devs
    -   NAME/Makefile   =   @junior_devs
    RW  NAME/           =   @junior_devs

この強力な機能については conf/example.conf に説明があります。

個人ブランチ

Gitolite には “個人ブランチ” (“個人的なブランチ用の名前空間” と言ったほうがいいでしょうか) という機能があります。これは、法人の環境では非常に便利なものです。

git の世界では、いわゆる「プルリクエスト」によるコードのやりとりが頻繁に発生します。しかし法人の環境では、権限のない人によるアクセスは厳禁です。開発者のワークステーションにはそんな権限はありません。そこで、まず一度中央サーバにプッシュして、そこからプルしてもらうよう誰かにお願いすることになります。

これを中央管理型の VCS でやろうとすると、同じ名前のブランチが乱造されることになってしまいます。また、これらのアクセス権限を設定するのは管理者にとって面倒な作業です。

Gitolite では、各開発者に対して “personal” あるいは “scratch” といった名前空間プレフィックス (たとえば refs/personal/<devname>/*) を定義します。詳細は、doc/3-faq-tips-etc.mkd の “personal branches” を参照ください。

“ワイルドカード” リポジトリ

Gitolite では、ワイルドカード (実際のところは perl の正規表現です) を使ってリポジトリを指定することができます。たとえば assignments/s[0-9][0-9]/a[0-9][0-9] のようにします。これは非常に強力な機能で、使うには rc ファイルに $GL_WILDREPOS = 1; と設定しなければなりません。この機能を使うと、新たな権限モード (”C”) が用意されます。これは、ワイルドカードにマッチするリポジトリの作成を許可するモードです。新たに作成したリポジトリの所有者は自動的にそのユーザに設定され、他のユーザに R あるいは RW の権限を付与できるようになります。この機能の説明は doc/4-wildcard-repositories.mkd にあります。

その他の機能

最後にその他の機能の例を紹介しましょう。これらについての詳しい説明は、ドキュメントの “faqs, tips, etc” にあります。

ログ記録: Gitolite は、成功したアクセスをすべてログに記録します。巻き戻し権限 (RW+) を与えているときに、誰かが “master” を吹っ飛ばしてしまったとしましょう。そんなときにはログファイルが救世主となります。ログを見れば、問題を起こした SHA をすぐに発見できるでしょう。

通常の PATH 以外にインストールした git: gitolite の非常に便利な機能のひとつは、通常の $PATH 以外にインストールされた git もサポートしているという点です (これは思っているほど珍しいことではありません。法人の環境やホスティング環境ではシステム全体への影響を及ぼすインストールが禁じられているところもあり、そんな場合は自分のディレクトリの配下にインストールすることになるからです)。通常なら、標準以外の場所にインストールされた git バイナリを何らかの方法でクライアント側の git に認識させなければなりませんが、gitolite があれば単に冗長モードのインストールで “rc” ファイルに $GIT_PATH を設定するだけです。クライアント側の変更は不要です :-)

アクセス権の報告: もうひとつの便利な機能は、サーバに ssh で接続したときに起こります。gitolite はあなたがアクセスするリポジトリとどのようなアクセスができるかを表示します。たとえばこんな感じです。

    hello sitaram, the gitolite version here is v1.5.4-19-ga3397d4
    the gitolite config gives you the following access:
         R     anu-wsd
         R     entrans
         R  W  git-notes
         R  W  gitolite
         R  W  gitolite-admin
         R     indic_web_input
         R     shreelipi_converter

委譲: 大規模な環境では、特定のリポジトリのグループに対する責任を委譲して個別に管理させることもできます。こうすれば主管理者の負荷が軽減され、主管理者がボトルネックとなることも少なくなります。この機能については、doc/ ディレクトリの中に個別のファイルで説明されています。

Gitweb のサポート: Gitolite は gitweb を何通りかの方法でサポートしています。まず、どのリポジトリを gitweb 上で見せるかを設定することができます。また、gitweb 用の “owner” と “description” を gitolite の設定ファイルに書くことができます。Gitweb には HTTP 認証に基づいたアクセス制御の機能もありますが、gitolite が生成する “コンパイル済み” の設定ファイルを使えば gitweb と gitolite で共通の (読み込み) アクセス制御ルールを適用することができます。

ミラーリング: Gitolite は、複数のミラーを保守したり、プライマリサーバーが落ちたときに簡単にミラーに切り替えたりすることができます。