Git: push rejected (non-fast-forward)
In short: The server has commits you do not have locally; Git rejects the push until you have fetched and integrated the others’ changes.
In more detail: Message: ! [rejected] main -> main (fetch first) or (non-fast-forward), plus Updates were rejected because the remote contains work that you do not have locally. Git protects against overwriting others’ commits.
In Depth
Causes
- Someone else (or you from a second device) pushed after your last sync.
- You changed history locally (rebase, amend, reset) and the branch tip no longer matches the server.
- Wrong branch or remote.
Solutions
- Fetch and integrate:
git pull --rebase(linear history) orgit pull(merge commit). Resolve conflicts, thengit push. - Look first:
git fetchandgit log HEAD..origin/mainshow what is new on the server. - After deliberately rewriting history on your own branch:
git push --force-with-lease(safer than--force, checks that the server is unchanged). - On shared branches (main, develop) never force; agree or work via pull request.
- Wrong branch?
git branch -vvshows the upstream.
Mnemonic
--force overwrites blindly and can destroy others’ work. --force-with-lease aborts if the server has meanwhile received new commits. Tell the team beforehand before changing history on shared branches. Protected branches (branch protection) forbid force push altogether in many teams.
See also: Resolving a merge conflict, Git: not a git repository