DevOps & Platform
5 min readMay 31, 2026Updated August 19, 2026

Fix Git Push Rejected: Updates Were Rejected

AJ
Ajeet Yadav
Platform & Cloud Engineer
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.

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

bash
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/main

If 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.


Rebase re-applies your local commits on top of the remote's latest commit, producing a clean linear history:

bash
git pull --rebase origin main

This 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:

bash
# 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 --abort

After the rebase, push normally:

bash
git push origin main

Pull with merge (creates a merge commit instead)

bash
git pull origin main
# equivalent to: git fetch + git merge origin/main

This 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.

bash
# 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.

Talk to us

Fix 3: You and a Colleague Both Committed to the Same Branch

This is the diverged state on a shared branch:

bash
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 main

If your team uses merge commits instead of rebase:

bash
git merge origin/main
# Resolve conflicts if any
git push origin main

Common 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.

bash
# In CI — safe pattern for force-pushing a release branch
git push --force-with-lease origin release/1.5

Quick Reference

SituationFix
Remote has new commits, you have local commitsgit pull --rebase origin main
Your own feature branch after a rebasegit push --force-with-lease origin my-branch
Team member pushed to your shared feature branchgit fetch && git rebase origin/my-branch

See Also

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

Was this article helpful?

Be the first to rate this article

Related Topics

Git
Troubleshooting
Version Control
DevOps

Found this useful? Share it.

Practice this

Read Next