Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
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.
# Global installation instructions:
# mkdir $HOME/.githooks
# git config --global core.hooksPath $HOME/.githooks
# curl -fL -o $HOME/.githooks/pre-push https://gist.githubusercontent.com/stefansundin/d465f1e331fc5c632088/raw/pre-push
# chmod +x $HOME/.githooks/pre-push
# Uninstall:
# rm $HOME/.githooks/pre-push
# Single repo installation:
# curl -fL https://gist.githubusercontent.com/stefansundin/d465f1e331fc5c632088/raw/install-pre-push.sh | sh
# Uninstall:
# rm .git/hooks/pre-push
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
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."
echo
exit 1
fi
exit 0
dlin-me commented Nov 20, 2014

Thanks

bean5 commented Dec 17, 2014

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

centerge commented Jan 6, 2015

thanks for this!

brange commented Jun 26, 2015

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

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.

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.

Owner

I just updated the instructions above to include instructions for a global installation using the core.hooksPath configuration option introduced in Git 2.9. Update to that and you no longer have to install this in every git repository, just do it once.

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