at kaneshin

Free space for me.

【Git】コミットメッセージのスペルチェック

f:id:laplus-knsn:20161209000103p:plain

この記事は Git Advent Calendar 2016 - Qiita の8日目の記事です。

スペルチェッカー - aspell

スペルチェックをするために aspell というスペルチェッカーを使用します。

f:id:laplus-knsn:20161209000151j:plain

インストール on macOS

macOS では Homebrew 🍺 を使ってインストールします。

# To install aspell
$ brew install aspell

# make sure that the aspell has been installed.
$ which aspell
/usr/local/bin/aspell

インストール on Debian

Debian しか使っていないものでして…

# To install apell
$ apt-get install aspell -y

# make sure that the aspell has been installed.
$ which aspell
/usr/bin/aspell

使い方

list コマンドを使用して、STDIN から文字列を流します。

# Test (Typo beautifl)
$ echo What a beautifl sky | aspell list
beautifl

上の例では beautiful をわざとタイポしています。

Git フック

どのタイミングで検証をするかはやはり Git フックで対応することになりますが、pre-commit などのクライアントサイドフック はよくあるので今回はサーバーサイドフックを使用します。

サーバーサイドフック

サーバーサイドフックスクリプトは知らない人は結構いる気がします。GitHub で特定のブランチのフォースプッシュを禁じる設定があると思いますが、あれはサーバーサイドフックが設定されているからです。

クライアントサイドフックの他に、いくつかのサーバーサイドフックを使うこともできます。これは、システム管理者がプロジェクトのポリシーを強制させるために使うものです。これらのスクリプトは、サーバへのプッシュの前後に実行されます。pre フックをゼロ以外の値で終了させると、プッシュを却下してエラーメッセージをクライアントに返すことができます。つまり、プッシュに関するポリシーをここで設定することができるということです。

サーバーサイドフックには下記の3種類存在しています。

  • pre-receive
  • post-receive
  • update

pre-receive, post-receive フック

クライアントからのプッシュを処理するときに最初に実行されるスクリプトが pre-receive で、処理が終了した後に実行されるのが post- receiveです。スクリプトは、プッシュされた参照のリストを標準入力から受け取り、ゼロ以外の値で終了させるとプッシュが却下されます。post-receive フックについては処理の完了通知などに使うことができます。

update フック

update フックは pre-receive フックと似ていますが、pre-receive と違うのは複数のブランチへのプッシュがあったときにブランチ単位でそれぞれ一度ずつ実行されます。

スペルチェック方法

1. pre-receive

下記のスクリプトを .git/hooks/pre-receive に記述します。

#!/bin/sh

which aspell > /dev/null
if [ ! $? -eq 0 ] ; then
  exit 0
fi

while read oldrev newrev refname
do
  misspelled=`git log --format=%B -n 1 "$newrev" | aspell list`
  if [ -n "${misspelled}" ] ; then
    echo >&2 "Possible misspelled words in the commit message:"
    for e in $misspelled; do echo >&2 " - ${e}"; done
    exit 1
  fi
done

2. コミットメッセージ例

今回、下記のようなコミットメッセージを用意しました。beautiful をタイポしています。

$ git log
commit f4eb3de
Author: Shintaro Kaneko <kaneshin0120@gmail.com>
Date:   Thu Dec 8 14:03:37 2016 +0000

    Initial commit: What a beautifl sky

3. git push

下記のようにプッシュを行うと、メッセージとともにプッシュがリジェクトされます。

$ git push origin master 
Counting objects: 1, done. 
Writing objects: 100% (1/1), 190 bytes | 0 bytes/s, done. 
Total 1 (delta 0), reused 0 (delta 0) 
remote: Possible misspelled words in the commit message: 
remote:  - beautifl 
To /home/kaneshin/foo/rem 
 ! [remote rejected] master -> master (pre-receive hook declined) 
error: failed to push some refs to '/home/kaneshin/foo/rem' 

おわりに

pre-commit とかでは個人の環境に依ってしまうので、サーバーサイドフックでカバーできるところは積極的にカバーしていきたいものです。