git hooksで日本語を使いたいWindows+Windows共有フォルダでGit運用している人

Windowsの共有フォルダにgitリポジトリをおいて、
WindowsのTortoiseGitから使って運用している人のための無駄な知識です。

hooksで日本語を使いたければ文字列をファイルにしてからhooksのシェル以外から使う!

(他に良い方法があると思うので、知ってる人がいましたらぜひ教えて下さい・・・)

今回やりたいこと

gitのコミットログをChatworkにのせる

以前からコミットログをメールで通知したりしているのですが、今回はChatwork側にpushの通知をしてみようと思いました。
しかし、メールの時もそうだったのですが、そのままhooksのスクリプトに処理を書くと日本語が文字化けしてしまいます。

文字化けの原因

hooksのスクリプトは(たぶん)msysのシェルがで動いている感じですが、このシェルにより日本語が化けてしまっているようです。
(msysの設定をきちんとできれば日本語も大丈夫なのだと思いますが、うまくやることができませんでした。。。)

例えば、こんな感じでLOGに入れてしまうともうだめです。

[code lang=bash]
LOG=git log -1 --pretty=format:"%s"
[/code]

対策

シェルを経由すると文字が化けてしまうので、経由しないで使えば文字化けしません。

例えば、

[code lang=bash]
git log -1 –pretty=format:"%s" > .data
[/code]

こんな感じでコミットログをファイルに書き込みます。

で、pythonなんかのスクリプトから文字列を読み込んで使います。

[code lang=python]
with open(".data", "r") as f:
commit_log = f.readline()
[/code]

スクリプト

というわけで、今回日本語でチャットワークにメッセージを送れたのはこんな感じのスクリプトになります。

d:/i/Python27/python.exe にPython2.7のpythonがインストールされている前提です。
ちなみにWindows+Windows共有フォルダで運用する場合、hooksのスクリプトはローカル側で動作しますので、それぞれpushするローカル側にpythonが無いと動かないのです。これも微妙なところ・・・。

GITリポジトリ/hooks/post-update

[code lang=bash]
#!/bin/bash

set -eu

API_TOKEN="チャットワークのAPI TOKEN"
ROOM_ID="チャットワークのROOM IDEALLY"

REPOS=$(basename $(pwd))
REPOS=${REPOS%.*}

BRANCH=$(git rev-parse –symbolic –abbrev-ref $1)

echo $API_TOKEN > .temp_data
echo $ROOM_ID >> .temp_data
echo $REPOS >> .temp_data
echo $BRANCH >> .temp_data
git log -1 –pretty=format:"%h – %an : %s" $BRANCH >> .temp_data

/D/i/Python27/python.exe chatwork.py

exit 0
[/code]

GITリポジトリ/hooks/chatwork.py

python2系です。

[code lang=python]
# -*- encoding: utf-8 -*-

try:
import urllib
import urllib2

API_TOKEN = ""
ROOM_ID = ""
repos = ""
branch = ""
body = ""
with open(".temp_data", "r") as f:
API_TOKEN = f.readline().strip()
ROOM_ID = f.readline().strip()
repos = f.readline().strip()
branch = f.readline().strip()
body = f.readline().strip()

body = "({0}) [{1}] {2}".format(repos, branch, body)

opener = urllib2.build_opener(urllib2.HTTPSHandler(debuglevel=1))
urllib2.install_opener(opener)

url = 'https://api.chatwork.com/v1/rooms/' + ROOM_ID + '/messages'
values = { 'body' : body }
headers = { 'X-ChatWorkToken' : API_TOKEN }

data = urllib.urlencode(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)

except Exception as e:
with open("error.txt", "w") as f:
f.write(e.message)

[/code]