CentOS7でGitoliteをセッティングする

# はじめに

gitサーバのユーザ毎アクセス管理が手軽にできるgitolite。巷にはセッティング例の記事はあるが、gitoliteのほぼ全ての操作は「鍵ペアを作る」とか「コミットする」という、手慣れた人にとっては当たり前の操作の集まりなので、具体的な手順よりも必要な要件を書いた方が話が早いのでは？

というわけで、メモ代わりの記事です。初回インストールの記憶で書いているので、ミスはあるかも。再セットアップすることがあれば、直すこともあるかも？

インストール先のサーバ環境はCentOS7だけど、おそらくyumが使えれば他でも大差ないでしょう。

# インストール

## 前提
まさかgitが入ってないことはないよね？

## 管理用鍵ペアを作る
ssh-keygen等で管理者用の鍵ペアを作成しておく。サーバ側で必要なのは公開鍵。秘密鍵は管理ユーザがリモートアクセスで使用する（サーバでは不要）。

## yum install & コミッタ設定
EPELを有効にした状態で「yum install gitolite3」。この操作で、gitolite操作用のユーザ「gitolite3」が自動的に作成される。このユーザで初期化時に自動的にコミットされる際の用のコミッタ設定もしておく（多分必須）。こんな感じ

```
# yum install gitolite3
# su - gitolite3
$ git config --global user.name ユーザ名
$ git config --global user.email メールアドレス
```

コミットするファイル名で日本語を使うための設定とかを仕込んでいる記事もみたけど、どれだけ重要なのかはよくわからない。

## 初期化

上記の作業でユーザgitolite3になっているので、先に作成した公開鍵を使って、gitolite3初期化をする。

```
$ gitolite setup -pk 管理用公開鍵ファイル
```

これだけでサーバ側の作業は終わり。gitliteに「gitolite-admin」というリポジトリができているので、以降はリモート側から、主にリポジトリへのコミットで管理を行う。

# 管理

## 管理用アカウントからのアクセス

管理用アカウントからのアクセスの要件は「管理用秘密鍵を使って」「ユーザgitolite3で」アクセスすることだ。なので、例えば.ssh/configに以下のようなエントリを追加しておいて

```
Host           gitoliteadmin（好きな名前をどうぞ）
HostName       ホスト名やIPアドレスなど
User           gitolite3
IdentityFile   ~/.ssh/秘密鍵ファイル名
```

「ssh gitoliteadmin」とやってみよう。もちろん、sshコマンドのオプションえ上記の情報をセットしてもOK（OKなんだけど、結局git操作でconfigへのエントリ追加はほぼ必須になる）。ログインメッセージが出て切断されれば成功だ。

```
hello gitadmin, this is gitolite3@*** running gitolite3 3.6.12-1.el7 on git ***

 R W    gitolite-admin
 R W    testing
```

## 管理用リポジトリをクローンする

上記のアクセス情報で管理用リポジトリ「gitolite-admin」をクローンできる。
gitコマンドからは
```
git clone gitoliteadmin:/gitolite-admin
```
などで可能だが、お好きなgitクライアントでどうぞ。

## ユーザ追加
ユーザの追加は、追加したいユーザの鍵ペアの公開鍵をgitolite-adminリポジトリに追加（コミット）するだけでいい。

例えば、「秘密鍵：git-user1.pem、公開鍵：git-user1.pub」があったとすると、git-user1.pubを（クローンした）gitlite-admin/keydirに置いて、git commit & pushしてあげる。秘密鍵はユーザが保持して、アクセスに使用する。

大事なのは、「この公開鍵ファイル名がアクセス制御のユーザ識別子となること」だ。なので、公開鍵を登録する場合にはファイル名に気をつけよう。ファイル名が「git-user1.pub」であれば、ユーザ識別子は「git-user1」となる。

## リポジトリ追加・権限設定

初期状態では、gitlite-admin/conf/gitolite.confが以下のような内容になっているはずだ。

```
repo gitolite-admin
    RW+     =   gitadmin

repo testing
    RW+     =   @all
```

このファイルに「repo 新規リポジトリ名」という行と「RW+ = 」というアクセス権限の行を追加して、ユーザ追加と同様、git commit & pushしてあげる。それだけ。もしかしたらサーバでgit initするより手軽？

```
repo gitolite-admin
    RW+     =   gitadmin

repo testing
    RW+     =   @all

repo new-repository
    RW+     =   @all
```

権限設定は「RW+ =」の後に、アクセス許可したいユーザ識別子あるいはグループを設定する。複数のユーザやグループを設定したい場合はスペース区切りで並べる。グループは同じファイルに「@group1 = git-user1 git-user2」などとして定義する。初期状態で「@all」というグループが設定されている。権限の種類は「R (read only)」「RW (read/write)」「RW+（全部可能）」の3種類。

```
@group1 = git-user1 git-user2

repo gitolite-admin
    RW+     =   gitadmin

repo testing
    RW+     =   @all

repo new-repository
    RW+    = gitadmin
    RW     = @group1
    R      = git-user3 git-user4
```


# ユーザでの利用

ユーザからのアクセスについても、基本は管理者と同じ。要件は「ユーザ用秘密鍵を使って」「ユーザgitolite3で」アクセスすること。.ssh/config例としてはこんな感じ...と思ったけど、管理用と全く変わらん（秘密鍵が違うだけ、だからね）。

```
Host           gitolite（好きな名前をどうぞ）
HostName       ホスト名やIPアドレスなど
User           gitolite3
IdentityFile   ~/.ssh/秘密鍵ファイル名
```

これまた管理者と同じで、ssh gitolite、とやると、使えるリポジトリ一覧が表示される。試しに「testing」をクローンしてみよう。

```
git clone gitolite:/testing
```

「warning: You appear to have cloned an empty repository.」という警告が出るが（誰も何もコミットしてなければ）、気にしない。

# 既存リポジトリの移行

gitoliteを使い始めるケースの大半では、生のgitで運用していたリポジトリを移行したいはずだ。この作業は主にリモート側で行う。これは管理ネタの1つだが、ユーザ追加した後にやった方がいいだろうなので、ここに書く。

まずは、管理アカウントで上述の「リポジトリ追加」を行う。移行の場合でも操作は変わらない。新規リポジトリができたら、リモート側（既存リポジトリがある）で、「gitサーバの追加」をして「git push」するのが基本となる。

前提としては、リモート側でユーザアカウントにて移行したいリポジトリにいるとする。リポジトリ名を「repo1」とすると

```
git remote add gitolite ssh://gitolite/repo1 # gitサーバ追加
git push gitolite master # 基本情報+masterのpush
git push gitolite --all # master以外のブランチpush
git push gitolite --tags # タグ
```

となる。これで既存リポジトリの内容がgitolite内リポジトリとして登録される。移行リポジトリが多い場合にはシェルスクリプトを作るなり、何でもどうぞ。

なお、この操作で、手元の.git/configには「origin」に加えて「gitolite」が追加されているはず。このままでもいいかもしれないが、もし「元のリポジトリへのアクセスは不要」「gitoliteではなくoriginとしたい」ような場合には、gitoliteからクローンし直すか、.ssh/configを編集してすればいいかと（自分は後者をやった）

# 最後に

わかってしまえば、セッティングは1分もかからないレベル（リポジトリの移行を除く）。

説明では主にgitコマンド使ってるけど、各種commit&pushとかはsourcetreeとか使っても快適にできるよ。