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.
-
2Related question: github - prevent colaborator from push -f.user456814– user4568142013年06月07日 19:56:07 +00:00Commented Jun 7, 2013 at 19:56
-
3It is possible to disable force push on the entire repo by contacting GitHub support.Keith Smiley– Keith Smiley2014年06月18日 02:51:26 +00:00Commented Jun 18, 2014 at 2:51
7 Answers 7
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 (削除ここまで)
7 Comments
GitHub introduced a new feature called "Protected Branches" to prevent force pushing. You can configure it in repository Settings> Branches.
Comments
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.
Comments
[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.
1 Comment
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 ( [email protected], https://github.com/contact ) to make the change on repositories you specify.
Comments
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 [email protected]:username/project.git
git remote set-url --push upstream no_push
is an easy and nice way to prevent it
Comments
Let me define those steps in a most simple way:
- Goto your repository & click on the Settings:
- Next goto Branches section & click on Add button:
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 thedevelopbranch, writedevelop. - Check two options "Lock branch" and "Do not allow bypassing the above settings."
- Fill in the branch name as
- Now test it:
git push origin main --force
You should get the following message ➪
Check the official documentation here for more information about branch protection policies.