git PR

gitのpre-commitでコミット前のチェックを行う方法

記事内に商品プロモーションを含む場合があります

概要

この記事ではgitのcommit時(コミットメッセージの入力前)に自動でlinterなどを実行するpre-commitフックの実装方法について解説します。

コミット前(pre-commit)のタイミングでコードのスタイルチェックやlinter、テストの実行を挟むことで、これらのチェックを通っていないコードをうっかりコミットしてしまうことを避けることができ、コードの品質を保つことにもつながります。

毎回手動でこれらのチェックツールを実行するのは面倒で忘れがちなので、pre-commitで自動で実行されるように設定しておくと便利です。

Git自体にフックという機能があり、それを活用することでコミット前に特定のスクリプトを実行することができます。

まずはGitにどのようなフックが用意されているのかざっと確認しておきましょう。

gitがcommit時に提供している4つのフック

以下4つがcommit時に用意されているフックです。

興味のある方はこちらの公式ドキュメントも参照してみてください。

Gitフック

フックのタイミングによって用途が異なるので、実現したいことに合わせてどのフックで実行するか検討しましょう。

なお、この記事で紹介するのはpre-commitフックになります。

pre-commitフック

  • 実行タイミング
    • コミットメッセージが入力される前にスクリプトが実行されます。
  • 用途
    • コードのスタイルチェック、リント(lint)チェック、ユニットテストの実行など。
    • 実行したスクリプトが(0以外のステータスを返す)とコミットは中止されます。

prepare-commit-msgフック

  • 実行タイミング
    • コミットエディタが表示される直前にスクリプトが実行されます。
  • 用途
    • デフォルトのメッセージを設定したり、コミットメッセージのフォーマットを強制したりするために使用されます。

commit-messageフック

  • 実行タイミング
    • コミットメッセージを入力した後でスクリプトが実行されます。
  • 用途
    • コミットメッセージを検証し、特定のフォーマットに従っていることを確認するために使用されます。
    • 実行したスクリプトが(0以外のステータスを返す)とコミットは中止されます。

post-commitフック

  • 実行タイミング
    • コミットプロセスが全て完了した後でスクリプトが実行されます。
    • 用途
      • 一般的には通知の送信、デプロイのトリガーなど、コミット後に実行したい一連のアクションに使用されます。
      • post-commitフックの終了ステータスは無視されます。

pre-commitの実装

gitのpre-commitフックに直接スクリプトを仕込むこともできますが、よく使うチェックに関してはpre-commitというツールを使うと自分でスクリプトを書くことなく簡単に実装することができます。

ここではこのpre-commitツールを使用してgoのformatter、linterを実行する例で手順を見ていきましょう。

このツール自体は特定の開発言語向けのツールではないので、go以外の言語で利用することも可能です。

pre-commitツールのインストール

まず上記で紹介したpre-commitのツールをインストールします。

ここではmacのbrewコマンドを使用してインストールしますが、他の環境でのインストールはこちらのドキュメントを参照してください。

https://pre-commit.com/#installation

以下のコマンドでpre-commitをインストールします。

$ brew install pre-commit

インストールが完了したらコマンドが実行できるか確認してみましょう。

$ pre-commit --version
pre-commit 3.3.3 # バージョンが表示される。

バージョン情報が表示されれば正しくインストールできています。

最後にpre-commit installコマンドでpre-commitスクリプトを設置する必要があります。

$ pre-commit install

これを実行することで、.git/hooks/pre-commitと言うファイルが作成されて、git commitを実行した際にスクリプトが呼び出されるようになります。

このpre-commitツールのインストール作業は各開発者のPCで一度行う必要がありますので注意してください。

以降で紹介する.pre-commit-config.yamlを作成してもpre-commit installが完了していないとpre-commitフックが動きませんので、各開発者の環境でセットアップしておくように伝えておきましょう。

.pre-commit-config.yamlファイルを作成する

インストールしたpre-commitのツールは、.pre-commit-config.yamlというファイルを自動で読み込んでコミット前のコマンドを実行します。

例えば、git commit実行時にgo fmtgo vetを実行したい場合のファイルは以下のようになります。

repos:
- repo: https://github.com/TekWizely/pre-commit-golang
  rev: master
  hooks:
    - id: go-fmt
    - id: go-vet

一つ一つの要素を確認していくと次のような意味があります。

  • repos
    • 複数のrepoを配下に定義できる。
  • repo
    • 使用するpre-commitフックのリポジトリを指定する。
    • 例えば上記のpre-commit-golangの場合、予めgoに関するフックがリポジトリに定義されていて、その中から使用したフックを選んで実行できる。
    • repo: localとすると任意のコマンドを実行することもできる。
  • rev
    • repoに指定したリポジトリで使用するブランチを指定する。
  • hooks
    • repoに定義されているhookで使用したいものを記載する。
      • hookの指定は上記のファイルの通り、id: <hook id>のようにする。
      • hook idはリポジトリのREADMEに記載されている。

このようなファイルを作成してプロジェクトのリポジトリに含んでおくことで、チームの開発者で共有して、pre-commit時のチェックを自動化することができます。

pre-commitの動作確認

セットアップが完了したら動作を確認してみましょう。

セットアップしたディレクトリ内で、適当なファイルをgit addしてからgit commitを実行してみます。

$ touch test
$ git add test
$ git commit
go-fmt.............................(no files to check)Skipped
go-vet.............................(no files to check)Skipped

今回はチェック対象のファイルがないのでSkippedとなっていますが、go-fmtgo-vetのフックが実行されていることがメッセージからわかります。

まとめ

ここまでで説明しました通り、pre-commitを仕込むことで開発者が自身でコマンドを実行すること無くformatterやlinterの実行を強制することができます。

これらはCI上で実行するケースもあると思いますが、pre-commit時に実行することでコミットする前にエラーに気づいて早期に修正できるメリットがあります。

あまり重いチェックの場合はコミットに時間がかかるため取り入れづらいと思いますが、比較的軽いチェックであればコミット前にチェックできた方が都合が良いと思います。

ぜひ積極的に取り入れて開発体験を向上させてみてください。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA