-
-
Save vlucas/8009a5edadf8d0ff7430 to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# @link https://gist.github.com/mattscilipoti/8424018 | |
# | |
# 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. | |
# | |
# Steps to install, from the root directory of your repo... | |
# 1. Copy the file into your repo at `.git/hooks/pre-push` | |
# 2. Set executable permissions, run `chmod +x .git/hooks/pre-push` | |
# 3. Or, use `rake hooks:pre_push` to install | |
# | |
# Try a push to master, you should get a message `*** [Policy] Never push code directly to...` | |
# | |
# The commands below will not be allowed... | |
# `git push origin master` | |
# `git push --force origin master` | |
# `git push --delete origin master` | |
protected_branch='master' | |
policy="\n\n[Policy] Never push code directly to the "$protected_branch" branch! (Prevented with pre-push hook.)\n\n" | |
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,') | |
push_command=$(ps -ocommand= -p $PPID) | |
is_destructive='force|delete|\-f' | |
will_remove_protected_branch=':'$protected_branch | |
do_exit(){ | |
echo -e $policy | |
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 | |
# Prevent ALL pushes to protected_branch | |
if [[ $push_command =~ $protected_branch ]] || [ $current_branch = $protected_branch ]; then | |
do_exit | |
fi | |
unset do_exit | |
exit 0 |
How would you be able to do this via a pre-commit hook instead of a pre-push hook? I'm sort of thinking I'd rather not even let myself make commits to my master branch even if its on local. If I want to save my work it should be done (and committed) on my develop branch
[Edit: Now for example, I have a local repo that is separated from my remote repo, I want them to remain in sync completely]
@chrisdillenger you can add this as a pre-commit hook. via nvie/gitflow#330
branch=`git symbolic-ref HEAD`
if [ "$branch" = "refs/heads/master" ]; then
echo "Direct commits to the master branch are not allowed."
exit 1
fi
Not working for me on git for windows. It's giving an error on the following line:
push_command=$(ps -ocommand= -p $PPID)
Error message:
ps: unknown option -- o
Lots of dubious stuff here. current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
fails if the branch name contains a /
, the first two if
blocks are redundant since the condition checked by the fourth one encompasses them both, and the use of =~
for comparing with master
is dubious (since it'll match any branch name that contains the string master
, like balance/decrease-master-mind-flayer-spawn-rate
, not just master
itself).
I'm also not sure about the portability of that ps
incantation.
I simplified this because I just wanted to avoid me accidentally doing git push
when I'm on the master
branch and don't know I am (and it didn't work with Windows/MINGW64).
protected_branch='master'
policy="\n\n[Policy] Never push code directly to the "$protected_branch" branch! (Prevented with pre-push hook.)\n\n"
current_branch=$(git rev-parse --abbrev-ref HEAD)
do_exit(){
echo -e $policy
exit 1
}
if [ $current_branch = $protected_branch ]; then
do_exit
fi
unset do_exit
exit 0
With git 2.22+, you can do:
current_branch=$(git branch --show-current)
This script will prevent ALL pushes to the master branch. This
pre-push
hook enforces that all changes happen in a branch and then get merged into master with a pull request, etc.If you only want to prevent force and delete pushes, remove the last
if
statement.