Elegant solution to prevent force push on master only
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
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.
[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.
GitHub introduced a new feature called "Protected Branches" to prevent force pushing. You can configure it in repository Settings > Branches.