git push
Sending commits — and why "non-fast-forward rejected" happens.
git pushasks the remote to move its branch pointer forward. The remote will only accept this if the move is a fast-forward — meaning your commits extend the remote's history without rewriting it. If the remote has work you don't, it refuses.
Push in Action
See a push accepted (local is ahead, remote fast-forwards) or walk through the fix for a rejected push (histories diverged).
Why the remote rejects
The remote only accepts a push if applying it would be a fast-forward — the remote's current commit must be an ancestor of yours. This guarantees nobody's work gets silently overwritten.
When a colleague pushes before you, the remote advances past your fork point. Your branch no longer extends the remote's history — it diverges from it. Pushing would rewrite the shared history, so Git refuses.
The fix is always the same: integrate the remote work first (fetch + merge or fetch + rebase), then push. Now your tip is ahead of the remote's tip — a clean fast-forward again.
Force push — when and why to avoid it
git push --forcetells the remote to accept the push even if it's not a fast-forward — it overwrites whatever was there. This rewrites shared history and destroys colleagues' commits.
It is only safe on branches where you are the sole author and all collaborators know the history is being rewritten — typically feature branches after an interactive rebase.
Prefer --force-with-lease: it fails if anyone has pushed since your last fetch, giving you a safety net against accidentally clobbering others' work.