• このエントリーをはてなブックマークに追加

はじめに

Gitのリモートリポジトリに置くフックスクリプト,ローカルで作業しているプロジェクトのファイルとかとあわせて手元で管理しておきたいですよね.

そんなことがしたかったので,リモートに置くためのGitフックスクリプトを,手元からリモートに同期するためのシェルスクリプトを rsync-git-hooks という名前でこさえてみました.

前提としている環境

例えば,プロジェクトのGitリポジトリは,こんな感じだとします:

% git remote -v
deploy  issm@deploy.example.com:path/to/repos.git (fetch)
deploy  issm@deploy.example.com:path/to/repos.git (push)
dev     issm@dev.example.com:path/to/repos.git (fetch)
dev     issm@dev.example.com:path/to/repos.git (push)
origin  issm@origin.example.com:path/to/repos.git (fetch)
origin  issm@origin.example.com:path/to/repos.git (push)
stage   issm@stage.example.com:path/to/repos.git (fetch)
stage   issm@stage.example.com:path/to/repos.git (push)

で,Gitフックスクリプトを,次のような構成で管理しているとします:

% cd /path/to/project
% tree etc
etc
└── git-hooks
    ├── deploy
    │   └── post-receive
    ├── dev
    │   └── post-receive
    ├── origin
    │   └── post-receive
    └── stage
        └── post-receive
 
5 directories, 4 files

実行例

% ./bin/rsync-git-hooks
Usage:
    ./bin/rsync-git-hooks <remote_name>

リモート名を引数に実行します:

% ./bin/rsync-git-hooks stage
rsync -rtvp -e ssh /path/to/project/etc/git-hooks/stage/post-receive issm@stage.example.com:path/to/repos.git/hooks/
sending incremental file list
post-receive
 
sent 102 bytes  received 37 bytes  278.00 bytes/sec
total size is 24  speedup is 0.17

これで先方に,手元のGitフックスクリプトが置かれます.

シェルスクリプトの中身

こんな感じです:

#!/bin/sh
ROOT=$(cd $(dirname $0)/..  &&  pwd)
 
REMOTE_NAME=$1
if [ "$REMOTE_NAME" = "" ]; then
    echo "Usage:"
    echo "    $0 <remote_name>"
    exit 1
fi
 
REMOTE_NAME_GREP="$REMOTE_NAME	"  # うしろの空白はタブ
REMOTE_REPOS=$( git remote -v | \grep push | \grep -E "$REMOTE_NAME_GREP" | awk '{print($2)}' )
echo $REMOTE_REPOS
if [ "$REMOTE_REPOS" = "" ]; then
    echo "No such remote: $REMOTE_NAME"
    exit 1
fi
 
RSYNC_SRC=$ROOT/etc/git-hooks/$REMOTE_NAME/\*
RSYNC_DST=$REMOTE_REPOS/hooks/
CMD_RSYNC="rsync -rtvp -e ssh $RSYNC_SRC $RSYNC_DST"
 
echo $CMD_RSYNC
$CMD_RSYNC
 
exit 0

指定したリモート名からリモートリポジトリのありかを知るために,git remote -v の結果をごにょごにょしてます.awk便利ですね,print() しか使ったことありませんがw

おわりに

以上,リモートに置くGitフックスクリプトを手元で管理しつつ,簡単に同期を行うためのシェルスクリプトを書いてみたお話でした.

git push する前にこのスクリプトが呼ばれるようにすれば,忘れることなくフックスクリプトが常に最新に保たてる感じですね!