Git Push Rejected: How to Fix a Non-Fast-Forward Error

A push is rejected as non-fast-forward when the remote branch has commits your local branch does not contain. Git blocks the push to avoid replacing remote history. Fetch those changes, integrate them into your branch, and then push again.

Practice Git workflows →

Why was my Git push rejected?

The remote branch may have been updated by a teammate, another computer, or a commit made on a hosting service. The rejection often includes a message like non-fast-forward or failed to push some refs. Your local branch and remote branch have diverged or the remote is ahead.

Do not immediately force-push. First find out what changed on the remote and integrate it, particularly if the branch is shared.

Step 1: Check your branch and working tree

Confirm the branch you intend to update and check whether you have uncommitted changes:

git status
git branch --show-current

Commit or safely save any in-progress work before pulling if necessary. Make sure your configured upstream is the branch you meant to push to.

Step 2: Fetch and inspect remote commits

Fetch updates without changing your current files, then compare your branch with its upstream:

git fetch
git log --oneline --graph --decorate --all -20

Review the graph to understand which commits are local and which came from the remote. If the branch or remote is not configured as expected, verify them with git branch -vv and git remote -v before integrating changes.

Step 3: Integrate remote changes

Option A: Rebase your local commits

If your local commits have not been shared and your team uses a linear history, rebase your branch on its upstream:

git pull --rebase

Option B: Merge the remote branch

If your team prefers merge commits, or your local commits are already shared, merge the upstream branch instead:

git pull --no-rebase

Choose one approach based on your repository’s workflow. Do not switch between merge and rebase just to make the error disappear; each affects history differently.

Step 4: Resolve conflicts and push

If Git reports conflicts, open each listed file, decide which content should remain, and remove the conflict markers. Then stage the resolved files. For a rebase, continue with git rebase --continue; to cancel it, use git rebase --abort. For a merge, finish the merge commit as Git instructs.

Once integration completes, inspect the result and retry the push:

git status
git push

If Git still rejects the push, fetch and inspect again; the remote may have received another update while you were working.

Should I use git push --force?

Force-pushing can replace commits on the remote and disrupt other contributors. Use it only when you intentionally rewrote your own branch, understand which remote commits would be replaced, and have coordinated with anyone using that branch. When appropriate, git push --force-with-lease checks that the remote has not advanced unexpectedly, but it does not make overwriting shared work harmless.

Non-fast-forward push FAQ

Will git pull overwrite my local commits?

A normal pull integrates remote commits by merge or rebase; it does not simply erase local commits. Review your working tree and choose the integration method that matches your team’s workflow.

Why did GitHub reject my first push?

The remote may already contain an initial README, license, or other commit that your local repository lacks. Fetch and inspect the remote history, then integrate it before pushing.

Learn Git Faster by Practicing

Reading is just the first step. Real learning happens when you practice.

Start Learning Git →