DevFixes
HomeGitVersion control
GitBeginnerMedium severity

Git push rejected: non-fast-forward

The remote branch contains commits that are not present in your local branch.

5-15 min Popularity 91/100 Verified 2026-07-21
Debug with AI

What does this error mean?

Git refused to move the remote branch pointer because doing so would ignore commits that already exist on the remote.

Why does this happen?

  • Someone pushed to the same branch after your last pull.
  • You rewrote local history with rebase or amend.
  • Your local branch tracks the wrong remote branch.
  • A remote automation committed to the branch.

AI explanation

Plain-English analysis

Your branch and the remote branch have diverged. Git stops the push because it cannot safely assume whether remote commits should be merged, rebased, or replaced.

Quick fix

Terminal
git fetch origin
git pull --rebase origin main
git push origin main
Expected output: The local commits are replayed on top of the remote branch and the push succeeds.

Step-by-step fix

1Rebase onto the remote branchBest for a clean linear history when your local commits have not been shared.78%
Command
git pull --rebase origin main
git push origin main
2Merge the remote branchPreserve both histories with a merge commit.56%
Command
git pull --no-rebase origin main
git push origin main
3Force with lease after an intentional rewriteUse only when you intentionally rebased shared history and understand which commits will be replaced.18%
Command
git push --force-with-lease origin main

Alternative solutions

Feature branch

git fetch origin
git rebase origin/main

Resolve conflicts, continue the rebase, then push.

Shared branch

git pull --no-rebase

Merging is often safer when multiple developers share the branch.

Real example

Broken
shell
$ git push origin main
! [rejected] main -> main (non-fast-forward)
Corrected
shell
$ git pull --rebase origin main
Successfully rebased and updated refs/heads/main.
$ git push origin main

Frequently asked questions

Avoid plain force on shared branches. `--force-with-lease` adds a safety check, but it can still replace remote history.

References