DevOpsil
Git
85%
Needs Review

Fix Git 'fatal: refusing to merge unrelated histories'

Amara OkaforAmara Okafor4 min read

The Error

You run git pull or git merge and Git refuses:

fatal: refusing to merge unrelated histories

This typically happens when pulling from a remote into a local repository that was initialized independently, or when merging two branches that have no shared commit history.

Root Cause

Git tracks history as a directed acyclic graph (DAG) of commits. When two branches share a common ancestor commit, Git can compute a merge base and perform a three-way merge. When there is no common ancestor, Git considers the histories "unrelated" and refuses to merge by default.

This safety check was added in Git 2.9 to prevent accidental merges of completely separate projects. Common scenarios that trigger it:

  1. You created a local repo with git init, added commits, then tried to pull from a remote that also has its own initial commit (e.g., GitHub created the repo with a README).
  2. You are combining two separate repositories into one.
  3. A shallow clone lost the common history due to --depth limiting.
  4. You re-initialized a repository (deleted .git and ran git init again) and are now trying to pull the old remote.

Step-by-Step Fix

1. Understand what you are merging

Before forcing the merge, verify you are merging the right things:

git log --oneline -5
git log --oneline -5 origin/main

Confirm that these are genuinely related codebases you intend to combine, not completely unrelated projects.

2. Allow unrelated histories

Add the --allow-unrelated-histories flag:

# For pull
git pull origin main --allow-unrelated-histories

# For merge
git merge origin/main --allow-unrelated-histories

This tells Git to proceed with the merge even without a common ancestor. Git will treat each side's entire history as new changes.

3. Resolve merge conflicts

Since the histories are unrelated, you will likely have conflicts, especially in common files like README.md, .gitignore, or package.json:

# See which files conflict
git status

# Open and resolve each conflict
# Look for <<<<<<< HEAD markers

# After resolving
git add .
git commit -m "Merge remote history into local repository"

4. If you want the remote to completely replace local history

When your local commits are throwaway and you just want the remote content:

git fetch origin
git reset --hard origin/main

Warning: This discards all local commits and working directory changes.

5. For shallow clone issues

If a shallow clone caused the problem, deepen the history:

git fetch --unshallow origin
git pull origin main

Or if that is not possible, fetch with more depth:

git fetch --depth=1000 origin
git merge origin/main

6. The clean start approach

If the repository is in a messy state and you just want to start fresh from the remote:

cd ..
mv my-project my-project-backup
git clone [email protected]:user/my-project.git
# Copy over any local changes you need from the backup

Prevention Tips

  • Do not initialize with a README on GitHub if you already have local commits. When creating a new repo on GitHub, leave it empty (no README, no .gitignore, no license) if you plan to push an existing local repo.
  • Clone instead of init when a remote exists. If the repo already has history on a remote, use git clone rather than git init followed by git remote add.
  • Avoid re-initializing repositories. If you need to fix a repo issue, almost everything can be resolved without deleting the .git directory.
  • Use --depth carefully. Shallow clones are useful for CI/CD but can cause merge issues. Use --unshallow when you need full history for merges.
Share:

Was this article helpful?

Amara Okafor
Amara Okafor

DevSecOps Lead

Security-first mindset in everything I ship. From zero-trust architectures to supply chain security, I make sure your pipeline doesn't become your weakest link.

Related Articles

GitQuick RefBeginnerNeeds Review

Git Commands: Cheat Sheet

Git commands cheat sheet for DevOps engineers — branching, rebasing, stashing, bisecting, cherry-picking, and recovery workflows with examples.

Sarah Chen·
3 min read

More in Git

View all →

Discussion