{"id":39,"date":"2026-07-15T00:00:00","date_gmt":"2026-07-15T00:00:00","guid":{"rendered":"http:\/\/\/var\/www\/html\/?p=39"},"modified":"2026-07-21T01:02:32","modified_gmt":"2026-07-21T01:02:32","slug":"git-command-line-fatal-refusing-to-merge-unrelated-histories-on-ubuntu-2004-lts","status":"publish","type":"post","link":"https:\/\/butitworkedlocal.com\/git-command-line-fatal-refusing-to-merge-unrelated-histories-on-ubuntu-2004-lts\/","title":{"rendered":"Resolving Git &#8216;fatal: refusing to merge unrelated histories&#8217; on Ubuntu 20.04 LTS"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Fix the Git &#039;refusing to merge unrelated histories&#039; error when pulling or merging disparate repositories on Ubuntu 20.04. Learn the root cause and resolution.<\/strong><\/p>\n\n\n<p>This guide addresses a common Git error encountered by developers and system administrators on Ubuntu 20.04 LTS servers: &quot;fatal: refusing to merge unrelated histories&quot;. This error typically arises when attempting to merge or pull changes from a remote repository into a local one that Git deems to have no common ancestral commits. While seemingly a blocking issue, Git provides a clear mechanism to resolve it, ensuring your project histories can be aligned.<\/p>\n<h3>Symptom &amp; Error Signature<\/h3>\n<p>When you attempt to integrate changes from a remote Git repository into your local working copy, typically using <code>git pull<\/code> or <code>git merge<\/code>, you might encounter the following error message in your terminal:<\/p>\n<pre><code class=\"language-bash\">$ git pull origin main\nFrom github.com:your-organization\/your-repository\n * branch            main       -&gt; FETCH_HEAD\nfatal: refusing to merge unrelated histories\n<\/code><\/pre>\n<p>Or, if you&#039;re trying a direct merge:<\/p>\n<pre><code class=\"language-bash\">$ git merge origin\/main\nfatal: refusing to merge unrelated histories\n<\/code><\/pre>\n<p>This error halts the pull\/merge operation, leaving your local repository in its current state without integrating the remote changes.<\/p>\n<h3>Root Cause Analysis<\/h3>\n<p>The &quot;fatal: refusing to merge unrelated histories&quot; error is a safety mechanism introduced in Git version 2.9 (released June 2016). Prior to this version, Git would attempt to merge any two branches you specified, even if they had no common commit history, potentially leading to a confusing and possibly destructive merge.<\/p>\n<p>Git&#039;s core principle is to build a directed acyclic graph (DAG) of commits. When you try to merge two branches, Git normally expects to find a common ancestor commit from which both branches diverged. If no such common ancestor exists, Git considers their histories &quot;unrelated.&quot;<\/p>\n<p>Common scenarios that lead to unrelated histories include:<\/p>\n<ol>\n<li><strong>Initializing an Empty Local Repo, Pulling from Existing Remote<\/strong>: You create a new project directory, run <code>git init<\/code>, and then try to <code>git pull<\/code> from an existing remote repository that already has commits (e.g., a <code>README.md<\/code> or initial project files). Your local <code>HEAD<\/code> has no commits, and the remote <code>HEAD<\/code> has a history, so they don&#039;t share a common ancestor.<\/li>\n<li><strong>Remote Repository Initialized Separately<\/strong>: You create an empty repository on a platform like GitHub or GitLab, and then initialize it <em>directly on the web interface<\/em> by adding a <code>README.md<\/code>, <code>.gitignore<\/code>, or license file. Simultaneously, you create a local repository with <code>git init<\/code> and some initial commits <em>without<\/em> cloning the remote. When you later try to <code>git pull<\/code> from the remote into your local repo, their histories are unrelated.<\/li>\n<li><strong>Restoring from a &quot;Working Directory&quot; Backup<\/strong>: If you only backed up the <code>.git<\/code> folder along with the working directory, and then restored it, or if you only backed up the working directory and then re-initialized Git with <code>git init<\/code>, the new local <code>.git<\/code> history might not align with the remote&#039;s history graph if not handled carefully.<\/li>\n<li><strong>Accidental Parallel Development<\/strong>: Two separate projects were started, both initialized as Git repositories, and later an attempt is made to merge them as if they were branches of a single project.<\/li>\n<\/ol>\n<p>In essence, Git is preventing what it perceives as an attempt to merge two entirely distinct timelines, which could obscure project history or introduce unexpected changes.<\/p>\n<h3>Step-by-Step Resolution<\/h3>\n<p>The primary and recommended solution involves explicitly telling Git to allow merging of unrelated histories using the <code>--allow-unrelated-histories<\/code> flag.<\/p>\n<h4>1. Understanding the <code>allow-unrelated-histories<\/code> Flag<\/h4>\n<p>This flag instructs Git to proceed with the merge even if it cannot find a common ancestor between the two histories. When this flag is used, Git treats the first commit of one history and the first commit of the other history as their common base for the merge, effectively creating a merge commit that bridges the two distinct histories.<\/p>\n<blockquote class=\"important\"><p>Use this flag with caution. While it resolves the immediate error, ensure you understand <em>why<\/em> the histories are unrelated. This action cannot be easily undone without rewriting history, which can be problematic in collaborative environments.<\/p>\n<\/blockquote>\n<h4>2. Safely Merging Unrelated Histories (Recommended Approach)<\/h4>\n<p>This method preserves both local and remote histories, combining them into a new merge commit.<\/p>\n<h5>2.1 Verify Current Status and Remote Configuration<\/h5>\n<p>Before proceeding, ensure your local repository is clean and correctly configured to point to the remote.<\/p>\n<pre><code class=\"language-bash\"># Check for any uncommitted local changes (commit or stash them if necessary)\ngit status\n\n# Verify your remote configuration\ngit remote -v\n<\/code><\/pre>\n<p>Expected output for <code>git remote -v<\/code>:<\/p>\n<pre><code>origin  https:\/\/github.com\/your-organization\/your-repository.git (fetch)\norigin  https:\/\/github.com\/your-organization\/your-repository.git (push)\n<\/code><\/pre>\n<h5>2.2 Fetch Remote Changes (Optional, but Good Practice)<\/h5>\n<p>It&#039;s often good practice to first fetch all remote changes without merging them. This allows you to inspect the remote&#039;s history if needed.<\/p>\n<pre><code class=\"language-bash\">git fetch origin\n<\/code><\/pre>\n<h5>2.3 Perform the Merge with <code>--allow-unrelated-histories<\/code><\/h5>\n<p>Now, execute the <code>git pull<\/code> or <code>git merge<\/code> command with the crucial flag. Assuming you want to pull from the <code>main<\/code> branch of your <code>origin<\/code> remote:<\/p>\n<pre><code class=\"language-bash\">git pull origin main --allow-unrelated-histories\n<\/code><\/pre>\n<p>If you prefer to <code>fetch<\/code> and then <code>merge<\/code> manually:<\/p>\n<pre><code class=\"language-bash\">git merge origin\/main --allow-unrelated-histories\n<\/code><\/pre>\n<p>Git will then attempt to merge the two histories.<\/p>\n<h5>2.4 Resolve Merge Conflicts (If Any)<\/h5>\n<blockquote class=\"important\"><p>It is highly probable that you will encounter merge conflicts after using <code>--allow-unrelated-histories<\/code>, especially if both histories have different files or different versions of the same files at their respective roots (e.g., two different <code>README.md<\/code> files).<\/p>\n<\/blockquote>\n<p>Your terminal will indicate any conflicting files:<\/p>\n<pre><code>Auto-merging README.md\nCONFLICT (add\/add): Merge conflict in README.md\nAutomatic merge failed; fix conflicts and then commit the result.\n<\/code><\/pre>\n<ol>\n<li><strong>Open the conflicting files<\/strong> in your preferred text editor (e.g., <code>nano<\/code>, <code>vim<\/code>, <code>vscode<\/code>).<\/li>\n<li><strong>Identify and resolve conflicts<\/strong>: Git marks conflicts with <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt;<\/code>, <code>=======<\/code>, and <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt;<\/code>.<pre><code class=\"language-markdown\">&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD\nThis is the content from my local repository.\n=======\nThis is the content from the remote repository.\n&gt;&gt;&gt;&gt;&gt;&gt;&gt; origin\/main\n<\/code><\/pre>\nEdit the file to include the desired content.<\/li>\n<li><strong>Stage the resolved files<\/strong>:<pre><code class=\"language-bash\">git add . # Or git add &lt;conflicting-file-1&gt; &lt;conflicting-file-2&gt;\n<\/code><\/pre>\n<\/li>\n<li><strong>Commit the merge<\/strong>: Git will typically provide a default merge commit message. You can accept it or modify it.<pre><code class=\"language-bash\">git commit -m &quot;Merge remote main with --allow-unrelated-histories and resolved conflicts&quot;\n<\/code><\/pre>\n<\/li>\n<\/ol>\n<h5>2.5 Push Changes to Remote (If Necessary)<\/h5>\n<p>Once the merge is complete and committed locally, you can push the new, unified history to your remote repository.<\/p>\n<pre><code class=\"language-bash\">git push origin main\n<\/code><\/pre>\n<h4>3. Alternative: Reinitialize Local Repository (Use with Caution)<\/h4>\n<p>This approach discards your local repository&#039;s history and state, effectively making it a fresh clone of the remote. This is suitable if your local repository has no important uncommitted changes, or if its history is completely irrelevant compared to the remote.<\/p>\n<h5>3.1 Backup Local Changes (If Any)<\/h5>\n<p>If you have any uncommitted or local-only committed changes that you wish to preserve, back them up.<\/p>\n<pre><code class=\"language-bash\"># Stash uncommitted changes\ngit stash push -m &quot;Pre-reinit local changes&quot;\n\n# Or, simply copy your entire project directory\ncp -r \/path\/to\/your\/project \/path\/to\/your\/project_backup_`date +%Y%m%d%H%M%S`\n<\/code><\/pre>\n<h5>3.2 Remove Local <code>.git<\/code> Directory<\/h5>\n<p>Navigate into your project directory and remove the hidden <code>.git<\/code> folder. This effectively de-initializes your local repository.<\/p>\n<pre><code class=\"language-bash\">cd \/path\/to\/your\/project\nrm -rf .git\n<\/code><\/pre>\n<h5>3.3 Re-clone the Remote Repository<\/h5>\n<p>Navigate to the parent directory of your project and clone the remote repository anew.<\/p>\n<pre><code class=\"language-bash\">cd \/path\/to\/parent\/directory\ngit clone https:\/\/github.com\/your-organization\/your-repository.git your_project_name\ncd your_project_name\n<\/code><\/pre>\n<h5>3.4 Restore and Reapply Local Changes (If Any)<\/h5>\n<p>If you stashed changes in step 3.1, you can now try to apply them. Be aware that conflicts might still occur if the remote has diverged significantly.<\/p>\n<pre><code class=\"language-bash\"># If you stashed changes and are in the newly cloned repo:\ngit stash pop\n\n# Alternatively, manually copy back specific files from your backup\ncp \/path\/to\/your\/project_backup\/your_file.js .\n<\/code><\/pre>\n<h4>4. Alternative: Force Push (Use with EXTREME Caution)<\/h4>\n<p>This option is generally NOT recommended in collaborative environments. It should only be used if you are absolutely certain that your local repository&#039;s history should <em>completely overwrite<\/em> the remote&#039;s history, and no one else is working on that branch.<\/p>\n<h5>4.1 Ensure Local Repository is Exactly What You Want<\/h5>\n<p>Make sure your local branch (<code>main<\/code> in this example) contains the exact history and files you want to be on the remote.<\/p>\n<h5>4.2 Force Push<\/h5>\n<pre><code class=\"language-bash\"># Safer variant: only forces if the remote branch hasn&#039;t been updated since your last pull\/fetch\ngit push --force-with-lease origin main\n\n# More aggressive variant: forces regardless of remote updates, can overwrite others&#039; work\n# Use with extreme caution, only if you are absolutely sure.\n# git push --force origin main\n<\/code><\/pre>\n<blockquote class=\"warning\"><p>The <code>git push --force-with-lease<\/code> or <code>git push --force<\/code> commands will overwrite the remote branch history! All commits on the remote that are not present in your local branch will be permanently lost. This can cause significant problems for other developers working on the same branch. Only use this if you are absolutely certain of the consequences and have communicated with your team, or if you are the sole contributor and are certain the remote history is undesirable.<\/p>\n<\/blockquote>\n<p>By understanding the root cause and carefully applying one of these resolution methods, particularly the <code>--allow-unrelated-histories<\/code> flag, you can effectively overcome the &quot;fatal: refusing to merge unrelated histories&quot; error and continue your development workflow on Ubuntu 20.04 LTS.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Fix the Git &#8216;refusing to merge unrelated histories&#8217; error when pulling or merging disparate repositories on Ubuntu 20.04. Learn the root cause and resolution.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[105],"tags":[40,106,107,6,13,108,109],"class_list":["post-39","post","type-post","status-publish","format-standard","hentry","category-git-ci-cd","tag-devops","tag-git","tag-merge","tag-troubleshooting","tag-ubuntu","tag-unrelated-histories","tag-version-control"],"_links":{"self":[{"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/posts\/39","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/comments?post=39"}],"version-history":[{"count":2,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/posts\/39\/revisions"}],"predecessor-version":[{"id":287,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/posts\/39\/revisions\/287"}],"wp:attachment":[{"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/media?parent=39"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/categories?post=39"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/tags?post=39"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}