non-fast-forward updates were rejected

Git push rejected: non-fast-forward updates fix

Programming & Dev Tools Intermediate 👁 1 views 📅 May 27, 2026

Your local branch is behind the remote. You need to pull or rebase before pushing. Here's the quick answer and the real fix.

Quick answer (for advanced users)

git pull --rebase origin <branch> then git push origin <branch>. If that fails, git pull origin <branch> — resolve conflicts — then push.

Why this happens

You're trying to push commits to a remote branch that has newer commits you don't have locally. Git rejects the push because your local history doesn't fast-forward — meaning you can't just add your commits on top. Someone else pushed first, or you forgot to pull before you started working. I see this daily with devs who stash changes and switch branches, then push from an old state. Had a client last week who lost an hour because they force-pushed and wiped a teammate's work. Don't be that guy.

Step-by-step fix

  1. Check your branch: git status — make sure you're on the right branch. If you're on main and meant to push feature-x, switch first.
  2. Fetch the latest remote: git fetch origin — this gets all remote changes without merging. See what you're missing.
  3. Rebase your work on top of remote: git rebase origin/<branch> — this replays your commits after the remote ones. If you get conflicts, resolve them with git mergetool or manually edit files, then git rebase --continue. No conflicts? You're golden.
  4. Push again: git push origin <branch> — should go through now. If it still says non-fast-forward, run git pull origin <branch> to merge instead of rebase, then push.

Alternative fixes (if rebase fails)

  • Merge instead: git pull origin <branch> — this will create a merge commit. It's uglier than rebase but works when you're in a hurry. Resolve conflicts if they pop up, commit, then push.
  • Force push with lease (last resort): git push --force-with-lease origin <branch> — this overwrites the remote with your local history but only if no one else pushed since your last fetch. Safer than --force, but still risky if you're on a shared branch. Never use --force unless you're the only person on that branch and you know exactly what you're doing.

Prevention tip

Before you start working on any branch, always pull first: git pull origin <branch>. If you're working on a feature branch alone, this is less critical. On shared branches like main or develop, always pull before pushing. Also, use git fetch frequently to see if the remote has moved. A simple git log --oneline origin/<branch>..HEAD shows you what commits you have that the remote doesn't. If that list is empty, you haven't made progress — or you're behind.

True story: a dev I worked with force-pushed his local branch without pulling first. He overwrote his coworker's two days of work. Git recovered it via reflog, but the panic was real. Don't learn that lesson the hard way.

Was this solution helpful?