Fix Git "fatal: refusing to merge unrelated histories" Error
Quick Fix
If you created a local repo and are pulling from a remote that has existing commits:
# For git pull
git pull origin main --allow-unrelated-histories
# For git merge
git merge origin/main --allow-unrelated-histories
# Then resolve any conflicts and commit
You ran git pull origin main or git merge and Git responded with fatal: refusing to merge unrelated histories. This error means the two branches share no common ancestor commit. Git added this safety check in version 2.9 (June 2016) to prevent accidentally merging two completely separate repositories. Before 2.9, this merge would happen silently. Understanding why the histories are unrelated determines whether --allow-unrelated-histories is the right fix or a mistake.
Why Histories Become Unrelated
Two branches are "unrelated" when git merge-base finds no common ancestor. There are five common scenarios that cause this.
Scenario 1: git init Locally + Remote Already Has Commits
This is the most common cause. You created a local repo with git init, made some commits, then added a remote that already has its own commits (like a GitHub repo initialized with a README):
# Local
mkdir my-project && cd my-project
git init
echo "hello" > app.js
git add . && git commit -m "initial commit"
# Remote (GitHub) was created with "Initialize with README"
git remote add origin git@github.com:user/my-project.git
git pull origin main
# fatal: refusing to merge unrelated histories
The local initial commit and the remote initial commit (README) have no parent relationship. They are two independent root commits.
Scenario 2: Orphan Branches
An orphan branch has no parent commit. It starts a fresh history within the same repository:
git checkout --orphan gh-pages
git rm -rf .
echo "docs" > index.html
git add . && git commit -m "docs initial"
# Trying to merge this back into main fails
git checkout main
git merge gh-pages
# fatal: refusing to merge unrelated histories
This is intentional for branches like gh-pages that serve a different purpose. You typically do not merge orphan branches back into main.
Scenario 3: Repository Was Squashed or Rewritten
If someone squashed the entire history into a single commit (common when open-sourcing an internal project or resetting history for compliance), the new root commit has no relationship to any branches that existed before the squash:
# Someone did this to "clean" the repo
git checkout --orphan fresh
git add -A
git commit -m "fresh start"
git branch -D main
git branch -m main
git push --force origin main
Anyone who had the old main checked out will now get unrelated histories when they pull.
Scenario 4: Subtree or Submodule Merge
When merging a completely separate repository as a subdirectory (subtree merge), the histories are inherently unrelated:
git remote add library git@github.com:org/library.git
git fetch library
git merge library/main
# fatal: refusing to merge unrelated histories
Scenario 5: Shallow Clone Depth Issue
A shallow clone (git clone --depth 1) may not have enough history for Git to find the common ancestor. This is less common but happens in CI pipelines that use shallow clones for speed:
# Deepen the clone if this is the issue
git fetch --unshallow
The Fix: --allow-unrelated-histories
When you have confirmed that merging is intentional, use the flag:
With git pull
git pull origin main --allow-unrelated-histories
With git merge
git fetch origin
git merge origin/main --allow-unrelated-histories
What Happens Next
Git will attempt a three-way merge using an empty tree as the common ancestor. This means every file from both sides is considered "added," so:
- Files that exist only on one side merge cleanly
- Files that exist on both sides with different content will conflict
- The merge commit will have two parents from unrelated lineages
# After running the merge, you may see:
Auto-merging README.md
CONFLICT (add/add): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
# Resolve conflicts
vim README.md # Edit to resolve
git add README.md
git commit # Creates the merge commit
Compare File Changes Visually
Use SecureBin's Diff Checker to compare conflicting file versions side-by-side before resolving merge conflicts.
Open Diff CheckerWhen NOT to Use --allow-unrelated-histories
The flag bypasses a safety check. Do not use it when:
- You are merging two different projects by mistake. If you accidentally added the wrong remote, fix the remote URL instead of forcing the merge.
- History was rewritten by force-push and you have local work. The correct fix is
git fetch origin && git reset --hard origin/main(if you have no local changes to keep) or a careful rebase. - You do not understand why the histories are unrelated. Investigate first. Run
git log --oneline --all --graphto visualize the branch topology and understand the root cause before bypassing the check.
Safer Alternatives
Alternative 1: Clone Instead of Init
The cleanest way to avoid this entirely is to clone the remote repo first, then add your files:
# Instead of git init + git remote add
git clone git@github.com:user/my-project.git
cd my-project
# Now add your files - histories are already connected
Alternative 2: Rebase Instead of Merge
Rebasing replays your local commits on top of the remote branch, creating a linear history without a merge commit:
# Fetch the remote branch
git fetch origin
# Rebase your local commits onto origin/main
git rebase origin/main
# If that fails with the same error, use:
git rebase --onto origin/main --root
This is often cleaner than a merge when one side has only a few commits (like the initial README on GitHub). Your local commits get new hashes but the history reads linearly.
Alternative 3: Start Fresh from the Remote
If your local work is small, the simplest approach is to clone the remote and copy your files in:
# Save your local work
cp -r my-project my-project-backup
# Clone the remote
git clone git@github.com:user/my-project.git my-project-clean
cd my-project-clean
# Copy your files (excluding .git)
cp -r ../my-project-backup/src ./src
cp ../my-project-backup/package.json .
# Commit
git add .
git commit -m "Add project source files"
git push origin main
Alternative 4: Replace History (Nuclear Option)
If you want the remote to match your local history exactly, discarding the remote's history:
# WARNING: This destroys the remote's existing history
git push --force origin main
Only do this if you are the sole contributor and the remote's commits (like the auto-generated README) are not needed. On shared repositories, force-pushing to main is destructive and should never be done without team coordination.
Real-World Scenarios
GitHub Repo Created with README + Local Project
The most searched scenario. You have a local project you want to push to a new GitHub repo, but you checked "Initialize this repository with a README" on GitHub.
Best approach:
# Option A: Pull with allow-unrelated-histories
git remote add origin git@github.com:user/repo.git
git fetch origin
git pull origin main --allow-unrelated-histories
# Resolve any conflicts (likely just README.md)
git push origin main
# Option B (cleaner): Delete the GitHub repo's initial commit
# Go to GitHub Settings > Delete repository
# Recreate without "Initialize with README"
# Then push normally:
git remote add origin git@github.com:user/repo.git
git push -u origin main
Monorepo Subtree Import
You are importing an external repository as a subdirectory of your monorepo:
# Using git subtree (recommended for this use case)
git subtree add --prefix=packages/library \
git@github.com:org/library.git main --squash
# Or with read-tree for more control
git remote add library git@github.com:org/library.git
git fetch library
git read-tree --prefix=packages/library -u library/main
git commit -m "Import library as packages/library"
The git subtree add command handles unrelated histories internally without needing the flag.
CI Pipeline Shallow Clone
Your CI pipeline uses --depth 1 for speed, and a merge operation fails:
# In your CI config, fetch enough history
git fetch --deepen=100
# Or fetch full history for this branch
git fetch --unshallow
# GitHub Actions example:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history instead of depth 1
Verifying the Fix
After resolving the unrelated histories merge, verify the result:
# Check that both histories are now connected
git log --oneline --graph --all | head -20
# Verify the merge commit has two parents
git cat-file -p HEAD
# Should show two "parent" lines
# Confirm remote tracking is set
git branch -vv
The Bottom Line
The "refusing to merge unrelated histories" error is Git protecting you from accidentally merging two disconnected commit trees. In most cases, it happens because you initialized a local repo separately from the remote. The fix is --allow-unrelated-histories on the pull or merge command. But before you use it, confirm that merging is actually what you want. If the histories are unrelated because you are pulling from the wrong remote, or because someone rewrote history, the flag will create a messy merge that masks the real problem. Understand the cause first, then pick the right solution.
Related Articles
Continue reading: Fix Docker OOM Killed, Fix Kubernetes CrashLoopBackOff, Detect Secrets in GitHub Repositories, How to Secure API Keys in Code, Fix Let's Encrypt Renewal Failed.
Usman has 10+ years of experience securing enterprise infrastructure, managing high-traffic servers, and building zero-knowledge security tools. Read more about the author.