dideler
1/23/2014 - 9:31 PM

pre-push.sh

#!/bin/bash

# Called by "git push" after it has checked the remote status,
# but before anything has been pushed.
#
# If this script exits with a non-zero status nothing will be pushed.
#
# To install:
# 1. Add the file as a hook in your repository: `.git/hooks/pre-push`
# 2. Set executable permissions: `chmod +x .git/hooks/pre-push`
#
# Aborts a push for the following commands:
# `git push --force origin master`
# `git push --delete origin master`
# `git push origin :master`
#
# Aborts force pushes while on the master branch:
# `git checkout master`
# `git push --force`
# 
# Requires Git 1.8.2 or newer (pre-push hook introduced in 1.8.2).

protected_branch='master'

policy='[Policy] Never force push or delete the '$protected_branch' branch!'

current_branch=$(/usr/bin/git symbolic-ref HEAD | sed -e 's|^refs/heads/||')

push_command=$(ps -ocommand= -p $PPID)

is_destructive='force|delete|\-f'

will_remove_protected_branch=':'$protected_branch

do_exit() {
  echo $policy
  echo -e "If you know what you are doing and accept responsibility, ignore the pre_push hook with --no-verify option."
  exit 1
}

if [[ $push_command =~ $is_destructive ]] && [[ $current_branch = $protected_branch ]]; then
  do_exit
fi

if [[ $push_command =~ $is_destructive ]] && [[ $push_command =~ $protected_branch ]]; then
  do_exit
fi

if [[ $push_command =~ $will_remove_protected_branch ]]; then
  do_exit
fi

unset do_exit

exit 0