コミットメッセージにチケット番号がない場合に警告を出すGithook

オンラインコンサルタントの直井です(^^♪

前に記事を投稿してから早一日が経過しました。
よく、「ローマは一日にして成らず」と言われますが、GitHooksは違います。
「GitHooksは一日にして作成すべき」これは、ローマ帝国から受け継がれてきた名言です。
なぜ、一日でやらなくてはいけないのか?
それは、業務効率化のツールは、すぐに共有すべきであるからです。効率的なツールの作成は有用な時間を作ることができるのです。

そんな冗談はさておき、今回の記事は以下の3本建てでお送りします。
・「GitHooksを利用してコミットメッセージに、ブランチ名からチケット番号を自動的に追加する」
・「チェックアウトしたときに、ブランチ名をチェックする」
・「GitHooksを共有する方法」


そもそも、何を解決したいのか?

そもそも、今回の問題はなんでしょうか?

現状:チケットとGitを連携するには、コミットメッセージにチケット番号が必要だが、コミットメッセージにチケット番号を入れるのを結構忘れがち → チケットとの関連付けや終了が自動的にされない。

解決したいこと:コミットメッセージにチケット番号を入れたい

ざっとまとめるとこんな感じです。なので、今回の問題はいたってシンプルに「
コミットメッセージにチケット番号を入れたい 」という願いをかなえるだけです。


どうやって実現させるか

状況が整理され、問題が明確になったところで、今度は最も重要な部分….
どうやってこの問題を解決するかです。

毎朝出社時に「 コミットメッセージにチケット番号を! 」と力技オペレーション解決もアリです。しかし、これはスマートでない解決方法です。

今回天才的な発想で思いついた解決方法は以下の通りです。
①:ブランチ名の最初にチケット番号を入れる
②:ブランチ名から自動的にコミットメッセージにチケット番号を入力する
③:①、②のアクションをする際に、チケット番号らしき数字が見つからなかったら警告を出す。

修正や新規機能を開発するときにすること、それはブランチを切る!ということは?その行為自体はチケット番号と結びつきがあるのです。また、ブランチに番号が付くことで、たくさんあるリモートブランチから目的のブランチを探しやすくなります。


1. ブランチ作成時チケット番号が書いていなさそうな時にエラーを表示するGitHookを作成

GitHookでは、様々なGitアクションに対してフックを設定することができます。
ブランチを作成したというアクションに対するフックはないので、厳密ではないですが、チェックアウトしたときに発動する「post-checkout」を利用します。

#!/bin/sh

# PHPStorm勢からのアツい要望
git pull

ticketNumber=`git branch | grep "*" | awk '{print $2}' | sed -e "s/^\([0-9]*\).*/\1/g"`
if [ -n "$ticketNumber" ]; then
    exit 0
else
    # チケット番号がないブランチ
    echo -e "チケット番号がありません。"
    exit 1
 fi

PHPStorm勢からのアツい要望とありますが、チェックアウトしたときにGitPullされていないことが何回かあったというお話を聞いてついでに入れました。

それ以降は、ブランチ名からチケット番号らしき数字を取得して、それがあればOKなければエラーを表示するようにしました。

eixt のコード0が正常に終了したことを伝え、エラーの場合は0以外(ここでは1)を指定するようにします。


2. ブランチ名からチケット番号を取得して自動的にコミットメッセージに組み込むGitHookを作成

前のセクションでブランチ名にチケット番号があるという前提ができました。
これ以降は、ブランチ名にチケット番号が入っているので、それをコミットメッセージにチケット番号を入力すればいいだけです。

#!/bin/sh

if [ "$2" == "" ] ; then
    ticketNumber=`git branch | grep "*" | awk '{print $2}' | sed -e "s/^\([0-9]*\).*/\1/g"`
    if [ -n "$ticketNumber" ]; then
        mv $1 $1.tmp
        echo "fix #${ticketNumber}" > $1
        cat $1.tmp >> $1
    else
	# チケット番号がないブランチ
	echo -e "チケット番号がありません。"
	exit 1
    fi
fi

さっきのpost-checkoutを流用しただけのお手軽ファイルを作成します。
ブランチ名からチケット番号らしき数字を取得し、コミットメッセージの最初にfix #チケット番号 を追加しています。

※すべてのコミットにこれが適用されます。


3. 作成したGitHooksを共有する

基本的に、GitHookは「.git/hooks」で生成・管理されるので、Git管理下にありません。
ですが、今回はチームメンバーと共有しなくては意味がありません。

なんと便利なことにコマンド一つでGitHooksのパスを変更することが可能なのです!

git config core.hooksPath <githooks dir>

超簡単!一番最後の引数にgithookしてほしいファイルが入ったディレクトリを指定するだけです。今回は、プロジェクトルートに「.githooks」ディレクトリを作成し、その中に1と2で作成したファイルを入れます。

なので、この場合下記コマンドを実行するだけで、良いわけです。

git config core.hooksPath .githooks

3 – 1 ダブルクリックだけで済むようにする

このコマンドをターミナルに入ってプロジェクトのあるディレクトリで実行してくれ!というのも簡単ですが、さすがに不親切な気がするので、batファイルを作っておきます。(windowsユーザーがほとんどなので)

@echo off
cd %~dp0
git config core.hooksPath .githooks

cd %~dp0 でこのbatファイルが存在するディレクトリに移動
そして先ほどのコマンドを実行

ただそれだけのファイルですが、あると便利だしみんな助かるので作りましょう。

※作成したbatファイルと.githooksが同じ階層にある前提です。

3 – 2 一時無効化batファイルを作成

急な修正やチケットがない変更…その他もろもろの理由で今回作成したgithooksが鬱陶しく感じる時があるかもしれません。
ですので、事前に一時無効化できるようにしておきます。

chcp 65001
@echo off
cd %~dp0
git config core.hooksPath .git/
set /p x="GitHooksの機能を一時的に無効化しました。元に戻しますか?(y/n):"
if "%x%" == "y" (
    git config core.hooksPath .githooks
)

このファイルをダブルクリックすることで、一時的に無効化されます。
その後はキー入力次第で元に戻すかどうか選択することができます。

一番上に「chcp 65001」と入れておくことで、日本語の文字化けを防げます。

hooksPathを./gitにしておくことで、何も読み込まれない状況を作り出しています。これは、./git/hooks/にはあるが./gitではファイルが見つからないため、動作しません。ですので、新しく空の「empty_githooks」ディレクトリを作成し以下のようにすることも一つの策です。

git config core.hooksPath empty_githooks

最後に

これでひとまず、プログラム側でどうにかできたので、後は運用面で浸透させる必要があります。

もしかすると、ここが一番肝で難しいことかもしれませんね…

それでは、またお会いしましょう!(^^)!