Introduction
Have you encountered the following frustrating scenario when working with Git?
test-app$ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 1 and 2 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
test-app$ git pull
fatal: refusing to merge unrelated histories
test-app$
This error happens because the local repository and the remote repository have different commit histories, and Git doesn’t know how to reconcile them. In this post, we’ll walk through why this happens and the steps to fix it while transitioning to using a remote repository effectively.
Why Does This Error Occur?
The “unrelated histories” error occurs when:
- A local Git repository is initialized (
git init
) and has a different commit history than the remote repository. - A remote repository is created (e.g., on GitHub or GitLab) and populated independently.
When you attempt a git pull
, Git refuses to merge these distinct histories by default to avoid unintentional overwrites.
Step-by-Step Solution
Here’s how to resolve the issue and transition to using the remote repository as the source of truth:
1. Backup Your Work
Before making changes, always back up your local repository to prevent accidental data loss.
cp -r test-app test-app-backup
This ensures you have a copy of your local work if something goes wrong.
2. Reset Local Repository to Match Remote
If you decide to discard your local changes and use the remote repository as the authoritative source:
- Fetch the Remote Repository
Download the latest changes from the remote repository:git fetch --all
- Reset Local Branch
Force your local branch to match the remote branch:git reset --hard origin/master
This replaces the local history with the remote history.
- Verify the State
Check that your local repository is synchronized with the remote:git status
3. Incorporate Local Changes (Optional)
If you have local changes that you want to preserve and merge into the remote repository, follow these steps:
- Create a Backup Branch
Save your local state to a new branch:git branch local-backup
- Switch to the Remote Branch
Move to the remote branch:git checkout master
- Reapply Local Changes
Usegit cherry-pick
to apply specific commits from the local branch:git cherry-pick <commit-hash>
Replace
<commit-hash>
with the hash of your local commits. - Push Changes to the Remote Repository
Push your updated branch to the remote:git push origin master
4. Overwrite the Remote Repository (If Necessary)
If you’re confident that your local state is the correct one and should replace the remote repository:
- Force Push Local Changes
Replace the remote history with your local branch:git push --force origin master
⚠️ Warning: This will overwrite the remote branch history. Communicate with your team before using this command.
Best Practices to Avoid the Issue
- Clone the Remote Repository First: When starting a new project, always clone the remote repository instead of initializing a new one locally (
git init
). - Use
git pull --rebase
: This avoids unnecessary merge commits when synchronizing with the remote repository. - Keep Backup Branches: Before making destructive changes, always create a backup branch of your current work.
Conclusion
Git is a powerful tool, but it can be tricky to manage diverging histories between local and remote repositories. With the steps outlined above, you can resolve the “fatal: refusing to merge unrelated histories” error and effectively transition to using a remote repository.
Whether you choose to discard local changes, incorporate them into the remote repository, or overwrite the remote history, understanding the commands and their impact ensures you’re always in control of your version history.
Have any questions or tips for dealing with Git issues? Share them in the comments!