DEV Community

Michael Kochell
Michael Kochell

Posted on • Updated on

How to avoid pushing to branches that are not protected (that should be)

Git hooks are used to run some arbitrary code before and after different git operations. The ones that begin with pre- are used before the operation, and can be used to bail out of the operation. post- hooks are run after an operation, but do not have built-in functionality revert the operation itself.

We're going to use pre-commit and pre-push hooks to make sure we never accidentally commit/push to an un-protected master branch. It is only going to affect our own local copies of the repositories. You will need git 2.9+ (June 2016). The script we will create will ask you if you want to commit/push to master, so you will still be able to if that's your intention.

Make a place to house your global hooks.

mkdir ~/.githooks
Enter fullscreen mode Exit fullscreen mode

Create a file called pre-commit in this directory.

#!/bin/bash

protected_branch='master'
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')

if [ $protected_branch = $current_branch ]
then
    read -p "You're about to commit to $protected_branch, is this what you intended? [y|n] " -n 1 -r < /dev/tty
    echo
    if echo $REPLY | grep -E '^[Yy]$' > /dev/null
    then
        exit 0 # push will execute
    fi
    exit 1 # push will not execute
else
    exit 0 # push will execute
fi

Enter fullscreen mode Exit fullscreen mode

We should also make a pre-push hook. To do this, copy the pre-commit file to a new file pre-push, and change to the prompt to say "push" instead of "commit". pre-commit is arguably more important and sort of renders pre-push useless. You can never be too careful though.

Set the files to be executable:

chmod a+x ~/.githooks/pre-commit
chmod a+x ~/.githooks/pre-push
Enter fullscreen mode Exit fullscreen mode

Set your global hooks folder to be recognized by git:

git config --global core.hooksPath ~/.githooks
Enter fullscreen mode Exit fullscreen mode

Now if you try to commit or push to master on any repo on your machine, the hook will ask you to make sure you want to do that.

If you want to apply this on a per project basis, then you will need to add the pre-push and pre-commit files to the project's .git/hooks folder instead of a global hooks folder.

Discussion (0)