107

Our remote master branch somehow got messed up. Current development code is on the master branch along with the latest commits. Obviously, the development code is not ready for the master branch.

So on my local repository, I did a reset to the latest tag, git reset --hard (Tag). The master branch is now correct on my local repository. Now when I try to push the changes on to the remote repository, git push origin master, I get an error:

To (REMOTE GIT REPOSITORY LOCATION)
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

So after looking around I found out the --force option. So I did a force push on to the remote repository, git push --force origin master, and I still got an error:

Total 0 (delta 0), reused 0 (delta 0)
remote: error: denying non-fast-forward refs/heads/master (you should pull first)
To (REMOTE GIT REPOSITORY LOCATION)
 ! [remote rejected] master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'

I can't do a pull on master, because it contains development code which can't be on master.

samwell
  • 2,757
  • 9
  • 33
  • 48
  • 4
    I think the message means that you don't have the rights to do a non-fast-forward push. – svick May 11 '12 at 01:22
  • 5
    You were correct, thanks. In the config file for the repository on remote, `denyNonFastforwards = true`. I changed it to false, pushed my changes and then changed it back to true. Thanks again everyone, for the help. – samwell May 11 '12 at 01:33
  • 2
    @samwell please mark svick's answer as accepted – hultqvist Apr 05 '13 at 09:39
  • @samwell did svick's answer work for you or not? – Songo Sep 22 '14 at 14:57
  • 1
    For those who need details on how to disable denyNonFastForwards like samwell did, more instructions can be found here: stackoverflow.com/a/43721579/2073804 – ron190 May 01 '17 at 23:18

10 Answers10

161

The message means that you're not allowed to do non-fast-forward push.

Your remote repository has most likely denyNonFastforwards = true in its config. If you change that, git push --force should work.

To change the setting, you need access to the machine with the remote repository. From there, do git config receive.denynonfastforwards false.

moodboom
  • 6,225
  • 2
  • 41
  • 45
svick
  • 236,525
  • 50
  • 385
  • 514
  • 2
    Can you do a `git config` for a server? Or perhaps you were using that metaphorically. To play with these ideas I created a test repo in `/opt/git` (my git server space) and then I modified this setting in `/opt/git/the_repo/the_repo.git/config`. But once done the `git push --force origin SHA:branch` worked as required. – HankCa Jul 18 '15 at 13:35
  • 4
    The error message will have a line that starts with "error: failed to push some refs to " where is path ending in .git which is a directory containing a file called "config". This "config" file is where you can set denyNonFastforwards = false – emery Mar 25 '16 at 20:16
  • @emery but if someone do not have access to the server? – TonySalimi Sep 14 '16 at 14:38
  • 1
    @emery's comment is valuable. Sometimes the folder on the server will have its origin set to something like /srv/git/repo.git. This is the config that has denyNonFastForwards set, not the application folder. – Elijah Lynn Apr 18 '17 at 15:58
  • 1
    @hsalimi If you don't have access to the server then you need to contact the server admin and have them temporarily turn it off so you can force push and then turn it back on. It is unlikely most are in a position to do this though. It may be more common in an internal environment with your own hosting team. – Elijah Lynn Apr 18 '17 at 16:11
  • The key here is to check the config in the _**remote**_ repository, not the local repository. – Simon Elms Oct 27 '17 at 02:41
  • 2
    This is initially frustrating, but the beauty of it is: the remote is totally protected by default, and if you as the developer are intentionally and correctly doing rebases, you can override this config to allow the dangerous behavior. Rebasing is something every git user should know how to do - and know when not to do. [doc1](https://git-scm.com/book/id/v2/Git-Branching-Rebasing) [doc2](https://www.atlassian.com/git/tutorials/merging-vs-rebasing) – moodboom Dec 01 '17 at 13:16
  • Since nobody mentioned it so far I would like to write when `denynonfastforwards` is enabled on behind. In my case it is due to command `git init --bare --shared=...`. So when --shared option is used within init command denynonfastforwards is set to true (it is also mentioned in doc: https://git-scm.com/docs/git-init). In my case I use mirroring of repo as-is so I want to force override it. – mikep Jul 25 '19 at 16:50
  • This flag has some annoying effect on commit-with-amend feature. If you use the commit-with-amend is too frequently, then you have to turn the feature off, otherwise you have to go to the remove repository each time you want to amend the last commit. – Andry Feb 24 '23 at 21:38
17

The remote doesn't allow non-fast-forwards.

Your best option is to git revert all of the commits that shouldn't be there and be more careful in future.

git revert [commit] will create a new commit that undoes whatever [commit] did.

richo
  • 8,717
  • 3
  • 29
  • 47
  • It was some settings on the remote repository that blocked all non-fast-forward changes. – samwell May 11 '12 at 01:39
  • If you do this and need to reapply commits the history isn't removed in a revert just the code changes, and you won't be able to cherry pick the commits or merge – mtpultz Jul 11 '18 at 20:22
13

Try using the -f flag and putting it after the remote branch name.

git push origin master -f

Chris Ledet
  • 11,458
  • 7
  • 39
  • 47
  • 3
    Nope, that didn't work either. I also tried `git push -f origin master` and same result. Both times I tried it I got the second version of the error message. – samwell May 11 '12 at 01:20
13

Steps to permanently enable force push in the following style

git push -f myrepo my-branch

Edit the file named "config" in the folder ending in ".git" on your remote repository

In git's command-line output from the failed push, look for the line that says something like:

error: failed to push some refs to 'ssh://user@some-remote-server.mycompany.com/srv/git/myrepo.git

then

ssh user@some-remote-server.mycompany.com
cd /srv/git/myrepo.git
vi config

Set "denyNonFastforwards" to false

In "config", set

[receive]
        denyNonFastforwards = false

Now you can push from your local machine with -f

git push -f myrepo my-branch
emery
  • 8,603
  • 10
  • 44
  • 51
  • How to do this without access to SSH to bare git repo? – Vladimir Vukanac Jun 28 '16 at 13:44
  • Maybe use the git revert command as richo suggests? If you back up the current state of the repo first, you can still merge your code in moving forward. – emery Jun 29 '16 at 07:42
  • `git revert` is kind of complicated when you have merges. To be more complicated my case has 3 merge, of which one is with very old ~20 commit diverged from develop, 2nd is kind of merge from master - ugly as hell. – Vladimir Vukanac Jun 29 '16 at 22:15
  • 1
    Maybe the solution is to reset to desired state, backup (stash), pull again, and apply backup (stash). – Vladimir Vukanac Jun 29 '16 at 22:19
  • 1
    mrW you can still merge the code base you want on top of a reverted/pulled code base – emery Jun 30 '16 at 15:41
3

The best way around this is to delete the remote branch and re-send it:

git push origin master --delete
git push origin master
Danilo Souza Morães
  • 1,481
  • 13
  • 18
  • the first command will fail with `! [remote rejected] master (deletion of the current branch prohibited)` – raven Jan 27 '23 at 09:49
2

You're not allowed to do git push that is not fast-forward.

  1. If the remote is GitHub, go to https://github.com/$USER/$REPO/settings/branches and un-protect the branch in question.

    enter image description here

    You have to be admin of the repo to do that.

  2. If the remote is your own git server, run git config receive.denynonfastforwards false there.

filiph
  • 2,673
  • 2
  • 26
  • 33
  • Be aware that for Git Hub Enterprise instances, pushes to the default branch (usually "master") can be disabled at the instance-level. This means that even if "master" is not protected, and even if you are a site-admin, you will not be able to do force-pushes to the default branch. Assuming you have permissions, you can temporarily get around this by switching the default branch to something else, doing your force-push, and then switching back. – Christopher Hunter Nov 08 '17 at 21:06
1

For me, @svick 's hint pointed in the right direction. Since the git server I wanted to modify is actually my box, I logged into it and did a git config --global receive.denynonfastforwards false to change all repos to accept a forced non-ff push. Didn't work out of the box. What I found was that in the config there already was receive.denynonfastforwards=true set, and it couldn't be erased with git config --global --unset receive.denynonfastforwards. Doing the edit in the repo manually (vi config) worked, though.

jglathe
  • 156
  • 3
  • 7
0

The problem occurs as the current branch isn't configured properly for the PULL. First check whether the upstream branch is properly configured for the pull using - git remote show origin. You can find it under the section - Local branches configured for 'git pull':. If not, configure it using:

git config branch.MYBRANCH.merge refs/heads/MYBRANCH

Give appropriate branch name for the place holder - MYBRANCH

Sudheesh.M.S
  • 498
  • 1
  • 7
  • 13
0

I'm using this group of commands to reset my remote repo, this will re-initialize your local repo and relink with your remote repo then force push the updates.

I think this way won't work in your case, but may be useful for someone else

go to the source folder then run the commands : note that https://github.com/*.git is your remote repo link

git init
git remote add origin https://github.com/*.git
git add .
git commit -m "initial commit"
git push origin master -f
git push --set-upstream origin master

**Note: this will clear all your git history on your master branch**

Khaled AbuShqear
  • 1,230
  • 14
  • 24
0

I solved by removing the master branch from protected and also default which is just over proted branch rules in setting of a repository.

10raw
  • 506
  • 12
  • 26