はじめに
突然ですが、こんな経験ありませんか?
< featureブランチにpushしたつもりがdevelopにpushしてしまった!
< pushしてからデバッグコードの消し忘れに気づいた!
どちらかを経験したことがある方は多いのではないでしょうか?(恥ずかしい話ですが私もあります...)
pushする前だったらローカルでcommitの取り消しができますが、
一度pushしてしまうとその差分は履歴として残るし、それを消すにしても消した履歴も残ってしまいますよね。
できることならpushする前に気づいてそっと修正したい...!
ということで、
今回は**「git commit した時にスクリプトを実行することで意図しない変更がpushされないようにする」**をやっていきます。
やり方
やりたいことは「git commit した時に任意のスクリプトを実行する」ことなので、
今回はGit フックのpre-commit
を使っていきます。
似たようなことができる機能でGitHub Actions
がありますが、トリガーにcommitがないので今回はpre-commit
を使っていきます。
pre-commitとは、以下Git フックより
pre-commit フックは、コミットメッセージが入力される前に実行されます。 これは、いまからコミットされるスナップショットを検査したり、何かし忘れた事がないか確認したり、テストが実行できるか確認したり、何かしらコードを検査する目的で使用されます。 このフックがゼロでない値を返すと、コミットが中断されます。
つまり、コミット前に任意のスクリプトを実行し、そのスクリプトが0を返すとコミットがそのままされ、ゼロ以外を返すとコミットが中断されます。
今回はこれを利用します。
実装
まずはスクリプトを用意します。下記の通りにコマンドを実行してください。
$ mkdir tmp
$ cd tmp
$ git init
適当なディレクトリを作成し、そこで$ git init
を実行しました。これで.git
という隠しディレクトリができているはずです。
続いて下記コマンドを実行します。
$ cd .git
$ cd hooks
$ ls
applypatch-msg.sample pre-applypatch.sample pre-rebase.sample
commit-msg.sample pre-commit.sample pre-receive.sample
fsmonitor-watchman.sample pre-merge-commit.sample prepare-commit-msg.sample
post-update.sample pre-push.sample update.sample
隠しディレクトリ内のhooksディレクトリに移動します。そこの中身をみてみるといろいろなサンプルスクリプトがあることがわかります。
これらは末尾の.sample
を消去すればそのまま動きます。
今回はここに自作のスクリプトを追加します。
$ vi pre-commit
上記コマンドでpre-commitというファイルを作成してください。(拡張子はなくて大丈夫です)
作成したファイルに下記を追記してください。
BRANCH_NAME=`git symbolic-ref HEAD | sed -e 's:^refs/heads/::'`
if test $BRANCH_NAME = master -o $BRANCH_NAME = develop; then
echo "${BRANCH_NAME} への直コミットは禁止されています。"
exit 1
fi
files=`git status|grep -e "modified" -e "new file"|sed "s/new file:\(.*\)/\1/g"|sed "s/modified:\(.*\)/\1/g"|cut -f 2`
for file in $files
do
result=`less $file | grep -e "console.log"`;
if [ -n "$result" ]; then
echo "${file} にデバッグ文が入っています。";
exit 1
fi
done
次に、作成したファイルに対して実行権限を与えてあげます。
$ chmod +x pre-commit
pre-commitが動作しているか確認します。
ここでは例としてconsole.log('hoge');
と記載されたreadme.mdというファイルを用意します。
$ git checkout master
$ git add readme.md
$ git commit -m 'test commit'
master への直コミットは禁止されています。
$ git checkout feature
$ git commit -m 'test commit'
readme.md にデバッグ文が入っています。
いずれの場合もコミットできていないはずです、
featureブランチにてconsole.log('hoge');
を削除すると正しくコミットできるはずです。