git pull to merge them in, then git push goes through.Guide
Git refused your push and mumbled about 'fetch first'. Translation: GitHub has commits you don't. Easy fix.
You run git push, confident, and Git slams the door:
What you see
$ ! [rejected] main -> main (fetch first)
$ error: failed to push some refs to 'https://github.com/you/project.git'
$ hint: Updates were rejected because the remote contains work that you do
$ hint: not have locally. This is Git's message, not commands to run.
Someone (a teammate — or you, from another computer or a GitHub edit) pushed commits you
haven't downloaded yet. Git refuses to overwrite them. git status tells you
exactly which situation you're in:
VS Code shows the same story as the little arrows in the status bar: ↓2 means two commits to pull, ↑1 means one commit to push. Both at once = diverged.
Catch up, then send
$ git pull
$ git push If you and the remote edited the same lines, the pull raises a merge conflict — calmly handled in Fix Merge Conflicts.
That's it, most days. The pull may create a small "merge commit" joining the two lines of work — harmless, and your push goes through right after. If the pull complains about a conflict, Fix Merge Conflicts walks you through it.
git pull --rebase does the same catch-up but replays your commits on top
of the downloaded ones instead of creating a merge commit — the history stays a straight line.
It's a nice habit on a branch only you work on.
Rebase-style catch-up
$ git pull --rebase
$ git push
Some tutorials suggest git push --force to "make it work". Don't — force-pushing
overwrites the commits on GitHub, including work someone else may have just pushed.
On a shared branch that deletes a teammate's work. If a push is rejected, the answer is
almost always to pull first, never to force.
Mental model: GitHub's copy and your copy are two notebooks. Push is only allowed when your notebook contains everything theirs does — pull copies their new pages into yours first.
Up next: when the push fails for a different reason — GitHub rejecting your login instead of your commits.
FAQ
git pull to merge them in, then git push goes through.git pull joins the two lines (a small merge commit is normal), then you push.--force-with-lease is the safer spelling.