Skip to content

How to Fix Git Push Rejected (non-fast-forward) Error

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about How to Fix Git Push Rejected (non. We cover key concepts, practical examples, and best practices.

You run git push and get Updates were rejected because the remote contains work that you do not have locally — the remote branch has commits that you need to integrate first.

The Problem

! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'https://github.com/user/repo.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
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.

Step-by-Step Fix

Step 1: Pull the latest remote changes

git pull origin main

Step 2: Choose merge or rebase

Merge (preserves full history):

git pull --no-rebase origin main

Rebase (linear history):

git pull --rebase origin main

Step 3: Resolve any conflicts

If there are conflicts:

# Edit conflicted files, then
git add <file>
git rebase --continue

Step 4: Push your changes

git push origin main

Step 5: Force push only when absolutely necessary

# WRONG — dangerous, overwrites remote
git push --force origin main

# RIGHT — safer, checks if remote has new commits
git push --force-with-lease origin main

Step 6: Set upstream tracking

git push -u origin main

After this, you can use git push without arguments.

Prevention Tips

  • Always pull before pushing: git pull --rebase
  • Use feature branches to avoid conflicts on main
  • Communicate with your team before force pushing
  • Protect main branch on GitHub/GitLab
  • Use git fetch followed by git log to preview remote changes

Common Mistakes with push rejected

  1. Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
  2. Using return to exit a function early instead of wrapping a pure value in the monad
  3. Mixing let bindings with <- bindings in do notation, producing type errors

These mistakes appear frequently in real-world GIT code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### What does non-fast-forward mean?

A non-fast-forward push means the remote branch has commits you do not have locally. Git refuses the push because it would overwrite remote commits. You must integrate the remote changes first by pulling.

What is the difference between git pull --rebase and git pull --no-rebase?

git pull --no-rebase creates a merge commit that ties your changes with remote changes. git pull --rebase replays your commits on top of the remote changes, creating a linear history without merge commits.

Is git push --force-with-lease safe?

Safer than git push --force. It checks that the remote branch has not been updated since you last fetched. If someone else pushed, the force push is rejected. Use --force-if-includes for even more safety.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro