コミット前にチェックしたい(pre-commit
)
$ pre-commit --version
pre-commit 3.8.0
$ pre-commit install
$ pre-commit run --all-files
pre-commit
はGit Hooksを使って、
コミット前などにコードのチェック作業などを自動化できるツールです。
設定ファイルは.pre-commit-config.yaml
です。
Pythonで書かれていますが、いろいろなプログラミング言語やプロジェクトで使えるようになっています。
注釈
commitizenを有効にすると、自動で追加されます。
インストールしたい(pre-commit
)
pip
でインストール
$ pip3 install pre-commit
$ pip3 install -U pre-commit
pipx
でインストール
$ pipx install pre-commit
$ pipx upgrade pre-commit
poetry
でインストール
$ poetry add pre-commit --group=dev
uv
でインストール
$ uv tool install pre-commit
$ uv tool upgrade pre-commit
設定したい(.pre-commit-config.yaml
)
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0 # 最新バージョンにする
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-added-large-files
- repo: リポジトリ
rev: バージョン
hooks:
- id: フック名
.pre-commit-config.yaml
にフック情報を記述します。
設定できるフックはSupported Hooksで確認できます。
チェックしたい(run
)
$ pre-commit run --all-files
run
コマンドでフックの確認ができます。
--all-files
オプションで、カレントディレクトリの下にあるすべてのファイルに対してチェックを実行します。
trailing-whitespace
やend-of-file-fixer
などのフックを有効にしている場合、ファイルが自動で修正されます。
フックしたい
$ find .git/hooks -f type ! -name "*.sample" -perm u+x
.git/hooks/pre-commit
.git/hooks/
で、現在有効になっているGit Hooksを確認できます。
*.sample
が付いていない実行ファイルが有効なフックです。
$ pre-commit install --hook-type フック名
--hook-type フック名
オプションで、フックを追加できます。
$ pre-commit install --install-hooks --hook-type pre-commit --hook-type commit-msg
--install-hooks
オプションで、複数のフックをまとめて追加できます。
# .pre-commit-config.yaml
default_install_hook_types:
- pre-commit
- commit-msg
- pre-push
.pre-commit-config.yaml
で有効にするフックを指定することもできます。
デフォルトはpre-commit
(コミットの直前)です。
commit-msg
やpre-push
など以下のGit Hooksもサポートされています。
Git Hook |
タイミング |
設定方法 |
---|---|---|
|
コミットメッセージ作成の直後 |
|
|
ブランチ切り替えの直後 |
|
|
コミットの直後 |
|
|
マージの直後 |
|
|
コミットを修正した直後 |
|
|
コミットの直前 |
デフォルト |
|
マージコミットの直前 |
デフォルト |
|
プッシュの直前 |
|
|
リベースの直前 |
|
|
コミットメッセージ作成の直前 |
|
# .pre-commit-config.yaml
repos:
- repo: リポジトリ
rev: バージョン
hooks:
- id: フック名
stages:
- フックのタイミング
- [pre-commit, commit-msg]
また、設定ファイルのstages
セクションで、
ツールごとにpre-commit
フックを実行するタイミングを設定できます。
pre-commit-hooksしたい
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: detect-private-key
- id: trailing-whitespace
args: ["--markdown-linebreak-ext=md"]
- id: end-of-file-fixer
- id: check-case-conflict
- id: check-merge-conflict
- id: check-added-large-files
args: ["--maxkb=500"]
- id: check-json
- id: check-toml
- id: check-yaml
- id: name-tests-test
args: [--pytest-test-first]
pre-commit-hooks
のフックから、
使うとよさそうなものを選んでみました。
ruff-pre-commitしたい
ruff
は、Pythonプロジェクトの
リンター&フォーマッターです。
コミットごとに自動チェックすることで、コードの表記ゆれを抑えることができます。
フックの設定方法はフォーマッター/リンターしたい(ruff)に整理しました。
commitizenしたい
commitizen (cz)
はコミットメッセージの形式を守るためのツールです。
stages: [commit-msg]
でコミットメッセージを保存したあとにフックがかかるようにしておきます。
フックの設定方法はセマンティック・バージョニングしたい(commitizen)に整理しました。
poetryしたい
repos:
- repo: ...
- repo: https://github.com/python-poetry/poetry
rev: 1.8.0
hooks:
- id: poetry-check
args: [--lock]
stages: [pre-push]
#- id: poetry-lock
- id: poetry-export
args: [--format, requirements.txt, --output, requirements.txt]
stages: [pre-push]
#- id: poetry-install
Pythonプロジェクトをpoetry
で管理している場合は、
poetry-check
(=poetry check
)、
poetry-lock
(=poetry lock
)、
poetry-export
(=poetry export
)、
poetry-install
(=poetry install
)
のフックを導入してみるとよいかもしれません。
それぞれに適切なargs
を設定して使うとよいと思います。
また、コミット時ではなくプッシュ時(pre-push
)に設定するとよいと思います。
注釈
Read the Docsに公開するためにrequirements.txt
が必要です。
このリポジトリも、もpoetry-export
フックを使って、
requirements.txt
を生成できるようにしてあります。
脆弱性を検出したい(Bandit
)
repos:
- repo: ...
- repo: ...
- repo: https://github.com/PyCQA/bandit
rev: 1.7.4
hooks:
- id: bandit
args: ["-r", "ディレクトリ名"]
nbstripoutしたい
repos:
- repo: ...
- repo: https://github.com/kynan/nbstripout
rev: 0.5.0
hooks:
- id: nbstripout
Jupyter Notebookを使っている場合、
実行結果を削除したファイルをコミットしたい場合があります。
nbstripout
でコミット前に出力をクリアできます。
注釈
.ipynb
ファイルは、実行結果を残しているといつのまにか間に肥大化している可能性があります。
また、デバッグ用途に使っている場合、
うっかりとシークレット情報を出力に残したままにしてしまう可能性もあります。
そのようなことを回避したい場合、このツールは有用です。
pytestしたい
repos:
- repo: local
hooks:
- id: pytest
name: pytest
entrypoint: pytest --verbose
stages:
- [pre-push]
language: system
pytest用のフックはGitHub上にはないようです。
pre-commit
はローカル(local
)にインストールされているコマンドを使うことができます。
プッシュ時(pre-push
)にテストを走らせるとよいと思います。
注釈
テストはCI/CDでも実行しているかもしれません。 ローカルからのプッシュ前に確認を追加することで、 パイプライン時間の無駄遣いを減らすことができます。