Fix Git Push Rejected: Updates Were Rejected

Quick answer
Git rejects your push when the remote has commits your local branch doesn't have. The safe fix is to pull first and integrate those changes — not force push. Here's the full diagnostic and fix guide.
- Why This Happens
- Diagnose First
- Fix 1: Pull With Rebase (Recommended for Linear History)
- Fix 2: Force Push — When It's Safe
- Fix 3: You and a Colleague Both Committed to the Same Branch
5 min read · DevOps & Platform
Fix Git Push Rejected: Updates Were Rejected
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'origin'
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.
Why This Happens
Git requires a fast-forward push by default: the remote's current commit must be an ancestor of what you're pushing. If someone else pushed commits to the remote after your last pull, the remote has moved forward — your push would overwrite their commits.
Remote: A → B → C ← someone pushed C
Local: A → B → D ← you committed D locally
← you can't push D without integrating C first
Diagnose First
1# See what the remote has that you don't
2git fetch origin
3git log HEAD..origin/main --oneline
4
5# See your local commits not on remote
6git log origin/main..HEAD --oneline
7
8# Full picture
9git log --oneline --graph HEAD origin/mainIf you see commits on both sides (HEAD has commits the remote doesn't, and the remote has commits you don't), your branches have diverged.
Fix 1: Pull With Rebase (Recommended for Linear History)
Rebase re-applies your local commits on top of the remote's latest commit, producing a clean linear history:
git pull --rebase origin mainThis replays your commits after the remote's new commits:
Before rebase: A → B → C (remote), A → B → D (local)
After rebase: A → B → C → D' (your commit, rebased)
If there are conflicts during the rebase:
# Resolve conflicts in the flagged files, then:
git add <resolved-files>
git rebase --continue
# If the conflict is too complex and you want to start over:
git rebase --abortAfter the rebase, push normally:
git push origin mainPull with merge (creates a merge commit instead)
git pull origin main
# equivalent to: git fetch + git merge origin/mainThis works but creates a merge commit (Merge branch 'main' of ...), which many teams avoid on main to keep the history linear. Use rebase unless your team's policy prefers merge commits.
Fix 2: Force Push — When It's Safe
Force pushing overwrites the remote branch with your local version. Only do this on branches you own (feature branches, not main or shared branches).
Never force push to main in a team project. Never force push to branches that others have checked out.
# Safer than --force: fails if someone else pushed after your last fetch
git push --force-with-lease origin my-feature-branch--force-with-lease checks that the remote's current commit matches what you last fetched. If someone else pushed since then, Git rejects the force push rather than silently overwriting their work. Always prefer --force-with-lease over --force.
When is force push legitimate?
- Amending commits on your own feature branch before a PR is merged
- Rebasing a feature branch onto the latest main (your branch history changes)
- Squashing commits on a branch only you use
Stuck on this in production?
We debug exactly this kind of issue for platform teams — usually in a single working session.
Fix 3: You and a Colleague Both Committed to the Same Branch
This is the diverged state on a shared branch:
1# 1. Fetch to see the remote state
2git fetch origin
3
4# 2. Rebase your commits on top of the remote
5git rebase origin/main
6
7# 3. Resolve any conflicts
8# Edit conflicted files, then:
9git add <files>
10git rebase --continue
11
12# 4. Push
13git push origin mainIf your team uses merge commits instead of rebase:
git merge origin/main
# Resolve conflicts if any
git push origin mainCommon Mistake: Mixing --force Into Automated Scripts
CI pipelines that amend commits and then push should always use --force-with-lease. If your pipeline uses --force without a lease check, concurrent builds can silently discard each other's commits.
# In CI — safe pattern for force-pushing a release branch
git push --force-with-lease origin release/1.5Quick Reference
| Situation | Fix |
|---|---|
| Remote has new commits, you have local commits | git pull --rebase origin main |
| Your own feature branch after a rebase | git push --force-with-lease origin my-branch |
| Team member pushed to your shared feature branch | git fetch && git rebase origin/my-branch |
See Also
- Fix: Git 'refusing to merge unrelated histories' — when two repos have no common ancestor
- Fix: Git Detached HEAD — another common Git state confusion
- Semantic Versioning and Conventional Commits — automated releases that avoid manual push conflicts
Frequently Asked Questions
Should I pull with merge or rebase?
Rebase for your own feature branch, which keeps history linear and avoids merge commits that say nothing. Merge when the branch is shared, because rebasing rewrites commits others may already have. The rejection itself does not tell you which is appropriate — who else has the branch does.
When is force pushing actually safe?
On a branch only you use, and preferably with --force-with-lease rather than --force. The lease variant refuses if the remote moved since you last fetched, which catches exactly the case where a colleague pushed and you would otherwise overwrite them. Plain force is what deletes other people's work.
Why was my push rejected when I have not changed anything?
Someone else pushed to the same branch, so your history no longer descends from the remote's. Fetch and inspect what arrived before deciding how to reconcile — the rejection is Git preventing data loss, not an error to work around.
The remote has commits I do not want. How do I discard them?
Confirm nobody else needs them first, then reset your branch to the state you want and force push with lease. Be certain: on a shared branch this discards a colleague's work, and Git will not warn you a second time.
Official References
- Debug Pods — reading pod status, events and container states
- kubectl reference — command syntax, output formats and selectors
Was this article helpful?
Be the first to rate this article
Related Topics
Found this useful? Share it.


