チームで共通のフックスクリプト(Git hook)を使っています


My Redmine

サービス開発グループの石川です。
今回のブログでは、チームで共通したGit hookのフックスクリプトによってコミット前のチェックをしている話をしようと思います。

Git hookとは?

Gitで特定のアクションが発生したときにカスタムスクリプトを実行する方法です。
詳細: https://git-scm.com/book/ja/v2/Git-のカスタマイズ-Git-フック

利用しているフックスクリプト

git commitコマンドを実行した際、変更されたファイルをRubocopで解析し、Warning以上の警告がないかをチェックする」というpre-commitファイルを利用しています。(こういった共通したチェックはpush後に通るCI上で実行した方が個人の環境に左右されず良いかもしれませんが、今回は色々理由があってgit hookを使っています。)

#!/bin/sh

# git diffに含まれるrubyファイルに対してrubocopでチェック
# fail level warning以上のもののみをチェックする
if git diff --cached --name-only --diff-filter=AM | grep '\.rb$'; then
  echo '---rubocopでfail-level W以上の警告がないかチェック---'
  git diff --cached --name-only --diff-filter=AM | grep '\.rb$' | xargs  bundle exec rubocop --fail-level W --display-only-fail-level-offenses
fi

推奨されていないメソッドを使っている場合や、デバッグ用のbinding.pryがコードに入ったままといった場合などに気付いて直せるようにすることが目的です。

test/test_helper.rbの中にbinding.pryを含んだ状態でコミットすると、以下の画像のように警告が表示されて問題に気付くことができます。


実際にコミットしたときの画面

他にも、「RedmineやGithubのチケット・Issueにコミットを紐付けるため、コミットメッセージに #nnn のような番号が含まれていることをチェック」などもフックスクリプトを共有すると良さそうです。

チームで共通のGit hookを使う方法

クライアントサイドのフックスクリプトは .git/hooks 以下に置くものなのですが、.git 以下のファイルはバージョン管理されないため .git/hooks もリポジトリで管理することができません。

そのため .githooks という新しく作ったディレクトリの中に共通のフックスクリプトを置き、最初の環境構築時に以下のようなコマンドを各自実行するようにしています。(READMEの環境構築手順の中に書いている)

$ git config --local core.hooksPath .githooks
$ chmod -R +x .githooks/

git config --local core.hooksPath .githooks を実行することで .git/hooksではなく .githooks以下のファイルがフックスクリプトとして実行されるようになります。
https://git-scm.com/docs/githooks

フックスクリプトは実行権限が無いと実行されないため、 chmod -R +x .githooks/ で権限を追加しています。

また、共有するフックスクリプト以外は自由に設定できるように .gitignore に以下のような設定を追加して、 pre-commitのみがステージング対象になるようにしています。

.githooks/*
!/.githooks/pre-commit

core.hooksPath設定を変えることで起こりうる問題

セットアップ時にcore.hooksPathを変えたと言うことを忘れた状態で個人の範囲で .git/hooks にスクリプトを追加した場合、うまく働かず苦しむことになってしまいます。その点を気にするならcore.hooksPathを変えるやり方では無く、以下のようにセットアップ時に手作業で.git/hooksにフックスクリプトをコピーする形にした方が良いです。

$ # githooksを.git/hooksにコピー
$ cp -r githooks .git/hooks

この場合、フックスクリプトを変更しても.git/hooksには変更が反映されない為スクリプトを変更したらチームメンバーにコピーし直すようお願いしないといけませんが、フックスクリプトはそこまで頻繁に変えるようなものでも無いので問題ないと思います。

最後に

コミット前にコードやコミットメッセージをチェックしたい場合には、Git hookのスクリプトを共有すると便利です。共有の仕方については core.hooksPath を変えるやり方と .git/hooks に各自コピーするやり方とがありますが、変更の頻度などに応じて適切なやり方を選ぶと良いと思います。


My Redmine

こちらの記事もオススメです!
Redmineとちょっとした自動化でちょっと幸せに
仕事の中で手間なことや困ったことを、git hooksやRedmineのAPIを活用した"ちょっとした自動化"で解決しています。
My Redmineのバージョンアップ作業をMy Redmineで管理
Redmineの機能「バージョン(ロードマップ)、「親子チケット」、「チケットのコピー」を使ってバージョンアップを管理している事例です。
SmartHRで人事情報の管理を検証中です
人事・労務管理ができるクラウドサービスSmartHR(30名まで無料)で人事情報の管理を行っています。
AWSを利用したハンズオン講座で講師を務めました(資料あり)
AWSを利用したハンズオン講座で講師を務めました。当日は参加者全員が予定していた内容を全て体験することができ、大好評でした!
AWS上でクラウドネイティブで再構築した「My Redmine Gen.2」リリース!
My Redmine Gen.2をリリース!クラウドへの対応を進めより良いサービスになりました。
ファーエンドテクノロジーからのお知らせ(2024/04/17更新)
入門Redmine 第6版 出版記念セミナー「Redmine 8年分の新機能ふりかえり」【2024/4/18開催】
入門Redmine 第6版(2024年3月23日発売)に掲載された新機能に関する内容を執筆者・監修者が紹介します。
My Redmine 初回ご契約で「入門Redmine 第6版」プレゼントのお知らせ
Redmineのクラウドサービス「My Redmine」を初めてご契約いただいたお客様にRedmine解説書「入門Redmine 第6版」を進呈いたします。
2024年度ブランドパートナーに島根県在住のモデル ユイさんを継続起用
ユイさん(モデルスタジオミューズ所属)をファーエンドテクノロジーの2024年度ブランドパートナーとして継続して起用します。
My Redmine スタンダードプランおよびAdminサポートデスクプランの料金改定のお知らせ【2024年4月ご利用分より】
2024年4月ご利用分より、My Redmine スタンダードプラン(民間企業・個人向け及び官公庁向け)とAdminサポートデスクプランの料金を改定いたします。
Redmineの最新情報をメールでお知らせする「Redmine News」配信中
新バージョンやセキュリティ修正のリリース情報、そのほか最新情報を迅速にお届け