gitでremoteリポジトリにpushされたときに、自動的にメールを出すrubyスクリプトを書いてみた

subversionを使っていた頃はコミットされた時に
自動的にメールを出すようにして、社内では重宝していたのですが、
gitでもremoteリポジトリにpushされたときには
メールで知らせて欲しいと思い、rubyで作成してみました。
また、社内にはgitwebもあるので、こちらのリンクもつけるようにしました。
まず欲しいメールは、

こんな感じ。サブジェクトにlogのテキストが欲しいので、
コミットごとにメールが来るようにして、
変更ファイルの一覧、gitwebへのリンクを作成。
サブジェクトは

[git][jikken]XXXX

といった感じで、ディレクトリ名をつけて、ログメッセージを付けるようにしています。
メールの下にあるURLをクリックすると、以下のようなページが出るようにしました。

ソースは以下のようになります。
引数からrefnameやリビジョンを取ってきて、
コミットごとにまわしてメールを出してます。

#!/usr/bin/ruby -Ku
require 'net/smtp'
require 'kconv'
require 'base64'

@refname=ARGV[0]
@oldrev=ARGV[1]
@newrev=ARGV[2]

@toaddr=['xibbar@xxx.com','fujioka@hogehogefugafuga']

if ENV['GIT_DIR']
  @dirname=File.basename(File.expand_path(ENV['GIT_DIR']))
else
  @dirname=File.basename(Dir.pwd)
end

if @newrev=="0000000000000000000000000000000000000000"
  @newrev_type="delete"
else
  @newrev_type=`git cat-file -t #{@newrev}`.chomp
end

`git log --oneline #{@oldrev..@newrev}`.split(/\r\n|\r|\n/).reverse.each do |line|
  refname,comment=line.chomp.split(/ /)
  body=`git log -1 --stat #{refname}`
  mail_subject=''
  comment.scan(/.{1,15}/u) do |str|
    str_jis=NKF.nkf("-W8j",str)
    mail_subject+=" =?iso-2022-jp?B?"+
    Base64.encode64(str_jis).chomp+"?="+"\n"
    mail_subject.strip!
  end

  Net::SMTP.start( 'localhost', 25 ) do |smtp|
    smtp.send_mail <<EndOfMail, 'root@gw.rabbix.jp', *@toaddr
From: Git Admin <root@gw.rabbix.jp>
To: Git committers:;
Subject: [git][#{@dirname}]#{mail_subject} 
MIME-Version: 1.0
Content-Type: text/plain; charset = iso-2022-jp

#{body.tojis}
commit: https://xxxxxx/cgi-bin/gitweb.cgi?p=#{@dirname};a=commit;h=#{refname}
diff: https://xxxxxx/cgi-bin/gitweb.cgi?p=#{@dirname};a=commitdiff;h=#{refname}
EndOfMail
  end
end
  • tmailとか使っていないのは、標準ライブラリだけでがんばりたかったからです。
  • 送信先とかURLとかいじって使うと便利かと思って公開しました。
  • @newrev_typeは使っていませんが、とりあえず取得できたので残しています。
  • なんで作ったかというと、rubyで書きたかったからです。
  • /usr/share/git-core/templates/hooksとかにupdateを入れておくと、initするとコピーされてそのリポジトリに入ってしまうのですが、オレオレリポジトリを作ってしまってpushすると、メンバー全員にメールが行くので大変危険です。
  • /git/りぽじとり という構造などの時は、/git/update を置いて、シンボリックリンクを張って運用すると便利です。