TraceDynamics
Version Control

Git 'refusing to merge unrelated histories': Causes and Fixes

Git says fatal: refusing to merge unrelated histories? Learn why two repos share no common commit, and fix it with a merge or a rebase without losing work.

On this page
  1. Why Git refuses
  2. What you may see before it, on current Git
  3. Fix 1: merge the two histories
  4. Fix 2: rebase your work on top of the remote
  5. Merge or rebase?
  6. When you should not use the flag
  7. Avoid it next time

You created a repository on GitHub with a README, then ran git init on your laptop and committed some code. You add the remote and try to bring the two together:

Shell
git merge origin/main
Output
fatal: refusing to merge unrelated histories

Nothing is broken. Git is telling you that the two branches have no commit in common, so it has no starting point from which to combine them, and it will not guess.

Why Git refuses#

Every commit points back to its parent, forming a chain. Two branches can be merged because their chains meet at some shared ancestor, called the merge base. Here the chains never meet. The remote's first commit and your first commit are different roots.

You can prove this in two commands. First, list the root commit on each side. A normal project has exactly one root, and both branches share it. Here they differ:

Shell
git rev-list --max-parents=0 HEAD
git rev-list --max-parents=0 origin/main
Output
0f4402568a470b34237a569ee3bbfa868d1033b3
75ac1ed6b2b484b3cc0d1e1287e2431840e32db8

Second, ask Git for the merge base directly. It prints nothing and exits with status 1 when there is none:

Shell
git merge-base HEAD origin/main
echo "exit code: $?"
Output
exit code: 1

If you see two different roots and no merge base, you have exactly this problem. The usual causes are initialising a local repository and creating a README on the hosting site, copying a project into a fresh repo, or pointing a remote at the wrong repository.

What you may see before it, on current Git#

On a recent Git with no pull.rebase setting, a bare git pull stops earlier with a different message:

Output
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.

That is a separate prompt asking how you want to combine the branches. Pick a strategy and the real error appears. Either of these reaches it:

Shell
git pull --no-rebase origin main
Output
fatal: refusing to merge unrelated histories

Fix 1: merge the two histories#

If you want to keep both histories intact, tell Git you know they are unrelated:

Shell
git merge --allow-unrelated-histories origin/main -m "Merge remote history"
Output
Merge made by the 'ort' strategy.
 README.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

The result is a single merge commit with two parents, one from each history:

Output
*   e9c2cf5 Merge remote history
|\
| * 75ac1ed Initial commit from GitHub
* c7652cc First local commit

If both sides have a file with the same name#

The most common collision is a README.md on both sides. Git cannot choose between two files that were each added independently, so it stops with an add/add conflict:

Output
Auto-merging README.md
CONFLICT (add/add): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

Open the file and you will see both versions between conflict markers:

Output
<<<<<<< HEAD
# My notes
=======
# Project
>>>>>>> origin/main

Edit the file to the content you want, delete the three marker lines, then finish the merge:

Shell
git add README.md
git commit -m "Merge remote history"

If you would rather start over, git merge --abort returns you to exactly where you were before the merge.

Fix 2: rebase your work on top of the remote#

If you prefer a straight line with no merge commit, rebase your commits onto the remote branch instead:

Shell
git pull --rebase origin main
Output
Rebasing (1/1)Successfully rebased and updated refs/heads/main.
Output
* 9ec1a4f First local commit
* 75ac1ed Initial commit from GitHub

Your commit is replayed after the remote's first commit, so the history is linear. Afterwards the two branches share a base, and the problem is gone for good:

Shell
git merge-base HEAD origin/main
Output
75ac1ed6b2b484b3cc0d1e1287e2431840e32db8

Merge or rebase?#

What differs Merge Rebase
History Keeps both, with one extra merge commit One straight line
Your commit hashes Unchanged Rewritten
Safe if you already pushed your commits Yes Only if no one else has them
Conflicts Resolved once May appear once per replayed commit

For a brand-new local project that nobody else has pulled, rebase is usually the tidier choice. If your commits are already shared, merge.

When you should not use the flag#

The flag exists for the case where you really do have two unrelated histories that belong together. If you did not expect that, stop and check before forcing it:

Shell
git remote -v
git log --oneline origin/main

If the remote URL is wrong, or origin/main contains a project you do not recognise, --allow-unrelated-histories will happily weld two different projects into one. Fix the remote instead. Related errors worth knowing: updates were rejected because the tip of your branch is behind, and what git pull --force really does.

Avoid it next time#

  • If a remote already exists, clone it rather than running git init and adding it by hand.
  • If you are pushing an existing local project to a new hosting repository, create the remote empty, with no README, license or .gitignore.
  • To bring changes from another branch into yours, see merging master into a branch.
Advertisement
esc

↑↓ navigate↵ openesc close