0
Help us understand the problem. What are the problem?

posted at

git hooksでpre-commit hooksを使って自動化した話

git のcommit前にlintやらを差し込みたいなということgit hooksを使って設定してみました。

git hooksとは

gitが提供している公式の機能でgitの特定のイベントをトリガーにして自分が設定したscriptを実行させる機構です。
例えば、push前にtestを実行をさせたり、commit前にlintを走らせたりできます。
今回は、commit前にlintを走らせる処理を書きました。

設定方法(pre-commit)

git hooks自体はgitに内蔵されています。
具体的には.gitの中にscriptのサンプルファイルがあります。

terminal でgitで管理しているプロジェクトのrootに移動して
下記のコマンドでhooksファイルがあるディレクトリに移動しましょう。

cd .git/hooks/ 

すると、以下のファイルがあり、 .sample という文字列をファイル名が除外して

chmod a+x <ファイル>

と権限を与えればhooksが有効になります。

applypatch-msg.sample     fsmonitor-watchman.sample pre-applypatch.sample     pre-merge-commit.sample   pre-rebase.sample         prepare-commit-msg.sample
commit-msg.sample         post-update.sample        pre-commit.sample         pre-push.sample           pre-receive.sample        update.sample

今回は pre-commitを使いたいので以下の用にリネームします。

pre-commit.sample -> pre-commit

pre-commitのscriptを書く

実際にscriptを書きましょう。 
今回はgolang-ci-lintを使って

  • lintを実行させる
  • formatを実行させる

を行いたいので以下のようにしました。

#!/bin/sh

echo "lint start"

cd $(git rev-parse --show-toplevel)
RESULT=$(golangci-lint run pkg/...)

if [ -n "$RESULT" ]; then
echo "lint failed"
  exit 1
fi

git add .
echo "lint finish"

lintの実行場所を固定にする

下記は必ずscriptの実行場所が必ずproject rootになるように、gitの管理場所を取得して、そのディレクトリに移動するようにしています。

git rev-parse --show-toplevel

lintの実行結果を格納

下記はlintの実行結果を格納しています。
これはあまりよろしくなく、本来は終了ステータスを格納すべきですが、誤ってそのまま実行結果の文字列を格納しちゃってます。

RESULT=$(golangci-lint run pkg/...)

強制的にformatをかけてcommitさせる

pre-commit内でgit addしてる理由は、format後のファイルをステージするためにです。

git add .

golangci-lintはauto formatの機能があるので、実際のcommitは以下の処理順番になります。

  • git commit コマンドを打つ
  • pre-commitが発火
  • golangci-lint run pkg/... でファイルにformatがかかる
  • git add .
  • formatがかかって変更されたファイルが新たにstageされる
  • commit 処理が走る

このようにしておくと、formatのかけ忘れなどを防ぐことができます。

管理方法

これでhooksは完成しましたが、.git内にファイルがある関係上このままではgit管理ができません。

なのでhooksファイルとhooksの参照先ファイルを変更します。
変更方法は以下の通り

適当なディレクトリを作り、そこのhooksファイルを移動

mkdir .githooks
mv ./git/hooks/pre-commit .githooks/

gitのhooksファイルの参照先を変更

git config core.hooksPath .githooks

hooksに実行権限を付与

chmod a+x .githooks/pre-commit

これで、hooksファイルの管理場所が.gitでは無くなったのでgit管理できるようになりました。

最後に

hooks といえば husky 自分で作るのは面倒くさいと敬遠していたのですが、重い腰をあげて作ってみると思いのほか簡単にできました。
何かの参考になれば幸いです。

それでは良い git hooksライフを

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
0
Help us understand the problem. What are the problem?