Git non-fast-forward rejected

GitVersion Control

Git Problem Overview


I feel like this question has been asked many times, but the solution is typically "I deleted the directory and re-did my work with a fresh checkout." I did a commit and push but realized that I referred to the wrong ticket number in the commit message. So I looked on SO for a quick solution and ended up typing the following into the terminal:

$ git reset --soft HEAD^
$ git commit -m "... correct message ..."

The only problem is I am getting the following error message:

To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.

I am using the git-flow model and am working on the develop branch. How can I merge things back in to make git happy again?

Git Solutions


Solution 1 - Git

If you push a commit to the server, and then rewrite that commit locally (with git reset, git rebase, git filter-branch, or any other history manipulation), and then pushed that rewritten commit back up to the server, you will screw up anyone else who had pulled. Here's an example; say you have committed A, and pushed it to the server.

---A <-- master

---A <-- origin/master

Now you decide to rewrite A, in the way you mentioned, resetting and re-committing. Note that this leaves a dangling commit, A, which will eventually be garbage collected as it is not reachable.

---A

A' <-- master

---A <-- origin/master

If someone else, let's say Fred, pulls down master from the server while you're doing this, they will have a reference to A, which they might start working from:

---A' <-- master

---A <-- origin/master

---A-B <-- fred/master

Now if you were able to push your A' to origin/master, which would create a non-fast-forward, it wouldn't have A in its history. So if Fred tried to pull again, he'd suddenly have to merge, and would re-introduce the A commit:

---A' <-- master

---A <-- origin/master

---A-B-\ \ * <-- fred/master A'--/

If Fred happens to notice this, then he could do a rebase, which would prevent commit A from reappearing again. But he'd have to notice this, and remember to do this; and if you have more than one person who pulled A down, they would all have to rebase in order to avoid getting the extra A commit in the tree.

So, it's generally not a good idea to change history on a repo that other people pull from. If, however, you happen to know that no one else is pulling from that repo (for instance, it's your own private repo, or you only have one other developer working on the project who you can coordinate with easily), then you can forcibly update by running:

git push -f

or

git push origin +master

These will both ignore the check for a non-fast-forward push, and update what's on the server to your new A' revision, abandoning the A revision so it will eventually be garbage collected.

It's possible that force pushes are entirely disabled with the receive.denyNonFastForwards config option. This option is enabled by default on shared repositories. In that case, if you really, really want to force a push, the best option is to delete the branch and re-create it, with git push origin :master; git push origin master:master. However, the denyNonFastForwards option is enabled for a reason, which is described above; on a shared repository, it means that now everyone who uses it needs to ensure that they rebase onto the new history.

On a shared repository, it is generally better to just push new commits on top that fix whatever problem you have; you can use git revert to generate commits that will undo the changes of previous commits.

Solution 2 - Git

Force git push:

git push origin +develop

Solution 3 - Git

You might have to do a git pull, which MAY auto merge stuff for you. Then you can commit again. If you have conflicts, it'll prompt you to resolve them.

Keep in mind, you have to specify which branch to pull from if you haven't updated your gitconfig to specify...

For example:

git pull origin develop:develop

Solution 4 - Git

I was using EGit and I faced this issue also. Just tried to rebase the current branch and It worked.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrynmrtnView Question on Stackoverflow
Solution 1 - GitBrian CampbellView Answer on Stackoverflow
Solution 2 - GitAlan Haggai AlaviView Answer on Stackoverflow
Solution 3 - GitTonyView Answer on Stackoverflow
Solution 4 - GitNguyen Minh BinhView Answer on Stackoverflow