2013-03-28

Redmine で別サーバーにある git リポジトリーを参照する

Redmine はローカル・マシンにあるリポジトリーしか参照できない。なので、Redmine 用のサーバーとリポジトリー用のサーバーを分けて運用している場合、チケットとコミット・ログを紐付けることができない。

これは不便なので、公開リポジトリーに commit したら Redmine サーバーにデータを転送するようにした。

なお、掲題の通り今回は git リポジトリーを扱う。

設定

Redmine を動かしているサーバーを server_redmine と呼ぶ。

Git の公開リポジトリーを置いているサーバーを server_git と呼ぶ。リポジトリーは /var/git/sample.git にあるとする。

ssh ログインの準備

server_git から server_redmine へ ssh ログインできる様に設定をしておく。

server_git で上 ssh 鍵を作り、server_redmine へ公開鍵をコピーする。

server_git ~$ ssk-keygen -t rsa
server_git ~$ ls .ssh/
id_rsa id_rsa.pub
server_git ~$ scp .ssh/id_rsa.pub server_redmine:~/
server_git ~$ ssh server_redmine
server_redmine ~$ mkdir .ssh
server_redmine ~$ chmod 700 .ssh
server_redmine ~$ touch .ssh/authorized_keys
server_redmine ~$ chmod 600 .ssh/authorized_keys
server_redmine ~$ cat id_rsa.pub >> .ssh/authorized_keys
server_redmine ~$ rm id_rsa.pub
server_redmine ~$ exit

以上で設定は終了。ssh ログインできれば成功。

server_git ~$ ssh server_redmine
server_redmine ~$ hostname
server_redmine

git repository のコピー

まずは、server_redmine に server_git の git リポジトリーを clone する。

server_redmine ~$ cd /var/git/
server_redmine /var/git$ git clone --mirror ssh:server_git:/var/git/example.git

--bare--mirror の違いがいま一つ分かっていないけれども、--mirror の方が今回の用途に合っていそう。

なお、この作業には server_redmine から server_git へ ssh ログインできることが前提になっている。もし出来ない場合は、上の server_git から server_redmine へ ssh ログインする設定をもう一度、逆方向にして欲しい。

ここまでで、server_git にある最新の git リポジトリーを server_redmine に持って来れた。けれど、今のままでは server_git のリポジトリーにコミットされた内容が server_redmine 側に反映されない。

hooks/update の利用

たいていのバージョン・コントロールには hook という機能がある。コミット直前に何かするとか、コミット直後に何かするとか、そういう機能。

git にも hook 機能があるので、それを使う。今回使うのは post-update フック。

post-update は、全てのコミットが公開リポジトリーに push された後に実行されるフック。server_git 内の /var/git/example.git/hooks/post-update を編集する。中身は次の通り:

#!/bin/sh
#
# An example hook script to prepare a packed repository for use over
# dumb transports.
#
# To enable this hook, rename this file to "post-update".

# exec git update-server-info
ssh -t -t server_redmine <<EOF
 cd /var/git/example.git
 git fetch --all
 exit
EOF

server_redmine に ssh ログインして、git fetch している。git の公開リポジトリーから redmine 側のリポジトリーに push できれば話は簡単なのだけど、「公開リポジトリー (--bare 付きで作ったリポジトリー)」からは git push できない制約がある。仕方がないので、server_redmine 側に移って git fetch している。

ファイルを作ったら、実行権限を付けるのを忘れずに。

server_git ~$ chmod +x /var/git/example.git/hooks/post-update

あとがき

他サーバーにある git repository を同期する手段には、cron を使って定期的に git fetch (or git pull) する方法もある。この方法の欠点は、git push 後、Redmine にデータが同期するまでにタイムラグが出来ること。また、git repository が更新されていなくても、git fetch が実行されてしまうこと。

hook を使えば、誰かが git push したら、自動的に Redmine 側の git repository に反映される。タイムラグもないし無駄な git fetch も発生しない。ぼくは、こちらの方法を好む。

No comments:

Post a Comment