Is there a way to lock a branch in GIT
You can use pre-commit to do this. It has a built in no-commit-to-branch
hook that can be used to prevent commits to one or more branches.
Setup
The basic setup process is:
- Install using pip or brew (instructions at https://pre-commit.com/#install)
- Create a
.pre-commit-config.yaml
file in the root of your project (see below for a first draft) - Install the hooks into your git config by running
pre-commit install
.
Basic config for protecting branches
Here is a basic config that includes just the no-commit-to-branch
hook:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.2.5
hooks:
- id: no-commit-to-branch
args: ['--branch', 'master']
If you want to protect multiple branches you can use include multiple --branch
args in the argument list:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.2.5
hooks:
- id: no-commit-to-branch
args: ['--branch', 'master', '--branch', 'staging']
Isn't this all overkill?
Pre-commit has many other built-in hooks, and a large collection of community-built hooks that will transform the way you clean-up and validate your commits. The reason I mention this is because, while this tool may be overkill for just preventing commits to a protected branch, it has many other features that make it a compelling and simple addition to any git project.
The branch being pushed to is the first parameter to the update hook. If you want to lock the branch myfeature
for pushing, this code (placed in hooks/update
) will do it:
#!/bin/sh
# lock the myfeature branch for pushing
refname="$1"
if [[ $refname == "refs/heads/myfeature" ]]
then
echo "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
echo "You cannot push to myfeature! It's locked"
echo "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
exit 1
fi
exit 0
The update hook, from the docs:
The hook executes once for each ref to be updated, and takes three parameters:
- the name of the ref being updated,
- the old object name stored in the ref,
- and the new objectname to be stored in the ref.
So... yes, it knows exactly what branch is being pushed, and can simply check that parameter and exit failure if it doesn't want the branch pushed to.
And if you want to (intelligently) do this before the user has uploaded the objects, you can use the pre-receive hook:
This hook executes once for the receive operation. It takes no arguments, but for each ref to be updated it receives on standard input a line of the format:
<old-value>
SP<new-value>
SP<ref-name>
LFwhere
<old-value>
is the old object name stored in the ref,<new-value>
is the new object name to be stored in the ref and<ref-name>
is the full name of the ref.
(those are spaces and line-feed)
A tool like gitolite has this kind of feature I believe: http://github.com/sitaramc/gitolite