Prevent commits to the local git master branch
I’ve been a fan of Yelps pre-commit git hook manager ever since I started using it to Prevent AWS credential leaks. After a recent near miss involving a push to master I decided to take another look and see if it could provide a safety net that would only allow commits on non-master branches. It turns out it can, and it’s actually quite simple to enable if you follow the instructions below.
Firstly we’ll install pre-commit globally.
pip install pre-commit
Before we enable the plugin we’ll make a commit to an unprotected local
master
branch to ensure everything’s working the way we think it is.
# confirm we're on master
$ git branch
* master
# create a local change we can work with
$ echo "Text" >> text
$ git add text
# successfully commit the change
$ git commit -v -m "Add text"
[master e1b84e5] Add text
1 file changed, 1 insertion(+)
create mode 100644 text
Now we’ve confirmed we can commit to master
normally we’ll add the pre-commit
config to prevent it.
$ cat .pre-commit-config.yaml
- repo: https://github.com/pre-commit/pre-commit-hooks.git
sha: v0.9.5
hooks:
- id: no-commit-to-branch
and then we activate the config.
$ pre-commit install
pre-commit installed at ~/protected-branch-test/.git/hooks/pre-commit
If anything fails then you’ll probably need to read through ~/.pre-commit/pre- commit.log
to find the issue. Now we’ve installed the pre-commit
pip,
added its config, and then enabled it we should be protected. No more
accidental committing to the master branch for us! But let’s verify.
# make a change to the checkout
echo "More text" >> text
git commit -m "Added more text"
... snip ...
Don't commit to branch.............Failed
... snip ...
# and the change is not committed.
By default this plugin protects the master
branch. If you have other
branches you want to deny commits on you can add the args
key to the
config as shown in this snippet.
hooks:
- id: no-commit-to-branch
args:
- --branch=release
If you need to commit to master while this plugin is enabled you
can use the --no-verify
argument to git commit
to disable all
pre-commit hooks.
It’s worth noting you can also prevent inadvertent pushes to master at the remote end by enabling branch protection on a number of the popular git providers, both GitHub and BitBucket support this. This approach has the advantage of not needing client side configuration but does require that all your providers support it, and that you actually enable it on each of them and their repositories. While you can of course do that by hand there are also a few tools that will manage this for you, but that’s a something for a different post.