21
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

DeNA 21 新卒Advent Calendar 2020

Day 22

Git Hooksのpre-commitを用いて望まないコミットを未然に防ぐ

Last updated at Posted at 2020-12-21

本記事はDeNA 21 新卒 Advent Calendar 2020の22日目の記事です。

はじめに

こんにちは、@7riatsuです。

突然ですが、皆さんは自分の意図しないコードをGitHubにプッシュしてしまった経験はありませんか?
僕はあります。それも人に見られると恥ずかしいような内容でした。

プログラムの動作確認時に出力を目立たせるため、以下のコードを書いていました。

test.rb
puts "💩"
puts hoge #検証したい変数

hoge に適切な値が入っていることを確認したので、コミットをしてGitHubにプッシュし、レビューを依頼したところで悲劇は起きました。

「💩がプッシュされているよ」

あろうことか、レビューを依頼する前に動作確認用に仕込んでいた不要な行をコミットしていたのでした。
その他にもデバッグ目的で仕込んだ console.logbinding.pry を誤ってコミットしてしまうことが多々ありました。
このような単純なミスは「レビュー前に確認をするべき」の一言で片付けるのではなく、仕組みで防ぎたいところです。

そこで今回は、Git Hooks の pre-commit を利用して、自分の意図しない不要な行のコミットを防ぐ方法をご紹介します。

Git Hooks とは

Gitの特定のアクションが発生した時にスクリプトを起動するもの。
クライアントサイドとサーバーサイドの二つのhooksに大別される。

  • クライアントサイドフック: commitmerge の際にトリガーされる
  • サーバーサイドフック:push 前後にトリガーされる

今回紹介する pre-commit はクライアントサイドフックに属する。

pre-commit とは

コミット実行時に一番最初に実行されるもの。
主な利用用途としては以下が想定される。

  • コミットしようとしているコードの検証
  • テストの実行をローカルで確認
  • コードスタイルチェック(lintなど)

更に詳しく知りたい方はGit公式ドキュメントを参照してください。

pre-commitの導入手順

それでは実際に pre-commit を動かすための準備をしていきましょう。

1. 下準備

# テスト用のディレクトリ作成
mkdir pre-commit-test
cd pre-commit-test

# gitの初期化
git init # このコマンドで後に使う.git/hooks/pre-commitが作成される

2. pre-commitのスクリプトを作成

以下のコードを .git/hooks/pre-commit にコピペしてください。

#!/bin/sh

# commitに含めたくないワードをスラッシュとパイプで区切って追加する
LIST="puts\|binding.pry\|console.log"

if git rev-parse --verify HEAD >/dev/null 2>&1; then
  against=HEAD
else
  against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

for FILE in `git diff-index --name-status --cached $against -- | cut -c3-` ; do
  if grep -w $LIST $FILE; then
    echo $FILE." has one of the word you don't want to commit. Please remove it"
    exit 1
  fi
    done
exit

こちらの記事を参照

コミットしたくないワードを追加する場合、スラッシュとパイプで区切って LIST= の行に記載してください。
例えば新たに debugger を追加するなら、以下のように変更します。

LIST="puts\|binding.pry\|console.log\|debugger"

3. 追加したスクリプトに実行権限を付与

chmod +x .git/hooks/pre-commit

1~3の手順で準備は完了しました。
それでは早速、 pre-commit が動くかどうかを検証してみましょう。

検証

今回は例としてRubyのスクリプトを検証します。
もちろん、他のプログラミング言語で書いたスクリプトに対しても動作します。

まずは puts を含んだRubyのスクリプトを準備します。

main.rb
a, b = 1, 2

c = a + b
puts c
# => 3

次に main.rb をコミットしてみましょう。

git add main.rb
git commit -m 'putsを含む足し算を追加'
# puts c
# main.rb. has one of the word you don't want to commit. Please remove it

確かにputsを含んでいるのでコミットに失敗しました。

次はmain.rbからputsを除いてコミットしてみましょう。

main.rb
a, b = 1, 2

c = a + b
git add main.rb
git commit -m 'putsを含まない足し算を追加'
# [master (root-commit) b824f3b] putsを含まない足し算を追加
#  1 file changed, 3 insertions(+)
#  create mode 100644 main.rb

今度は正常にコミットをすることができました。

また、以下のコマンドでhooksをトリガーさせずにコミットすることも可能です。

git commit --no-verify

終わりに

特に他の人にレビューを依頼している場合、単純な指摘ではなく、もっと重要な指摘に時間を割いてもらうために、こういったミスは極力したくありません。
単純なミスは積極的に仕組みで防いでいきましょう!

宣伝

この記事を読んで「面白かった」「学びがあった」と思っていただけた方、よろしければ Twitter や facebook、はてなブックマークにてコメントをお願いします!
また DeNA 公式 Twitter アカウント @DeNAxTech では、 Blog記事だけでなく色々な勉強会での登壇資料も発信してます。ぜひフォローして下さい!
Follow @DeNAxTech

21
10
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
21
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?