You ran git pull origin main and Git slapped you with fatal: refusing to merge unrelated histories. I see this at least once a month — last week a client called panicked because their GitHub repo wouldn't pull after they'd initialized locally with a README and then added a remote that already had commits. Git isn't broken. It's protecting you from smashing two completely separate commit trees together.
The error fires when the two branches you're merging don't share an ancestor commit. Two independent git init runs, a re-uploaded repo, or a fresh GitHub repo with a README you didn't pull first — all classic triggers.
Quick Fix (30 seconds) — If You Just Want It Working
If you don't care about preserving a clean history and you know the remote is the source of truth, this is the fastest exit. Add the flag to tell Git you're aware the histories are unrelated and you want the merge anyway.
git pull origin main --allow-unrelated-histories
That's it. Git will create a merge commit joining both trees. If your default branch is master, swap it out:
git pull origin master --allow-unrelated-histories
Heads up: if both sides have the same file with different content (say, both have a README.md), you'll get merge conflicts. Resolve them, then:
git add .
git commit -m "Merge remote history"
git push
This works. It's blunt but effective. If you don't need pretty history, stop reading here.
Moderate Fix (5 minutes) — When You Want the Remote to Win
Sometimes you've got a local repo with junk commits you don't need — you were experimenting, or you cloned the wrong thing, or your .git folder is a leftover from another project. You want the remote's history, period.
Real scenario: a client had been working in a folder for two weeks without realizing they'd initialized a fresh repo instead of cloning their team's. They'd been committing locally the whole time. When we tried to pull, boom — unrelated histories.
First, back up anything you actually need:
git branch backup-local
Now reset your local branch to match remote exactly. This wipes your local commits from the working tree (they're still on backup-local):
git fetch origin
git reset --hard origin/main
Then clean up untracked files that would conflict:
git clean -fd
Your local now mirrors the remote. Push your backup branch if you want to cherry-pick later:
git push -u origin backup-local
Now you can git log on backup-local and pull the specific commits you need with git cherry-pick.
Advanced Fix (15+ minutes) — When Histories Actually Need Reconciling
Sometimes both sides matter. You wrote real code locally, the remote has real code too, and you need a proper merge that preserves the trail. This is where --allow-unrelated-histories still works but you should do it deliberately.
Step 1: Inspect both sides before merging
git log --oneline --all --graph --decorate
You'll see two disconnected trees. Note the root commits on each side. If they're genuinely separate projects, you may want a fresh start. If they're the same project re-created, proceed.
Step 2: Fetch without merging
git fetch origin
Do not pull. Fetch only. Now you have origin/main locally without touching your branch.
Step 3: Merge with the flag and review conflicts carefully
git merge origin/main --allow-unrelated-histories
Conflicts will almost certainly happen on README.md, .gitignore, and LICENSE. Open each in your editor, decide which lines to keep, then:
git add README.md .gitignore LICENSE
git commit
Step 4: Verify the tree is sane
git log --oneline --graph -20
You should see a merge commit with two parents. If your build works, push:
git push origin main
Step 5: If it went sideways, bail out
git merge --abort
That returns you to the pre-merge state. No harm done.
Why This Happens (So You Can Avoid It Next Time)
Git compares commit SHAs. If two branches don't share a common ancestor commit, Git assumes you're doing something dangerous — merging two entirely separate projects. The error exists because 99% of the time, when histories are unrelated, someone made a mistake.
The usual suspects:
git initlocally, thengit remote add origin, thengit pull— without pulling first, you've got two root commits.- GitHub created a repo with an auto-generated README or
.gitignore, and you never pulled it before committing locally. - You copied a
.gitfolder from another project. - You re-imported a repo from GitLab, Bitbucket, or a backup and the SHAs changed.
To prevent it: when starting from an existing remote, always git clone, not git init. If you must init locally, run git pull origin main --allow-unrelated-histories on the very first pull.
What Not To Do
Don't blindly run git push --force to make the error go away. If you haven't fetched first, you'll overwrite the remote. Had a client lose three days of a teammate's work that way. Force push is only safe here if you're 100% certain the remote has nothing you need.
Don't edit .git internals or try to rewrite SHAs unless you enjoy pain. The --allow-unrelated-histories flag exists precisely for this. Use it.
Don't skip the backup branch step if you're resetting. You will want those commits back about 20% of the time, and you can't get them if you didn't save them.
Pick Your Path
If you just want it working and don't care about history: --allow-unrelated-histories, resolve conflicts, push. Done in under a minute.
If remote is truth and local was a mistake: backup branch, git reset --hard origin/main, clean, move on.
If both sides have real work: fetch, merge with the flag, resolve carefully, verify, push.
The error looks scary but it's Git being cautious. Once you know it just means "these two don't share a parent," it stops being a wall and becomes a checkbox.