Edited at

gitのpre-push hookでmasterブランチにpushする際にプロンプトで確認するようにする

More than 1 year has passed since last update.

会社のGitを使っているときに、自分のブランチで作業しているつもりが間違ってmasterブランチで作業しており、気づかずにpushしそうになって肝を冷やしたことがあるので、masterにpushする際はプロンプトで確認するようにした。


環境


  • Mac OS X Yosemite 10.10.5

  • Git 2.11.1


gitテンプレートディレクトリを作成

特定のレポジトリではなく、PC上で扱う全てのレポジトリのコミットをhookするため、グローバルの.gitテンプレートディレクトリを準備する。

(なお、特定のレポジトリでだけhookしたい場合は、以下で作るpre-pushファイルをレポジトリの.git/hooks/におけばよい)

mkdir -p ~/.git_template/hooks


.gitのテンプレートに.git_templateを指定

git config --global init.templatedir ~/.git_template/

これで新たにgitレポジトリを作ったりcloneすると.git_templateディレクトリの設定が有効になる。


hookファイル作成

vi ~/.git_template/hooks/pre-push

内容は以下のようにする。

#!/bin/bash

while read local_ref local_sha1 remote_ref remote_sha1
do
if
[[ "${remote_ref##refs/heads/}" = "master" ]]; then
echo "Warning: push to remote master, continue? [y/N]"

exec < /dev/tty
read ANSWER

case $ANSWER in
"Y" | "y" | "yes" | "Yes" | "YES" ) echo "OK. push start.";;
* ) echo "push failed.";exit 1;;
esac
exit 0
fi
done

gitのhookは普通にはインタラクティブなことができないらしく、readが使えなかった。

exec < /dev/tty

を追加することでreadができるようになる。


hookファイルのパーミッション変更

パーミッションを変えて実行可能にする

これをしないとhookされない。

chmod +x ~/.git_template/hooks/pre-push


結果

以上の設定をすると、masterブランチにpushする際に

Warning: push to remote master, continue? [y/N]

と訊かれるようになる。

Y, y, yes, Yes, YESと入れるとpushされ、それ以外だとpushが失敗するようになる。

masterでなく、他のブランチをhookしたい場合はpre-hookファイルのmasterの部分を置換すればよい。


参考


2018/03/18追記

複数ブランチに対応。

例えばmasterとdevelopブランチにpushする前にチェックしたい場合は以下のようにすればよい。

#!/bin/bash

while read local_ref local_sha1 remote_ref remote_sha1
do
for
branch in "master" "develop"; do
if
[[ "${remote_ref##refs/heads/}" = "${branch}" ]]; then
echo "Warning: push to remote ${branch}, continue? [y/N]"

exec < /dev/tty
read ANSWER

case $ANSWER in
"Y" | "y" | "yes" | "Yes" | "YES" ) echo "OK. push start.";;
* ) echo "push failed.";exit 1;;
esac
exit 0
fi
done
done