gitのbareリポジトリのバックアップをとる
チームでgitを使うときは個人の公開リポジトリから適宜pullする、なんてことはせずにsvnのように中央集権的なbareリポジトリを作ることになると思います。
で、そのリポジトリが吹っ飛んだときとかは、分散型の特性を生かして個人のリポジトリをドラゴンボールみたいに寄せ集めて願い事を唱えながらmergeをしてbareリポジトリを蘇らせるというナメック式バックアップを取ることもできますが、やはりここは宇宙人のなかでもダントツでかしこいとされる地球人らしさを見せておきたいわけであります。
というわけでbareリポジトリのバックアップをとりたいのです。
ベタにrsyncとかscpでリポジトリまるごと日次バックアップというのもいいのですが、その場合バックアップ時刻からリポジトリが吹っ飛んだ瞬間の間にpushされていた変更は失われてしまうわけです。失われた分をわざわざpushするのは地球人らしくありません。
なのでここはgitの機能を使ってpushされたと同時にバックアップをとれるようにします。
bareリポジトリを作って更新する
早速作ってみます。バックアップ対象のbareリポジトリをyamuchaとします。
で、このyamuchaというゴミリポジトリのバックアップとしてchaozというbareリポジトリを作ります
chaozを普通のbareリポジトリとして作るのであれば次のようなコマンドを使いますが
$ git clone --bare yamucha chaoz
バックアップ用のリポジトリを作るのであれば--bareではなく--mirrorというオプションをつけます。
$ git clone --mirror yamucha chaoz
mirrorがあると元になったリポジトリの丸々コピーはもちろん、トラッキングもできるみたいです。*1
で、あとはyamuchaの更新をchaozに反映しなければなりません。反映はfetchで取得できます。
$ cd chaoz $ git fetch --all
git-pullをすると、chaozはbareリポジトリだから管理ファイルしか存在しないためにmergeができないよと怒られます。なのでここではgit-fetchをしないといけません。
これでpush単位でのバックアップがとれるようになりました。
hooksでフックさせる
このままではyamuchaにpushしたらいちいちchaozに入ってfetchしなくちゃいけなくて面倒です。両者、その名に違わずどうしようもないクソリポジトリです。爆殺したくなりますね。
なので、ここではhooksを使います。
bareリポジトリか通常のリポジトリの.gitディレクトリの中にhooksというディレクトリがあります。この中にpost-receiveのように決まった名前*2のシェルスクリプトをいれておくと、それぞれのタイミングでスクリプトを実行してくれます。
今回はyamuchaがpushされたタイミングでフックさせたいので、yamucha/hooks/post-updateに処理を書きます。
$ cd yamucha/hooks
$ cp post-update.sample post-update
$ vim post-update
post-updateにはchaozでfetchをするよう処理を書きます。
cd chaoz && git --git-dir=.git fetch --all
--git-dir=.gitがないと、ここはgit管理下のディレクトリじゃねえよと怒られます。あと、このスクリプト自体には引数としてpushされたbranchの名前が渡されるので、branchごとに処理を変えることも可能です。
これでpush時にリアルタイムでバックアップをとれるようになりました。サイバイマンも大喜びです。
参考:
http://d.hatena.ne.jp/tyru/20110723/git_clone_mirror
http://blog.hatak.net/2011/05/22/1062