git commitのタイミングで差分のあるファイルのみ整形する
2022-07-29
はじめに
複数人で開発をすると人によってコードの書き方が違ってくるので、コードレビューやコード修正がしにくいということはあります。その問題を解決するためにコードフォーマッターを導入することで解決すると思います。しかし、コードフォーマッターを実行するタイミングは、まちまちなのかなと思います。コードをビルドするタイミング、エディタ上でコードを保存するタイミング、CI 上で整形などなど…しかし、これらのタイミングだと以下の問題があるのかと思っています。
- コードをビルドするタイミング
- ビルドするほどじゃないコード修正のときにビルドしないといけないので面倒
- エディタ上でコードを保存するタイミング
- vim や VS Code など人によって使っているエディタが違うときに設定方法が違ってくるので面倒
- CI 上で整形
- 最近の CI はクレジットを消費して実行するものが多いので、貴重なクレジットを整形に使うのはもったいない(クレジット消費が多いのは体感なので間違ってるかも)
これらの問題を解決するコードフォーマッターのタイミングが、git commit
かなと思いました。git なら人によって環境が違うということもなくpre-commit
を作ればチームで設定を使い回せるのもいいと思っています。今回はそんな commit のタイミングで差分のあるファイルに対してコードを整形する方法について紹介します。
設定方法
リポジトリ直下に.githooks
を作って、pre-commit
ファイルを作成します。今回は SwiftLint で Swift ファイルを、clang-format で C++ファイルのコードを整形するシェルスクリプトを載せています。フォーマッターを実行している箇所を、使いたいものに環境によって変更して下さい。事前に、SwiftLint や、clang-format など使うフォーマッターをインストールして下さい。
#!/bin/bash
STAGED_FILES=$(git diff --diff-filter=d --staged --name-only)
echo "$STAGED_FILES" | grep -e '\(.*\).swift$' | while read -r file; do
swiftlint autocorrect --format --path "${file}"
git add "${file}"
done
#!/bin/bash
STAGED_FILES=$(git diff --diff-filter=d --staged --name-only)
echo "$STAGED_FILES" | grep -e '\(.*\).cpp$' -e '\(.*\).h$' | while read -r file; do
clang-format -i -style=file "${file}"
git add "${file}"
done
そしてリポジトリ直下で以下のコマンドを実行します。
git config core.hooksPath .githooks
chmod +x .githooks/pre-commit
これでgit commit
のタイミングで自動で整形されます。pre-commit
は commit の直前に実行されるので、フォーマットした後は、再度整形したファイルをgit add
します。シェルスクリプト内で再度git add
しないと整形前のステージングされたファイルが commit されます。このスクリプト実行後に整形されたファイルが commit されます。
最後に
今回は commit のタイミングでコードを整形する方法について紹介しました。設定も簡単なのでおすすめです。 この設定を導入する時は、一度、プロジェクト全体にフォーマッターで整形して、master(main)リポジトリなりに反映しないと、編集箇所以外の箇所も整形して差分が大変なことになりますのでご注意して下さい。