51

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.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
Czlowiekwidmo
  • 1,105
  • 2
  • 10
  • 12

3 Answers3

52

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

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
7

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.

hakeris1010
  • 285
  • 1
  • 5
  • 12
4

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
adamk
  • 45,184
  • 7
  • 50
  • 57
Thomas Koch
  • 2,833
  • 2
  • 28
  • 36