Create a gist now

Instantly share code, notes, and snippets.

Git pre-push hook to prevent force pushing the master branch.
#!/bin/sh
# This script will install a Git pre-push hook that prevents force pushing the master branch.
# Install in current Git repo:
# curl -fL https://gist.githubusercontent.com/stefansundin/d465f1e331fc5c632088/raw/install-pre-push.sh | sh
# Uninstall:
# rm .git/hooks/pre-push
# in each repository that you've added this to.
GITROOT=`git rev-parse --show-toplevel 2> /dev/null`
echo
echo
if [ "$GITROOT" == "" ]; then
echo This does not appear to be a git repo.
exit 1
fi
if [ -f "$GITROOT/.git/hooks/pre-push" ]; then
echo There is already a pre-push hook installed. Delete it first.
echo
echo " rm '$GITROOT/.git/hooks/pre-push'"
echo
exit 2
fi
echo Downloading pre-push hook from https://gist.github.com/stefansundin/d465f1e331fc5c632088
echo
curl -fL -o "$GITROOT/.git/hooks/pre-push" "https://gist.githubusercontent.com/stefansundin/d465f1e331fc5c632088/raw/pre-push"
if [ ! -f "$GITROOT/.git/hooks/pre-push" ]; then
echo Error downloading pre-push script!
exit 3
fi
chmod +x "$GITROOT/.git/hooks/pre-push"
echo "You're all set! Happy hacking!"
exit 0
#!/bin/bash
# Prevents force-pushing to master.
# Based on: https://gist.github.com/pixelhandler/5718585
# Install:
# cd path/to/git/repo
# curl -fL -o .git/hooks/pre-push https://gist.githubusercontent.com/stefansundin/d465f1e331fc5c632088/raw/pre-push
# chmod +x .git/hooks/pre-push
BRANCH=`git rev-parse --abbrev-ref HEAD`
PUSH_COMMAND=`ps -ocommand= -p $PPID`
if [[ "$BRANCH" == "master" && "$PUSH_COMMAND" =~ force|delete|-f ]]; then
echo "Prevented force-push to $BRANCH. This is a very dangerous command."
echo "If you really want to do this, use --no-verify to bypass this pre-push hook."
exit 1
fi
exit 0
@dlin-me
dlin-me commented Nov 20, 2014

Thanks

@bean5
bean5 commented Dec 17, 2014

Nice. You reference this page in the file itself. Handy.

@centerge
centerge commented Jan 6, 2015

thanks for this!

@brange
brange commented Jun 26, 2015

I changed the $PUSH_COMMAND comparison to =~ force|delete|-f|"+master" to prevent git push origin +master

@rajah1313

is there a way to have this hook available on a new clone of the repository ? so basically it is somehow installed on the server and then gets installed on the client side with a clone. the idea being to stop accidental checkin to master for e.g.

@stefansundin
Owner

@rajah1313 Not from the server to a client, but you can change your default git hooks that are created when you clone a repository, and include this hook there. See this thread for details: http://stackoverflow.com/questions/1977610/change-default-git-hooks

If you have control over the server, you can install a git hook there to prevent force pushes etc. GitHub also has protected branches these days, which didn't exist when I created this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment