“Error: failed to push some refs” in Git — explained and fixed

Git refuses the push because the remote branch contains commits your local copy doesn't have — someone (teammate, you on another machine, a web edit) pushed first. Git won't silently overwrite their work, so it stops with “failed to push some refs” and hints like “non-fast-forward” or “fetch first.” Your commits are safe; they just need to be reconciled with the remote's.

The standard fix

  1. Pull the remote changes into your branch:
    git pull --rebase origin main
    Rebase replays your local commits on top of the remote's — the history reads as if you'd started from the latest. (Use your branch name; git pull without --rebase also works and creates a merge commit instead — both are correct, teams pick one style.)
  2. Resolve any conflicts if Git pauses: edit the marked files, git add them, git rebase --continue. Conflicts mean both sides touched the same lines — they're a decision, not damage.
  3. Push again: git push origin main — now your branch contains the remote's commits plus yours, and the push is a clean fast-forward.

Other messages that travel with it

Force push is almost never the answer. git push --force rewrites the remote to match you and discards the commits that blocked the push — on a shared branch, that's a teammate's work deleted. It's appropriate mainly for your own solo feature branch after a rebase, and even then --force-with-lease is the safer form (it refuses if the remote moved since you last looked).

If it still happens

Look at the actual divergence: git fetch then git log --oneline --graph --all -15 shows both lines of history. If the remote's new commits came from you (another laptop, a GitHub web edit), the rebase is painless. If a rebase goes sideways, git rebase --abort restores the pre-pull state exactly — nothing about this error can lose committed work unless force gets involved.

Common questions

Did I lose my commits when the push failed? No. A rejected push changes nothing on either side. Your commits sit in your local branch waiting to be reconciled.

Rebase or merge — which should be used? Both produce a pushable branch. Rebase gives a linear history; merge preserves the true branching. Follow the team's convention; for a solo repo, rebase reads cleaner.

Related errors

EADDRINUSE · npm ERESOLVE · 404 Not Found