LoginSignup
7
4

More than 3 years have passed since last update.

git commit前にaddしたファイルのみrubocopで検査する

Posted at

pre-commitを使ってRubocopで検査すると遅い

もともとの.git/hooks/pre-commitはこうなっていた。

#!/bin/sh

bundle exec rubocop -P
if [ "$?" -ne 0 ]; then
    exit 1
fi

これによって、コミット前にRubocopを強制実行してルールに外れている場合はコミットさせないようにしているのだけれど、如何せん遅い😡

遅い原因

かれこれ6年も運営しているRailsプロジェクトで行うと数分間応答がなくなってしまう。検査対象が全てのファイルになっているからだ👎

課題

gitで変更があったファイルだけに対してRubocopを実行すればよい👍

対策

変更があったファイルだけを取り出す

gitで変更のあったファイルだけを抽出するには、git diffを使う。

git diff --cached --name-only --diff-filter=AMRC

オプションの説明

--cachedは、addされたファイルだけを対象にする。
--name-onlyは、変更のあったファイル名だけを取り出す。
--diff-filter=AMRCは、Added, Modified, Renamed, Copiedなファイルを対象とする。

Rubyのファイルだけを取り出す

現時点だとRuby以外の変更ファイルも抽出されるので、さらにgrepで絞り込む

git diff --cached --name-only --diff-filter=AMRC | grep '\.rb\>$'

拡張子が.rbで終わっているファイルだけに絞り込んだ。

Rubocopを実行する

絞り込まれた結果に対してRubocopを行う。渡す方法にはxargsを使う。

git diff --cached --name-only --diff-filter=AMRC | grep '\.rb\>$' | xargs bundle exec rubocop -P

これで、変更のあったRubyファイルだけを対象にRubocopを実行することに成功した🎉

ということで、.git/hooks/pre-commitを修正した。

#!/bin/sh

git diff --cached --name-only --diff-filter=AMRC | grep '\.rb\>$' | xargs bundle exec rubocop -P
if [ "$?" -ne 0 ]; then
    exit 1
fi

オマケ

Auto Collectもこれを使うとめっちゃ速い😎

git diff --cached --name-only --diff-filter=AMRC | grep '\.rb\>$' | xargs bundle exec rubocop -a

しかしpre-commitには含めたくないし、いい感じのコマンドにしたいけれど、いいコマンド名を思いつかない…🤔

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4