fatal: refusing to merge unrelated histories

Git: Fix 'refusing to merge unrelated histories' Without Losing Commits

Git blocks merges when two branches have no common ancestor. Use --allow-unrelated-histories to merge them safely, or rebase to avoid a merge commit.

Quick answer: Run git pull origin <branch> --allow-unrelated-histories (or git merge --allow-unrelated-histories) to combine two branches that have no common commit ancestor. For a linear history, use git rebase --allow-unrelated-histories instead.

You've probably seen this when you initialized a new repo locally, made a few commits, then tried to pull from a remote that already had commits (like a GitHub repo with a README). Git sees two completely separate commit trees with no shared root and panics. What's actually happening here is Git's safety check: it refuses to merge because there's no common ancestor to base the three-way merge on. Without a common base, Git can't tell which changes are "yours" and which are "theirs" — so it stops and asks you to confirm you know what you're doing.

This used to work silently in older Git versions (pre-2.9), which is why some tutorials still say "just pull it." The behavior changed in Git 2.9 (released June 2016) to prevent accidental history corruption. If you're on any modern Git — 2.9 through 2.45+ — you'll hit this.

Fix 1: Allow unrelated histories in a merge (safest, keeps both histories)

This is what you want 95% of the time. It creates a merge commit that ties both histories together. Nothing is lost.

# If pulling from remote:
git pull origin main --allow-unrelated-histories

# If merging a local branch:
git checkout main
git merge other-branch --allow-unrelated-histories

Resolve any conflicts (there will probably be a few if both sides touched the same files — like README.md), then commit the merge. Both commit trees now share a common ancestor, and future merges work normally.

Real-world trigger: you cloned a brand-new GitHub repo that only has the auto-generated README and .gitignore, then locally did git init, wrote code, committed, and ran git pull origin main. Boom — unrelated histories.

Fix 2: Rebase to keep a linear history

If you hate merge commits and want a clean line, rebase your commits on top of the remote branch:

git pull --rebase origin main --allow-unrelated-histories

Or manually:

git fetch origin
git rebase origin/main --allow-unrelated-histories

The reason step 3 works is that rebase replays your commits one by one on top of the target branch, creating new commit hashes with the remote branch as parent. The --allow-unrelated-histories flag is still needed because, during the initial rebase, Git still sees no common ancestor. Once the first commit is replayed, the histories are linked.

Warning: don't rebase a branch that's already pushed and shared with other people. You'll rewrite history and force everyone else to deal with a mess.

Fix 3: If conflicts are a nightmare, start fresh (nuclear option)

If both histories have divergent versions of the same files and you don't care about preserving one side's commit log, you can:

  1. Clone the remote repo to a new directory.
  2. Copy your local files over it (overwriting).
  3. Commit and push.

This loses your local commit history but keeps the files. Only do this when the commit history genuinely doesn't matter — like a solo project where you just want the code up.

Why not just use --force?

Force-pushing a local history over a remote is the wrong fix here. It deletes every commit on the remote that isn't in your local branch. If that remote has collaborators, you've just nuked their work. The --allow-unrelated-histories flag exists precisely because Git wants you to think about this.

Prevention

Don't git init a project when a remote repo already exists. Clone first, then move your files in. If you're starting fresh on GitHub, either skip the auto-generated README, or clone before writing code. The extra 30 seconds saves you this whole headache.

Also: if you're setting up a new local repo and know you'll push to an existing remote, you can preemptively link histories by fetching first and resetting:

git init
git remote add origin <url>
git fetch origin
git reset --soft origin/main

Then commit your changes on top. No unrelated histories, no merge commit, clean linear start. That's the cleanest path if you catch it early.

Related Errors in Programming & Dev Tools
0X40010003 DBG_TERMINATE_THREAD (0X40010003) Fix: Debugger Killed Your Thread ModuleNotFoundError: No module named 'yaml' Python can't find 'yaml' even after PyYAML is installed 0X80040205 Fix EVENT_E_INTERNALEXCEPTION (0X80040205) in 3 Steps 0X4000001D STATUS_WX86_CONTINUE 0x4000001D: Fix WOW64 Exceptions Fast

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.