git push rejected non-fast-forward: decision path for safe recovery (2026)
Fix It With a Tool
Compare local vs remote changes before choosing a recovery path
Use Git Diff Viewer to check exactly what changed before rebasing, merging, or correcting target branch selection.
When git push is rejected with non-fast-forward, the safest fix depends on the failure state. Use this decision path to avoid accidental history overwrite.
Decision path
1. Behind remote
Use this path when remote moved ahead and your local branch has no unique commits that need preservation.
# inspect current branch and upstream
git status -sb
git branch -vv
# sync remote refs
git fetch origin
# confirm remote-only commits
git log --oneline HEAD..origin/your-branch
# replay local work on top of remote (or merge if your team policy requires)
git pull --rebase origin your-branch
# retry push
git push origin your-branch
2. Diverged history
Use this when both local and remote contain unique commits. Preserve both sides, then resolve conflicts safely.
# fetch latest remote graph
git fetch origin
# visualize divergence
git log --oneline --left-right --graph origin/your-branch...HEAD
# choose one integration strategy
git rebase origin/your-branch
# or: git merge origin/your-branch
# resolve conflicts if needed
git add <resolved-files>
git rebase --continue # if rebasing
# or: git commit # if merging
# push integrated result
git push origin your-branch
3. Wrong target branch
Use this when you are pushing the right commit to the wrong branch name, or upstream tracking points to an unexpected remote ref.
# verify local branch and upstream mapping
git status -sb
git branch -vv
git remote -v
# check where HEAD is expected to go
git config --get branch.$(git branch --show-current).merge
# push explicitly to the intended target branch
git push origin HEAD:correct-branch
# optionally set upstream for future pushes
git push -u origin correct-branch
If the rejection appears right after stash/worktree cleanup, these guides help classify side effects quickly: git stash pop conflict and git worktree already checked out fix.
If push errors are preceded by fatal: Unable to create '.git/index.lock': File exists, run the git index.lock file exists root-cause fix guide first so remote history fixes are not mixed with local lock-state failures.
4. Final safety check before retrying push
- Run tests for the branch scope.
- Inspect diff one more time with Git Diff Viewer.
- Confirm current branch and target branch names are correct.
- Push normally; escalate only if policy explicitly permits force-with-lease.
FAQ
Can I skip fetch and just force-push?
No. Always fetch first so you can classify the failure state and avoid overwriting remote commits.
When is --force-with-lease acceptable?
Only on branches you own, after intentional history rewrite, and only when your team policy allows it.
Why does non-fast-forward happen repeatedly on active branches?
Because remote changes continue landing between your local updates. Shorten pull-to-push windows and verify upstream mapping before each push.