Git Push Rejected: How To Fix "Updates Were Rejected Because The Remote Contains Work You Do Not Have"
Git Push Rejected: Fix "Updates Were Rejected Because the Remote Contains Work You Do Not Have"
You've seen this error. Everyone has. You try to push your changes and Git stops you cold:
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'origin'
hint: Updates were rejected because the remote contains work you do not have locally.
Here's your fast-track reference to diagnose and fix it.
Why This Happens (30-Second Version)
The remote branch has commits your local branch doesn't. Git refuses to overwrite them. This is a good thing — it's protecting you from losing someone else's work.
Quick Diagnosis
First, figure out what you're dealing with:
# See what's on the remote that you don't have
git fetch origin
git log HEAD..origin/main --oneline
# Check branch divergence at a glance
git status
# Look for: "Your branch is behind 'origin/main' by X commits"
Fix #1: Pull Then Push (The Standard Fix)
This is the right move 95% of the time when collaborating with others.
git pull origin main
# Resolve any merge conflicts if they appear
git push origin main
Use this when: You want to merge remote changes into your branch before pushing.
Fix #2: Pull with Rebase (Cleaner History)
Keeps a linear commit history. My personal preference for feature branches.
git pull --rebase origin main
# If conflicts arise during rebase:
git rebase --continue # after resolving each conflict
# OR
git rebase --abort # to bail out entirely
git push origin main
Use this when: You want your commits to appear on top of the remote changes, no merge commit needed.
Fix #3: Force Push (Use With Extreme Caution)
Only do this if you know you want to overwrite the remote. Typically valid on your own personal feature branch that nobody else is using.
# The safer force push — fails if remote has changed since your last fetch
git push --force-with-lease origin feature/my-branch
# The nuclear option — don't use on shared branches
git push --force origin feature/my-branch
⚠️ Never force push to
main,master, or any shared branch. You will overwrite teammates' work. Branch protections should prevent this, but don't rely on that alone.
Use this when: You've rebased your local branch and need to update the remote to match. Personal branches only.
Fix #4: You Pushed to the Wrong Branch
Sometimes the problem is simpler than you think.
# Check where you are
git branch
# Push to the correct branch
git push origin your-actual-branch-name
# Or set upstream tracking explicitly
git push -u origin your-actual-branch-name
Fix #5: New Repo, Unrelated Histories
Happens when you git init locally and then try to connect to an existing remote repo.
git pull origin main --allow-unrelated-histories
git push origin main
Conflict Resolution Quick Reference
When a pull or rebase gives you conflicts:
# See what's conflicted
git status
# Open conflict markers in files, look for:
# <<<<<<< HEAD
# your changes
# =======
# their changes
# >>>>>>> origin/main
# After fixing conflicts manually:
git add <resolved-file>
git commit # for merge
# OR
git rebase --continue # for rebase
Decision Tree
Got rejected?
│
├── Is it YOUR personal branch nobody else uses?
│ └── Yes → git push --force-with-lease (after rebase)
│
├── Is it a shared/team branch?
│ ├── Want clean history? → git pull --rebase → resolve → push
│ └── Don't care about merge commits? → git pull → resolve → push
│
└── Wrong branch entirely?
└── git push origin correct-branch-name
Set Rebase as Default Pull Strategy
Stop thinking about this every time. Configure it once:
# Set rebase as default for all repos
git config --global pull.rebase true
# Or just for the current repo
git config pull.rebase true
Prevention Tips
# Always fetch before starting new work
git fetch origin
# Make it a habit before long sessions
git pull --rebase origin main
# Use branch protections in GitHub/GitLab to prevent force pushes to main
TL;DR Cheat Sheet
| Situation | Command |
|---|---|
| Normal collaboration | git pull origin main && git push |
| Want clean history | git pull --rebase origin main && git push |
| Personal branch after rebase | git push --force-with-lease origin branch |
| Wrong branch | git push origin correct-branch |
| Unrelated histories | git pull --allow-unrelated-histories |
The error looks scary but the fix is almost always git pull --rebase. Make that your muscle memory and you'll rarely be stuck for more than 30 seconds.
Was this article helpful?
DevSecOps Lead
Security-first mindset in everything I ship. From zero-trust architectures to supply chain security, I make sure your pipeline doesn't become your weakest link.
Related Articles
Fix Git 'fatal: refusing to merge unrelated histories'
Resolve the Git error 'refusing to merge unrelated histories' when pulling or merging branches that share no common ancestor.
Git Worktrees For Managing Multiple Feature Branches Simultaneously
Stop stashing. Stop context-switching. Git worktrees let you check out multiple branches simultaneously in separate directories — each with its own working...
Git Bisect: Find the Exact Commit That Broke Production
Use git bisect to binary-search through commit history and pinpoint the exact change that introduced a bug — manually or fully automated.
Git Commands: Cheat Sheet
Git commands cheat sheet for DevOps engineers — branching, rebasing, stashing, bisecting, cherry-picking, and recovery workflows with examples.
Helm Error: Release Has No Deployed Revisions - How To Recover Failed Installations
If you've been working with Helm for any length of time, you've probably encountered this frustrating error: "Error: release has no deployed revisions." It...
GCP Cloud Function "Function Execution Took Too Long" Error: Memory And Timeout Configuration Fix Guide
Getting the dreaded "Function execution took too long" error in your Cloud Functions? You're not alone. This error happens when your function exceeds the c...
More in Git
View all →Pre-Commit Hooks Framework for Automated Code Quality
Set up the pre-commit hooks framework to automatically enforce linting, formatting, and security checks before every Git commit.