Git hooks を使って push を行うときに確認を出し誤 push を防止する

Git hooks を使って push 時に確認を出す方法を紹介します。
2018.07.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、黒澤です。

開発を行う中で rebsae を用いて develop に追従させる運用をしていると、feature に force push する機会が出てくると思います。

GitのRebaseによるBranchの運用

あるとき、こんなミスをしてしまいました。

$ git push -d origin feature/hoge

git push -f とするところを -d とタイプミスして push してしまいました。f と d が隣にあるのでなくはないミスだと思います。(そうだよね?)

すると、何が起こるかというと リモートのブランチが消し飛びます。

$ git push -d origin feature/hoge
:
 - [deleted]         feature/hoge

WIP で作っていた PR もクローズします。

PR 自体は Restore branch のボタンを押して、Reopen and comment してやれば復活させることが可能です。

でもこれで「じゃあいいや」で終わる問題かと言えばそうではありません。force push は破壊的な push ができてしまうコマンドです。今回起こった問題以外にも何かやらかしてしまう可能性があります。

そこでなんとかしたいというのが今回の本題です。

Git hooks とは

特定のアクションが行われた際に、スクリプトを実行することができます。今回のケースでいうと push が行われたときにスクリプトを実行して確認を出すのを実現するのに使用します。

Git - Git フック

スクリプトを書く

hook は通常各プロジェクトの .git/hooks に格納されています。適当なディレクトリで見てみるとこんな感じになっていると思います。

$ cd .git/hooks/
$ tree
.
├── applypatch-msg.sample
├── commit-msg.sample
├── fsmonitor-watchman.sample
├── post-update.sample
├── pre-applypatch.sample
├── pre-commit.sample
├── pre-push.sample
├── pre-rebase.sample
├── pre-receive.sample
├── prepare-commit-msg.sample
└── update.sample

でも今回はプロジェクト単位ではなく全部に適用したいものなので init.templatedir を使って指定を行います。

# ディレクトリを作る
$ mkdir -p ~/.git_template/hooks
# push したときに実行するスクリプト
$ vi ~/.git_template/hooks/pre-push
# 実行権限をつける
$ chmod a+x ~/.git_template/hooks/pre-push
# テンプレートに指定する
$ git config --global init.templatedir '~/.git_template'

pre-push の中身

#!/bin/bash

echo '[warn] push to remote, continue? [y/N]'

exec < /dev/tty
read answer

case $answer in
    'y' | 'yes') echo '[info] OK. push start.';;
    * ) echo '[error] push failed.';exit 1;;
esac
exit 0

これで push を行なった際に、pre-push に書いたスクリプトが実行されます。

$ git push -f origin feature/hoge
[warn] push to remote, continue? [y/N]
y
[info] OK. push start.

確認というワンクッションを置くことで f を d に間違えて push するというしょうもないミスは減らせた気がします。今回は push しか設定していませんが他にも様々なアクションに対して hook を設定することができるのでサンプルファイルを参考にすると良いと思います。

また、実行できれば Ruby とか Python でも記述することが可能です。

まとめ

  • Git hooks を使おう
  • めそ子スタンプをよろしくお願いします!

めそ子のLINEスタンプが出来ました