56

I'm trying to figure out a good way to prevent developers from force pushing master with Git. We used GitHub to host our remote repositories so a pre-receive hook isn't an option. Any other solutions that could easily be implemented for a team of developers?

As a side note, I don't want to disable force pushing in general. Sometimes it is a necessary evil. But that said, force pushing on master cannot happen.

Arturo Herrero
  • 12,772
  • 11
  • 42
  • 73
Swift
  • 13,118
  • 5
  • 56
  • 80
  • 2
    Related question: [github - prevent colaborator from push -f](http://stackoverflow.com/questions/5094524/github-prevent-colaborator-from-push-f). –  Jun 07 '13 at 19:56
  • 2
    It is possible to disable force push on the entire repo by contacting GitHub support. – Keith Smiley Jun 18 '14 at 02:51

7 Answers7

72

Update

Github has since introduced the concept of protected branches. It can be found under Settings -> Branches -> Protected Branches

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/

You cannot prevent this in Github.

What you can do is have an intermediate repo on your side, run a pre-receive hook in that to prevent force push and push from this intermediate repo to github and block access for direct push to github. Yeah this is not elegant and you lose lots of features with Github, but I don't see any other way.

Edit: Just came across this answer, which says the same and gives another workaround: GitHub - prevent collaborators from using push -f

Community
  • 1
  • 1
manojlds
  • 290,304
  • 63
  • 469
  • 417
  • 2
    It is possible at GitHub enterprise: https://enterprise.github.com/help/articles/blocking-force-pushes-for-a-user-account – Vladislav Rastrusny Oct 28 '14 at 09:31
  • 2
    [Github recently added a feature for this!](https://github.com/blog/2051-protected-branches-and-required-status-checks) – Jostein Oct 01 '15 at 11:07
  • Given the "protected branches" bit had been part of other answers for years before the introducing edit, you may want to consider giving credit to other authors as well. – Thorbjørn Ravn Andersen Feb 20 '19 at 13:38
  • Once a branch is protected this way, how does an *admin* can force push something? – Vadorequest Aug 26 '19 at 12:35
  • 2
    As it is for now ***"Protected branches are available to Pro, Team, and Enterprise users"*** only. – Lukasz Dynowski Oct 23 '21 at 15:24
  • @LukaszDynowski I have a usual github account, and I protected my master branch from force-push without a problem. The algorithm is: go the page mentioned in the answer, click `Add branch protection rule`, then fill out branch name the rule is for. Then you completely ignore all the ✓-boxes and create a rule with all of them unchecked. That's it. There's no checkbox for force-push protection, but creating the rule will make protection just work, unless you explicitly opted out of the protection *(there's a checkbox for that)*. – Hi-Angel Sep 03 '22 at 22:04
  • Follow-up question I need an answer to: [How to prevent force-pushing to a GitHub Wiki repo?](https://stackoverflow.com/q/74106286/4561887) – Gabriel Staples Oct 18 '22 at 05:56
14

GitHub introduced a new feature called "Protected Branches" to prevent force pushing. You can configure it in repository Settings > Branches.

github protected branches

Lukasz Wiktor
  • 19,644
  • 5
  • 69
  • 82
9

I'm not a github expert, but I believe you can do this if you use github Organizations.

You would need to create an Organization "Pull Only" Team for the developers who aren't allowed to push to master. Instead of working on the main repo, they would fork your main repo and set their local repos to sync with their fork repos. Anytime they want to push code to the main repo, they would have to push their code onto their fork and submit a Pull Request instead.

This is where you create another Organization "Push & Pull" Team for developers which can review and approve the pull requests, and merge them into your main repo.

Basically every developer is only pushing to their own fork, and nobody can push to the main repo directly (except the Team with both Push/Pull access). For a push to happen on the main repo, it must always go through a pull request from a fork repo.

triad
  • 20,407
  • 13
  • 45
  • 50
5

[UPDATE] Github now provides "protected branches" feature just for this purpose.

Easy-peasy: Get Github "Enterprise" installation, then follow instructions below: https://help.github.com/enterprise/2.1/admin/articles/blocking-force-pushes-to-a-repository/

Disclaimer: this was a tounge-in-cheek answer. Drop a line at https://github.com/contact and maybe Github folk will hear us and enable this option for the masses.

Wojtek Kruszewski
  • 13,940
  • 6
  • 38
  • 38
  • Your link: "Moved to https://enterprise.github.com/help/articles/disable-force-pushes" https://enterprise.github.com/help/articles/disable-force-pushes: "Whoops, looks like that page doesn't exist." – Ben Regenspan May 23 '14 at 16:40
2

In the case of GitHub specifically, it is possible to block force pushes, but it is not possible to make this change on your own. You'll have to contact support ( support@github.com, https://github.com/contact ) to make the change on repositories you specify.

VxJasonxV
  • 951
  • 11
  • 35
1

Well if you don't want to change the branch protection, or you might have some group in git that is allow to push to master, I think is better to have a documentation on how to configure github to your Team members in their machines with this command, and telling them the purpose of the commands.

Supposing that they have forked the repo, add the main repo remote + disallow push to master.

git remote add upstream git@github.com:username/project.git
git remote set-url --push upstream no_push

is an easy and nice way to prevent it

0

Let me define those steps in a most simple way:

  1. Goto your repository & click on the Settings:

enter image description here

  1. Next goto Branches section & click on Add button:

enter image description here

  1. Ok, good, we are in the last step now. You need to do these:

    • Fill in the branch name as master.
      Note: here, you can set any branch name you want to protect. For example, if you want to protect the develop branch, write develop.
    • Check two options "Lock branch" and "Do not allow bypassing the above settings."

enter image description here

  1. Now test it:
git push origin main --force

You should get the following message ➪

enter image description here


Check the official documentation here for more information about branch protection policies.

Arsen Khachaturyan
  • 7,904
  • 4
  • 42
  • 42