How to Fix Refusing to Merge Unrelated Histories Safely
Why git pull stops with fatal: refusing to merge unrelated histories, the one-time --allow-unrelated-histories fix, when it's safe, and how to verify the merge.

git pull stops with this message when the branch you're pulling and the branch you're on don't share a single commit. Git's merge works by finding a common ancestor and reconciling both sides against it. When no such commit exists, it refuses rather than guess.
fatal: refusing to merge unrelated histories
The fix is to tell git, once, that you really do want to join two independent histories. Replace main with the branch you're pulling:
git pull origin main --allow-unrelated-histories
That creates a merge commit with two parents, one from each history. From then on the two sides share that commit, so ordinary git pull works again and you never need the flag for this repository. The rest of this page covers why it happens, when the flag is the right call, what to do about conflicts, and how to check the result before you push.
Why git says refusing to merge unrelated histories#
The git merge documentation describes a merge as incorporating changes "since the time their histories diverged from the current branch". That phrase assumes the histories did diverge from something. A three-way merge needs a base commit, your tip, and their tip. If two histories have no common commit, there is no base, and by default git refuses.
The same page explains the override: --allow-unrelated-histories exists "for merging histories of two projects that started their lives independently", calls that "a very rare occasion", and states that no configuration variable to enable it by default exists or will be added. That design choice tells you how to think about the error. It's a safety check, not a bug, and the maintainers want you to make the decision explicitly every time.
git pull is fetch followed by merge, which is why you usually meet this error during a pull rather than a plain merge. The common triggers are:
- A new GitHub repo plus a local
git init. You created the repository on GitHub with a README, license, or.gitignore, so it has one commit. Locally you rangit init, committed your code, added the remote, and pulled. Two root commits, nothing shared. - Combining two real projects. You're importing a standalone repo into another one and want to keep both histories.
- A re-initialized repository. Someone deleted the
.gitdirectory, rangit initagain, and committed. The remote still has the old history. - A rewritten upstream. The remote branch was replaced with history that shares no commit with your clone.
The first case is by far the most common, and it's also the case where the flag is almost always safe. The last two cases deserve a pause, covered below.
Here's a small model of the check git performs. Each commit lists its parents, and the question is whether two tips have any ancestor in common:
# Minimal model of how git decides whether two histories are related.
# Each commit maps to the list of its parent commits.
history = {
"L1": [], # your first local commit (git init + commit)
"L2": ["L1"],
"R1": [], # "Initial commit" created on GitHub with a README
}
def ancestors(commit):
seen, stack = set(), [commit]
while stack:
c = stack.pop()
if c in seen:
continue
seen.add(c)
stack.extend(history[c])
return seen
def common(a, b):
return ancestors(a) & ancestors(b)
print("Before the merge:")
print(" common ancestors of L2 and R1:", sorted(common("L2", "R1")) or "none")
print(" git merge refuses:", not common("L2", "R1"))
# A merge commit with both tips as parents ties the histories together.
history["M"] = ["L2", "R1"]
history["R2"] = ["R1"] # a teammate pushes another commit later
print("After merge commit M:")
print(" common ancestors of M and R2:", sorted(common("M", "R2")))
print(" flag needed again:", not common("M", "R2"))
The merge commit is what fixes things permanently. Once it exists, every future pull has a shared ancestor to work from.
The fix for git pull, step by step#
Start from a clean working tree. The merge docs warn that running a merge with non-trivial uncommitted changes "may leave you in a state that is hard to back out of", and git pull will stop anyway if local changes overlap files it needs to update. Commit or stash first.
git status
git stash # only if you have changes you want to keep
git pull origin main --allow-unrelated-histories
Git opens your editor with a default merge message. Save and close it to finish. If you'd rather supply the message inline:
git pull origin main --allow-unrelated-histories -m "Merge GitHub initial commit into local history"
If your git is configured to rebase on pull, the flag does nothing. The git pull documentation lists --allow-unrelated-histories as "only useful when merging". Force a merge for this one pull with --no-rebase:
git pull --no-rebase --allow-unrelated-histories origin main
The same thing as a separate fetch and merge, which is easier to reason about if something goes wrong:
git fetch origin
git merge --allow-unrelated-histories origin/main
To inspect the result before anything is committed, add --no-commit. Git performs the merge, updates the index and working tree, and stops just short of creating the commit:
git fetch origin
git merge --no-commit --allow-unrelated-histories origin/main
git status
# happy? finish it:
git commit
# not happy? back out:
git merge --abort
How to confirm it worked: git status reports a clean tree, git log shows a new merge commit at the top with two parents, and running git pull again prints Already up to date.
When allowing unrelated histories is safe and when it isn't#
The flag is safe when all three are true:
- You know why the histories are unrelated. For the GitHub-README case, the answer is obvious.
- You want the content of both sides in the result.
- You're prepared to resolve conflicts in files that exist on both sides, typically
README.md,.gitignore, orLICENSE.
It's the wrong tool when you expected the histories to be related. If this is a repository you've been pulling from for months and the error appeared out of nowhere, the unrelated history is a symptom. Likely causes are a remote URL pointing at a different repository, pulling the wrong branch, a re-initialized .git directory, or an upstream history that was replaced. Merging in that situation stitches two copies of the same project together, doubles the history, and produces a wall of conflicts. Look at what you're about to merge first:
git fetch origin
git log origin/main
If the remote history looks like the project you already have, stop and find out what changed. If your local commits are throwaway and the remote is the source of truth, the cleaner fix is a fresh git clone and copying your working files in, with no merge at all.
Two variations are useful when you've decided to merge but want control over the content:
- Keep your tree, record their history. The
oursmerge strategy keeps "the resulting tree of the merge" identical to your current branch while still creating a merge commit that ties the histories together. Everything on their side is ignored, so only do this when their content is disposable.
git merge -s ours --allow-unrelated-histories origin/main
- Auto-resolve conflicts one way. The
-X oursand-X theirsoptions to the defaultortstrategy only decide conflicting hunks. Non-conflicting changes from both sides are kept. Don't confuse-X ourswith-s ours; the git pull docs call this out explicitly.
git merge -X theirs --allow-unrelated-histories origin/main
Handling conflicts after the merge starts#
Two independent projects often both have a README.md, and git can't merge files with no shared base version cleanly. You'll see conflict markers in the file and git status will list it as both modified. The merge isn't done yet: HEAD stays where it was and MERGE_HEAD points at the other side.
git ls-files -u # which paths are still conflicted
# edit each file, remove the <<<<<<< ======= >>>>>>> markers
git add README.md
git merge --continue # or: git commit
If the conflicts are worse than expected, abort and think again:
git merge --abort
That works for a pull as well as a plain merge, because the merge docs describe --abort as equivalent to git reset --merge whenever MERGE_HEAD is present. It restores the pre-merge state, with the caveat already mentioned: uncommitted changes present when the merge started may not come back cleanly.
How to verify the merged history#
Don't push until you've checked three things.
The merge commit has two parents. Run git log. The top entry should be a merge commit listing both parent commits, the previous tip of your branch and the tip you pulled in. Further down you'll see two separate root commits, one per original project. That's expected, and it's exactly what makes the result "related" from now on.
The content is what you intended. Before the merge, git sets ORIG_HEAD to your previous tip, so you can diff the whole operation in one command:
git diff ORIG_HEAD
Read through it. Files that only existed on the remote side show up as additions. Files you resolved by hand should contain exactly what you chose, with no leftover markers.
A second pull is a no-op. The merge docs say that when all named commits are already ancestors of HEAD, git exits early with Already up to date. If you see the unrelated-histories error again instead, the merge commit wasn't created, usually because of --squash (see the gotchas below).
If the result is wrong and you haven't pushed, undo it. This resets your branch, index, and working tree back to the pre-merge tip, so make sure nothing uncommitted matters to you:
git reset --merge ORIG_HEAD
After verification, git push should be a plain fast-forward on the remote, because your merge commit descends from the remote tip you just pulled. If the push is rejected, someone pushed in between, and the steps in fixing a rejected non-fast-forward push apply as usual. If you ended up on a detached HEAD while poking around commits, recovering from a detached HEAD covers getting your work back onto a branch.
Fixing it in IntelliJ, SourceTree, Visual Studio and other GUIs#
Every Git GUI runs the same git merge underneath, so the error text is identical whether it appears in an IDE log panel or a terminal. The official git docs don't describe any particular client's dialogs, so the dependable path is the command line:
- Open a terminal in the repository root. Most IDEs have a built-in terminal that already sits there.
- Run the one-time command:
git pull origin main --allow-unrelated-histories. - Resolve conflicts in the IDE's merge tool if you prefer, then stage and commit.
- Refresh the GUI. It'll pick up the new merge commit from the repository on disk.
One thing to check inside the IDE: if its pull action is set to rebase, the flag won't apply, because it's only meaningful for a merge. Either switch the pull mode to merge for that one operation or use --no-rebase in the terminal as shown earlier.
Common mistakes and gotchas#
- Looking for a way to force it. There's no
--forcefor merge. The override is--allow-unrelated-histories, and if what you want is "take mine, ignore theirs", that's the-s oursstrategy, not a force flag. - Looking for a config setting. There isn't one, on purpose. The docs say no configuration variable "exists or will be added". You pass the flag exactly once per combined history.
- Using it to paper over a wrong remote. If the error surprised you in a repo that used to pull fine, the flag will succeed and leave you with a doubled history. Inspect the remote branch with
git log origin/mainbefore merging. - Combining it with --squash.
--squashbuilds the merged tree but, in the words of the docs, does not record the merge information and doesn't setMERGE_HEAD. Your next pull sees two unrelated histories all over again. - Expecting it to work with rebase. With
pull.rebaseset or--rebaseon the command line, the flag is ignored. Use--no-rebasefor this pull. - Merging over uncommitted work. If conflicts appear,
git merge --abortmay not be able to restore your uncommitted changes. Commit or stash first. - Forgetting to clean up the README duplicate. After the merge you'll often have your own
README.mdcontent and GitHub's placeholder stitched together. Resolve it properly rather than committing both halves.
Quick reference#
| Situation | Command |
|---|---|
New GitHub repo plus local git init |
git pull origin main --allow-unrelated-histories |
| Pull is configured to rebase | git pull --no-rebase --allow-unrelated-histories origin main |
| Inspect before committing | git merge --no-commit --allow-unrelated-histories origin/main |
| Keep my files, record their history | git merge -s ours --allow-unrelated-histories origin/main |
| Prefer their side on conflicting hunks | git merge -X theirs --allow-unrelated-histories origin/main |
| List conflicted paths | git ls-files -u |
| Finish after resolving | git merge --continue |
| Back out of an in-progress merge | git merge --abort |
| Review what the merge changed | git diff ORIG_HEAD |
| Undo a finished, unpushed merge | git reset --merge ORIG_HEAD |
Checklist before you push:
- You know why the two histories are unrelated and you want both.
- Working tree was clean before the merge.
git logshows a merge commit with two parents at the top.git diff ORIG_HEADshows only the content you expect.git pullnow reportsAlready up to date.
For the full option list, the git merge reference and the git reset reference are the pages to keep open.
Quick answers
What does fatal: refusing to merge unrelated histories mean?
The branch you're on and the branch you're merging or pulling have no commit in common, so git can't find a base for a three-way merge. By default it refuses instead of guessing, and the error appears most often after creating a GitHub repo with a README and then running git init locally.
How do I fix refusing to merge unrelated histories in git pull?
Commit or stash local changes, then run git pull origin main --allow-unrelated-histories, replacing main with your branch. Git creates a merge commit with both histories as parents, and future pulls work without the flag.
Is there a force option for refusing to merge unrelated histories?
No. The override is --allow-unrelated-histories, and there is no config setting to enable it permanently by design. If you want to keep only your files while still joining the histories, use the ours merge strategy with -s ours.
How do I fix it in IntelliJ, SourceTree or Visual Studio?
These tools run the same git merge underneath. Open a terminal in the repository root, run the pull with --allow-unrelated-histories, resolve any conflicts, then refresh the GUI. If the IDE pulls with rebase, add --no-rebase, since the flag only applies to merges.
Does the flag work with git pull --rebase?
No. The git pull documentation lists --allow-unrelated-histories as only useful when merging, so with pull.rebase set or --rebase given it has no effect. Use --no-rebase for the one pull that joins the histories.
Did this solve it?
One tap. No account.
Sorry about that. What was missing?
from 0 readers
Saved you an hour? Send a tip.
USDC or ETH on Base, Ethereum, Arbitrum and more. Keeps the notes free and the examples running.
Network
0xc783bc5c3fa14cEC3f09A22284bC91C5AF0d59e1
On a computer? Scan the code with your phone wallet, or copy the address.
Pick the network your wallet or exchange uses. USDC works on all six; ETH on Base, Ethereum, Arbitrum and Optimism. Don't send on Tron or Solana: this address doesn't exist there. Tips are optional and unlock nothing; every guide stays free.
Discussion
Start the discussion
Next note