GitHub
Git
merge conflict
push error
troubleshooting

Cannot push to GitHub - keeps saying need merge

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The Git error "Updates were rejected because the remote contains work that you do not have locally" means the remote branch has commits that your local branch does not have. Git refuses to push because it would overwrite those remote commits. The fix is to pull the remote changes first (with git pull or git pull --rebase), resolve any conflicts, and then push. This happens when someone else pushed to the same branch, or when you made commits directly on GitHub (like editing a README).

The Error Message

bash
1$ git push origin main
2To github.com:user/repo.git
3 ! [rejected]        main -> main (fetch first)
4error: failed to push some refs to 'github.com:user/repo.git'
5hint: Updates were rejected because the remote contains work that you do
6hint: not have locally. Integrate the remote changes
7hint: (e.g., 'git pull ...') before pushing again.

This means the commit history has diverged:

 
Remote:  ABCD (someone else added D)
Local:   ABCE (you added E)

Git cannot fast-forward the remote from C to E because D would be lost.

Fix 1: git pull Then Push (Merge)

bash
1# Pull remote changes and merge them with yours
2git pull origin main
3
4# If there are no conflicts, Git creates a merge commit automatically
5# Then push
6git push origin main

This creates a merge commit:

 
Remote after push:  ABCDM (merge commit)
E

Resolving Merge Conflicts

If the same files were changed in both commits, Git reports conflicts:

bash
1$ git pull origin main
2Auto-merging app.py
3CONFLICT (content): Merge conflict in app.py
4Automatic merge failed; fix conflicts and then commit the result.
bash
1# 1. Open the conflicting file and resolve conflicts
2# Look for conflict markers:
3# <<<<<<< HEAD
4# your changes
5# =======
6# remote changes
7# >>>>>>> origin/main
8
9# 2. Edit the file to keep the correct code, removing markers
10
11# 3. Stage the resolved file
12git add app.py
13
14# 4. Complete the merge
15git commit -m "Merge remote changes"
16
17# 5. Push
18git push origin main

Rebasing replays your local commits on top of the remote changes, creating a linear history:

bash
1git pull --rebase origin main
2
3# If conflicts occur during rebase:
4# 1. Fix the conflict in the file
5# 2. Stage it
6git add app.py
7# 3. Continue the rebase
8git rebase --continue
9
10# Push after successful rebase
11git push origin main

Result:

 
Remote after push:  ABCDE' (your commit replayed on top)

Set Rebase as Default

bash
1# Always rebase on pull for this repo
2git config pull.rebase true
3
4# Or globally
5git config --global pull.rebase true

Fix 3: Force Push (Dangerous)

Force push overwrites the remote branch with your local state. Only use this on personal branches where no one else is working:

bash
1# DANGEROUS — overwrites remote commits
2git push --force origin main
3
4# Safer alternative — fails if someone pushed since your last fetch
5git push --force-with-lease origin main

--force-with-lease is safer because it checks that the remote branch is at the commit you expect. If someone pushed in the meantime, it fails instead of overwriting their work.

Why This Happens

Someone Else Pushed to the Same Branch

bash
# Alice pushes to main
# Bob tries to push to main without pulling Alice's changes
# Bob gets the "need merge" error

Editing Files on GitHub Directly

bash
# You edit README.md on GitHub's web UI (creates a commit)
# Then push from local without pulling — remote has the web commit

Force-Pushed from Another Machine

bash
# You force-pushed from machine A, rewriting history
# Machine B still has the old history and can't push
# Fix: git pull --rebase or git reset --hard origin/main on machine B

Prevention

bash
1# Always pull before starting work
2git pull origin main
3
4# Use feature branches instead of pushing to main directly
5git checkout -b feature/my-change
6# ... make commits ...
7git push origin feature/my-change
8# Create a PR to merge into main
9
10# Fetch regularly to stay aware of remote changes
11git fetch origin
12git log --oneline main..origin/main  # See what's new on remote

Common Pitfalls

  • Force-pushing to a shared branch: git push --force overwrites all remote commits, potentially deleting other people's work. Only force-push to branches where you are the sole contributor. Use --force-with-lease for safety.
  • Pulling without specifying a strategy: Without pull.rebase configured, git pull defaults to merge, creating unnecessary merge commits. Set git config --global pull.rebase true for cleaner history.
  • Not resolving all conflict markers: After a merge conflict, leaving <<<<<<<, =======, or >>>>>>> markers in the file causes syntax errors. Search for these markers before committing.
  • Rebasing after already pushing a merge commit: If you already pulled with merge and pushed, rebasing later rewrites the history that others may have. Once pushed, do not rebase those commits.
  • Ignoring the error and retrying push repeatedly: The error will not resolve itself. You must integrate the remote changes first with git pull before the push will succeed.

Summary

  • The "need merge" error means the remote has commits you do not have locally
  • Use git pull --rebase origin main to replay your commits on top of remote changes (cleanest approach)
  • Use git pull origin main for a merge-based integration (creates a merge commit)
  • Resolve conflicts by editing files, removing conflict markers, staging, and completing the merge/rebase
  • Never git push --force to shared branches — use --force-with-lease if force-pushing is truly needed

Course illustration
Course illustration

All Rights Reserved.