When someone pushed before you
Intermediate Git CLI GitLab UI GitHub UI
Why this matters
A rejected push looks like a failure and is usually a courtesy: Git noticed that accepting your push would discard someone else's work, and stopped. The message tells you which situation you are in, if you read past the first line. Three situations cover nearly everything.
Flavour 1: non-fast-forward
$ git pushTo https://gitlab.com/northwind-trails/trailguide.git
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'https://gitlab.com/northwind-trails/trailguide.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. If you want to integrate the remote changes,
hint: use 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.What happened: a colleague pushed commits to the same branch after you last fetched. Your branch and the remote have diverged, and accepting your push would drop their commits.
The fix, exactly as the hint says:
$ git pull
$ git pushTo https://gitlab.com/you/trailguide.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'https://gitlab.com/you/trailguide.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again.If the pull produces a conflict, resolve it (Section 11) and push afterwards. If your team prefers a linear history, git pull --rebase then push.
Flavour 2: fetch first
What happened: almost the same, but Git has not even fetched the remote's commits yet. The most common cause is a brand-new project created with a README while your folder already had its own history (lesson 7.3).
The fix depends on the cause:
- A colleague pushed:
git pull, thengit push. -
Two unrelated histories (the README case): a plain
git pullanswersfatal: refusing to merge unrelated histories. Either recreate the project empty, or run it once with permission:Terminal $ git pull origin main --allow-unrelated-historiesremote: GitLab: You are not allowed to push code to protected branches on this project. To https://gitlab.com/northwind-trails/trailguide.git ! [remote rejected] main -> main (pre-receive hook declined) error: failed to push some refs to 'https://gitlab.com/northwind-trails/trailguide.git'An editor opens for the merge message; save and close, resolve any README conflict, then push.
Flavour 3: protected branch
What happened: the branch accepts changes only through a merge request. Nothing is wrong with your account or your token. Note the two tells: a remote: line, which is the server speaking, and [remote rejected] rather than [rejected].
The fix is to move your commits onto a branch and open a merge request (lesson 6.9):
$ git switch -c docs/45-move-my-commits
$ git push -u origin docs/45-move-my-commitsTelling them apart
| The message contains | Flavour | Fix |
|---|---|---|
(non-fast-forward) |
someone pushed to your branch | git pull, then push |
(fetch first) |
the remote has work you have not fetched, possibly unrelated | git pull, or --allow-unrelated-histories once |
remote: and [remote rejected] |
the server's own rule, usually branch protection | branch and open a merge request |
Authentication failed, Access denied |
not a rejection at all: credentials | lesson 7.2 |
What not to do
How to do it
The whole lesson is two commands, plus reading which flavour you have:
$ git pull
$ git pushIf the pull conflicts, resolve and push. If the message contains remote:, no amount of pulling helps; branch instead.
The push fails with a notification; open Output → Git (choose "Git" in the dropdown) to read the full message, because the notification truncates it.
Then click Sync Changes in the status bar, which pulls and pushes in one go, or … menu → Pull followed by Push. On a conflict the merge editor opens.
A Push failed notification appears with the server's message; the full text is in Git → Show Git Log, Console tab.
IntelliJ often offers Merge or Rebase directly in that notification, which runs the pull for you. Otherwise Update Project (Ctrl+T / ⌘T) then push again.
Nothing to do on the website for the first two flavours: they are about your computer being behind.
For the third, the project's Settings → Repository → Protected branches page shows the rule (maintainers and owners can see and change it). If you believe you should be allowed to push directly, that is a conversation with the maintainer, not a Git problem.
The same. Settings → Rules → Rulesets (or Settings → Branches) holds the protection rules, visible to administrators.
If a pull request says "This branch is out-of-date with the base branch", that is the web equivalent of being behind: the Update branch button does the pull for you on the server.
Common mistakes
- Reading only the first line.
! [rejected]is the same for two very different situations; the flavour is in the parentheses and the hints. - Reaching for
--force. It turns a courtesy into data loss. - Pulling repeatedly on a protected branch. No amount of pulling changes the server's rule.
- Confusing authentication with rejection.
Authentication failedhappens before any of this and is a token or key problem.
Try it yourself
Goal: produce a real rejected push and fix it properly.
- In your playground with a remote, make a commit on the website (edit
docs/faq.mdin the browser and commit). - Locally, without fetching, make a different commit (edit
README.md) and try to push. - Read the message and identify the flavour.
- Fix it with
git pull, thengit push. - Run
git log --oneline --graph -4and see how the two lines joined.
Expected result: step 2 is rejected as non-fast-forward (or fetch first); step 4 succeeds; the graph shows a merge commit joining the web edit and your local commit.
Show solution
The rejection protected the browser commit. The pull merged the two, and because the two commits touched different files there was no conflict to resolve. With a conflict, the same sequence applies with a resolution step in the middle.