How to Fix Git Pull Errors: Divergent Branches, Fast-Forward, and Unrelated Histories
Running git pull is usually straightforward, but when your local repository's history doesn't align with the remote server, Git stops the operation to prevent you from losing your work. This results in errors like:
fatal: Not possible to fast-forward, aborting.Hint: You have divergent branches and need to specify how to reconcile them.fatal: refusing to merge unrelated histories
Because git pull is a shortcut for running git fetch followed by git merge, you must explicitly tell Git how to reconcile these divergent histories. This guide walk you through how to fix each of these errors.
Error 1: "Divergent Branches" & "Not Possible to Fast-Forward"
The Cause
This warning occurs when both your local branch and the remote branch have moved forward independently.
Remote: A --- B --- C (Origin/Main)
\
Local: A --- B ------- D (Main)
Because commit D exists locally but not on the remote, and commit C exists on the remote but not locally, Git cannot perform a simple fast-forward (which just slides the branch pointer forward). Doing so without merging or rebasing would delete your local commit D.
To resolve this, you must choose one of three strategies:
Solution A: Rebase (Recommended for Private Branches)
Rebasing takes your local commits, stashes them temporarily, pulls the remote commits, and then replays your local commits on top of the remote history. This keeps your git log linear and free of merge commits.
To run it for a single pull:
git pull --rebase origin main
To configure it globally for all your projects:
git config --global pull.rebase true
Handling Rebase Conflicts
If your local changes overlap with the remote changes, Git will pause the rebase.
- Open the conflicting files and resolve the code manually.
- Stage the resolved files:
git add . - Continue the rebase:
git rebase --continue(do not commit manually).
Solution B: Merge (Safe for Shared/Public Branches)
Merging combines both histories by creating a new merge commit. This is the safest default when working on branches shared with other developers, as it does not rewrite existing commit history.
To run it for a single pull:
git pull --no-rebase
To configure it globally:
git config --global pull.rebase false
Solution C: Fast-Forward Only
This strategy forces Git to only pull if a fast-forward is possible. If the branches have diverged, the pull will fail, prompting you to manually inspect and resolve the differences.
To run it for a single pull:
git pull --ff-only
To configure it globally:
git config --global pull.ff only
Error 2: "fatal: refusing to merge unrelated histories"
The Cause
This error occurs when you try to merge two branches that do not share a common ancestor commit. This typically happens when you initialize a brand new local repository, create some files, and then try to pull from a remote repository that already has its own commits.
git init
git remote add origin https://github.com/user/repo.git
git pull origin main
# fatal: refusing to merge unrelated histories
Solution: Force the Merge with --allow-unrelated-histories
If you want to merge these two unrelated histories together, use the --allow-unrelated-histories flag:
git pull origin main --allow-unrelated-histories
This will force Git to merge the two independent histories, creating a new merge commit.
- If files with the same name exist in both projects, Git will pause. Open the files, resolve conflicts, run
git add ., and complete the merge withgit commit.
Alternative: Clone Instead of Init (Best Practice)
To avoid this issue entirely, do not run git init followed by a pull. Instead, delete the local directory and clone the remote repository directly:
git clone https://github.com/user/repo.git
Cloning automatically copies the remote's history and links your local tracking branch correctly.
Summary of Reconcile Commands
| Strategy | Command | Git History Result | Use Case |
|---|---|---|---|
| Rebase | git pull --rebase | Linear (No merge commits) | Personal feature branches. |
| Merge | git pull --no-rebase | Non-linear (Creates merge commit) | Shared public branches. |
| FF-Only | git pull --ff-only | Linear (Fails if diverged) | Automated environments or release branches. |
| Unrelated Histories | git pull origin main --allow-unrelated-histories | Merged (Creates merge commit) | Merging two independent projects. |
Sources
- [1] Git Reference Documentation: git-pull
- [2] Atlassian Git Tutorials: Syncing and Pulling
- [3] Git Book: The Golden Rule of Rebasing
- [4] Git Reference Documentation: git-push
