:::: MENU ::::

Prevent Git history re-writes with denyNonFastForwards on GitHub & BitBucket

As you may know, I’m (still) in love with Git. One of the reasons is it’s power, but, occasionally, that power allows you to shoot the rest of your team in the chest. Or delete their commits and wipe them from history (which feels about the same).

You can do this by forcing your pushes upon other git servers, using git push -f. As #git IRC‘s resident bot says, this is a bad idea:

Rewriting public history is not recommended. Everyone who has pulled the old history have to do work (and you’ll have to tell them to), so it’s infinitely better to just move on. If you must, you can use `git push -f <remote> <branch>` to force (and the remote may reject that, anyway). See http://goo.gl/waqum

It continues:

[!force_push] If you need to overwrite the history of a remote git repository (very bad idea, see !rewrite), you can do so with `git push -f`.  Note the remote server may reject this.  See man git-config and search for receive.denyNonFastForwards.  Best practice is for upstream servers to denyNonFastForwards.

If you don’t want team members to be able to rewrite time and wipe away a combined team’s work at the same time, you can do as the computer tells you and configure NonFastForwards by executing the following on your git staging server:

git config receive.denyNonFastForwards true

That will tell the server to refuse receipt of commits that do not follow naturally from commits already received.

What if you don’t have access to the remote server directly however? Fear not, it’s still possible.


Thankfully this features was added in 2013, and you can configure it as administrator of a repository via the web interface.

  1. Log in
  2. Go to your repository URL (or click on the repository name). E.g. https://bitbucket.org/your-repo
  3. Click on “Settings” at the bottom of the left NavBar
  4. Click on “Branch Management”, under “Settings”, submenu “General”
  5. Find “Prevent history re-writes (rebase) on these branches”, type “master” into the field below it, and click “Add”


Although GitHub currently provides no public interface for this functionality, it is apparently possible by contacting GitHub support directly and asking for the option to be set.

Do you know how to set this using GitLab? Share your how-tos for other platforms in the comments.


So, what do you think ?