しおメモ

雑多な技術系ブログです。ニッチな内容が多いです。

masterへのpushをローカルではじく

ルールとマナーを守って楽しくgit pushしよう!!

概要

GitHub等サーバーサイドで、masterやdevelopへのforce pushは禁止できますが、普通のpushは素通りしてしまいます。

運用ルールにもよるとは思いますが、ローカルからmasterに直push出来てもあまりいいことがなさそうなので、ローカルではじきます。

pre-pushを作る

こんな感じのを.git/hooksに作ればOKです。

#!/bin/bash

TARGET_BRANCHES="(master|develop)"

while read local_ref local_sha1 remote_ref remote_sha1
do
  if [[ "${remote_ref##refs/heads/}" =~ $TARGET_BRANCHES ]]; then
    echo "😇😇😇${remote_ref##refs/heads/}にpush奴〜〜〜😇😇😇"
    exit 1
  fi
done

commit用のpre-commitもあります。

shellでフックをかける

git initに仕込むなど、やり方はいろいろあるとは思いますが、フックをかけるタイミングを選びたいので、自分はdotfilesにオリジナルを置いておき、都度コピーしています。

よく使うので、.bashrcやら.zshrcに入れてあります。

# フックかける
ghooks() {
    GIT_ROOT=`git rev-parse --git-dir 2>/dev/null`
    if [ "$GIT_ROOT" ]; then
        cp ~/dotfiles/githooks/* $GIT_ROOT/hooks/
        chmod a+x $GIT_ROOT/hooks/*
    fi
}
# フック外す
rmhooks() {
    GIT_ROOT=`git rev-parse --git-dir 2>/dev/null`
    if [ "$GIT_ROOT" ]; then
        rm $GIT_ROOT/hooks/pre-push
    fi
}

chmodで実行権限を付与しないと動きません。

フックの有無をプロンプトに表示する

zshの場合、

function zle-line-init zle-keymap-select {
    # ...
    RPROMPT='${vcs_info_msg_0_}'
    if [ -e "`git rev-parse --git-dir 2>/dev/null`/hooks/pre-push" ]; then
        RPROMPT="🔒"$RPROMPT
    fi

    zle reset-prompt
}

このようにすると、こんな感じになります。

f:id:scior:20190307205040p:plain

フックかけ忘れも防げるのでオススメです。