I was wondering is there a way to prevent 'git push --force
' on a repository (only on master branch)?
Assume I have remote git repository and do:
git push
' to 'master'. It works.git push --force
' to 'branch-1'. It works.git push --force
' to 'master'. It is rejected.Is it even possible?
Thanks for any answers and suggestions.
BR, Dawid.
If you have the appropriate permissions on your "central" git repository, you can disable force push by git config --system receive. denyNonFastForwards true . For Github Enterprise, you can follow instructions on this page to disable force push.
To find it go to Settings > Branches > Branch Protection Rules and click 'Add Rule'. Then, enter the name of the branch you want to protect and click the checkbox to require pull request reviews before merging.
Git's push --force is destructive because it unconditionally overwrites the remote repository with whatever you have locally, possibly overwriting any changes that a team member has pushed in the meantime.
Setting the configuration variables:
receive.denyNonFastForwards receive.denyDeletes
will prevent any 'forced' pushes from working across all branches.
If you want finer pre-branch control then you will have to use a 'hook' on the remote repository, probably the 'update' hook.
There is a sample update hook called 'update-paranoid' that probably does what you need (and more) in the git distribution in the 'contrib' folder.
gitweb link
Github has already introduced the concept of protected branches!
It can be found under Settings -> Branches -> Protected Branches
. Feature is now available for all users - not only enterprise!
This "protection" can be enabled for any branch, and for any user, including admins.
More details here - https://help.github.com/articles/defining-the-mergeability-of-pull-requests/
So no more hooks and arbitrary code is needed.
I wrote this quick update hook to prevent non-fast-forward updates (pushes) on the "dev" branch in a repository:
#!/bin/sh
REFNAME=$1
OLDSHA=$2
NEWSHA=$3
if [ "refs/heads/dev" != $REFNAME ]; then
exit 0
fi
MERGEBASE=$(git merge-base $OLDSHA $NEWSHA)
if [ $OLDSHA = $MERGEBASE ]; then
exit 0
fi
echo "Not a fast-forward on branch dev"
exit 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With