Introduction
This error means the remote branch already contains commits your local branch does not have. On an unprotected branch you might overwrite history with a force push, but protected branches in GitHub, GitLab, and Azure DevOps correctly block that path. The fix is to integrate the remote commits first, then push a fast-forward result.
Symptoms
git pushfails withnon-fast-forwardorfailed to push some refs- A follow-up
git push --forceis rejected by branch protection - The problem starts after another engineer pushed to the same branch or after you amended or rebased local commits
- CI or pull request checks still point to the remote branch while your local branch history has diverged
Common Causes
- Someone pushed new commits to the remote branch before you pushed yours
- You rewrote local history with
git commit --amendorgit rebaseafter an earlier push - Multiple engineers are pushing to the same shared feature branch
- You are pushing directly to a protected integration branch that only allows pull requests
Step-by-Step Fix
- 1.Inspect how far your branch diverged
- 2.Confirm whether you only need to replay your local commits or whether the branch now has unrelated remote work you must review first.
git fetch origin
git status
git log --oneline --graph --decorate HEAD..origin/feature-branch
git log --oneline --graph --decorate origin/feature-branch..HEAD- 1.Rebase onto the remote branch if your local commits should stay on top
- 2.This is the usual fix for a personal feature branch or a branch where your commits should remain linear after newer remote work.
git fetch origin
git rebase origin/feature-branch
git push origin feature-branch- 1.Use a merge if the branch is shared and you want the safest reconciliation
- 2.A merge commit avoids rewriting local commit hashes again and is often easier when several people are already collaborating on the same branch.
git fetch origin
git merge origin/feature-branch
git push origin feature-branch- 1.Switch to a pull request flow if direct pushes are intentionally blocked
- 2.If the remote platform rejects all direct updates to the target branch, push your fixes to a separate branch and merge through review instead of fighting branch protection.
git switch -c fix/non-fast-forward-recovery
git push -u origin fix/non-fast-forward-recoveryPrevention
- Run
git fetch originbefore starting a rebase, amend, or release push on shared branches - Prefer short-lived feature branches over long-lived shared branches with many direct pushes
- Use pull requests for protected branches instead of planning around force pushes
- If history rewriting is allowed on a branch, use
git push --force-with-leaserather than plain--force