【完全ガイド】git fatal: refusing to merge unrelated histories の原因と解決方法|共通祖先・リポジトリ統合まで徹底解説

【完全ガイド】git fatal: refusing to merge unrelated histories の原因と解決方法|共通祖先・リポジトリ統合まで徹底解説

Git を使い始めた頃、多くの人が一度は遭遇する謎めいたエラー:

$ git pull origin main
warning: no common commits
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
...
From github.com:username/myrepo
 * branch                  main       -> FETCH_HEAD
fatal: refusing to merge unrelated histories

**「関連のない履歴同士は merge できません」**という Git からの拒絶。エラーメッセージは短いのに、何が起きているのか分からず途方に暮れる…。

このエラーが特に厄介なのは、通常の操作の流れでも突然発生すること:

  • ローカルで git init してから GitHub リポジトリを紐付けた
  • GitHub 上でREADME を作った後に、ローカルの既存プロジェクトを push しようとした
  • 誤って .git ディレクトリを削除・破損させた
  • 別々に始まった2つのリポジトリを1つにまとめたい
  • fork した後、大幅に分岐したものを本流に戻したい

しかも、--allow-unrelated-histories を使えば動くけど、本当にそれでいいの? という不安。GitHub Community でも「盲目的に --allow-unrelated-histories を使ってコードベースが壊れた」という報告が。

本記事では、fatal: refusing to merge unrelated histories完全な原因と解決方法を、リファレンスとして実用的に整理します。エラーの本質(共通祖先がない)、Git 2.9 での歴史的変更、5つの発生パターン、--allow-unrelated-histories の正しい使い方、fresh clone、サブディレクトリ統合、patch 経由、実践シナリオ、予防のベストプラクティス、FAQまで完全網羅。この1本でこのエラーを恐れず、正しく対処できるようになります。


目次

結論:3秒で解決する場合が多い

時間がない方向けに、最短の対処手順を示します。

最速の解決

git pull origin main --allow-unrelated-histories

# または merge
git merge origin/main --allow-unrelated-histories

これで大半のケースは解決。ただし、なぜ必要か理解した上で使うことが重要。

⚠️ 使う前に必ず確認

# 1. remote URL が正しいか
git remote -v

# 2. 相手のブランチに何があるか
git fetch origin
git log origin/main --oneline

間違ったリポジトリを origin にしていたなどの根本的なミスなら、--allow-unrelated-histories で強引に merge するのは危険。

いつ使うか / いつ使わないか

使ってOK:

  • ローカル git init → GitHub 既存リポジトリと連携したい
  • 別プロジェクト同士を1つに統合したい
  • 意図的に無関係な履歴を統合

使ってはいけない:

  • 間違った remote URL に接続している
  • .git を誤って壊した(fresh clone した方が安全)
  • 「よく分からないけどエラーが消えれば良い」

詳細は以下で解説します。


まず理解する:エラーの本質

Git は「共通祖先」を探している

Git の merge は 3-way merge です:

       A ─ B ─ C ← main
      /
BASE ─
      \
       X ─ Y ─ Z ← feature

Git は BASE(共通祖先)を見つけて、両方の変更を統合します。

共通祖先がないとどうなるか

Repo A: A ─ B ─ C
                  ← 共通祖先がない
Repo B: X ─ Y ─ Z

両者に共通する commit が1つもない → Git は「どうやって merge すればいいか判断できない」→ エラー

Git 2.9 での歴史的変更(2016年6月)

Git 2.9 より前は、共通祖先がなくても勝手に mergeしていました。しかし:

  • 「間違って全く別のリポジトリを merge してしまった」事故が多発
  • 意図しない履歴の混在が問題化

そのため、Git 2.9 でデフォルトの merge がこのエラーで停止するようになりました。

古い記事の情報が「動く」と書いていても、現代の Git では動きません。明示的に --allow-unrelated-histories が必要

メッセージの意味

fatal: refusing to merge unrelated histories

翻訳:「関連のない履歴同士の merge を拒否します

Git は「本当にこれ、いいの?」と警告してくれている親切機能です。


発生パターン5選

パターン1:ローカル init → GitHub 既存リポジトリ連携(最頻出)

典型的なシナリオ:

# 1. GitHub で新規リポジトリ作成
# → 「Initialize with README」にチェック → README.md が作られる

# 2. 手元のローカルで
mkdir my-project
cd my-project
git init
# ファイル作成
git add .
git commit -m "First commit"

# 3. GitHub と連携
git remote add origin https://github.com/user/my-project.git
git branch -M main
git push -u origin main
# error: failed to push some refs
# → pull を試みる
git pull origin main
# fatal: refusing to merge unrelated histories

何が起きているか:

  • ローカルの First commit
  • GitHub の Initial commit(README作成)
  • 両者は完全に別の履歴

パターン2:GitHub 既存リポジトリの clone せず、init から始めた

似たパターン:

GitHub に既存のリポジトリがある。それを clone せず、

git init
# ... 作業 ...
git remote add origin ...
git pull
# fatal: refusing to merge unrelated histories

→ 本来は最初から git clone すべきだった。

パターン3:.git ディレクトリの破損・削除

# 誤って
rm -rf .git

# 慌てて再初期化
git init
git remote add origin ...
git pull
# fatal: refusing to merge unrelated histories

→ ローカルの履歴が消えた状態で pull すると、リモートとローカルの関連性が失われる。

パターン4:別々に開発した2つのリポジトリを統合したい

# frontend と backend を別リポジトリで開発
# → 1つに統合したい

cd frontend
git remote add backend ../backend
git fetch backend
git merge backend/main
# fatal: refusing to merge unrelated histories

正当な使用場面の代表例。

パターン5:fork の大幅な分岐

# fork したリポジトリを長期間別方向に開発
# → 元のリポジトリと再統合したい

git remote add upstream https://github.com/original/repo.git
git fetch upstream
git merge upstream/main
# fatal: refusing to merge unrelated histories

これは通常起きないが、Git 履歴が rewrite された場合などに発生。


対処法①:–allow-unrelated-histories(最頻出)

基本的な使い方

# pull の場合
git pull origin main --allow-unrelated-histories

# merge の場合
git merge origin/main --allow-unrelated-histories

動作

  1. Git が「関連ない履歴だと分かっているが、merge を実行」
  2. 両方の全ファイルを統合
  3. 同じファイル名があれば conflict → 手動解決

conflict 発生時の対応

git pull origin main --allow-unrelated-histories
# Auto-merging README.md
# CONFLICT (add/add): Merge conflict in README.md
# Automatic merge failed; fix conflicts and then commit the result.

# 解決
vim README.md
git add README.md
git commit

add/add は「両方でファイルが追加された」conflict の意味。

詳細はgit merge conflict の解決方法の記事も参照。

実行前の確認(超重要)

盲目的に使う前に確認:

# 1. remote URL が正しいか
git remote -v
# origin  https://github.com/正しいユーザー/正しいレポ (fetch)

# 2. 相手のブランチに何があるか
git fetch origin
git log origin/main --oneline

# 3. ローカルに何があるか
git log --oneline

# 4. 両者を比べる
git log --oneline --all --graph

これで 本当に統合すべき履歴なのかを判断してから実行。


対処法②:Fresh Clone(最も安全)

ローカルの変更が少ない場合、これが最も安全:

# 1. ローカルの変更を退避
cp -r my-project /tmp/my-project-backup

# 2. 削除して clone
rm -rf my-project
git clone https://github.com/user/my-project.git
cd my-project

# 3. バックアップから変更を戻す
cp -r /tmp/my-project-backup/* .
# 必要ならファイル選択

# 4. コミット
git add .
git commit -m "Add my local changes"
git push

メリット

  • 履歴が綺麗(関係ない履歴が混ざらない)
  • conflict 発生しにくい
  • リモートの正規の履歴を尊重

デメリット

  • ローカルの commit 履歴は失われる(1つの commit に集約)

「ローカルの履歴がそこまで重要でない」なら、これが正解


対処法③:サブディレクトリ移動して統合

別々のリポジトリを1つに統合する場合、ファイル名衝突を避けるプロ技:

# backend リポジトリ側で
cd backend
mkdir backend-files
# 全ファイルを backend-files/ に移動(.git 以外)
git mv $(ls -A | grep -v backend-files | grep -v .git) backend-files/
git commit -m "Move backend into subdirectory"

# frontend 側で
cd ../frontend
git remote add backend ../backend
git fetch backend
git merge backend/main --allow-unrelated-histories
# ファイル名衝突なし → クリーンな merge

これで:

merged-project/
├── frontend-files (元 frontend)
└── backend-files/ (元 backend)

monorepo 移行の際に便利。


対処法④:Patch 経由

特定のコミットだけ取り込みたい場合:

# 送信側
cd source-repo
git format-patch HEAD~5..HEAD
# 0001-... .patch など生成

# 受信側
cd target-repo
git am /path/to/*.patch

履歴を統合せずコミットだけ移植

cherry-pick で個別移植

git remote add source ../source-repo
git fetch source
git cherry-pick source/main~2
git cherry-pick source/main~1
git cherry-pick source/main

--allow-unrelated-histories 不要。


対処法⑤:新ブランチ経由

現在のブランチをクリーンに保ちたい場合:

# 新ブランチ作成
git checkout -b merge-branch

# そこで merge
git merge origin/main --allow-unrelated-histories

# 動作確認
# ...

# 問題なければ main に merge
git checkout main
git merge merge-branch

段階的にリスクを分散。


実践シナリオ

シナリオ1:GitHub 新規 + README 作った後の連携

問題:

# GitHub で「Initialize with README」で作成済み
git init
git add .
git commit -m "First commit"
git remote add origin https://github.com/user/repo.git
git push -u origin main
# エラー: push failed
git pull origin main
# fatal: refusing to merge unrelated histories

解決:

# --allow-unrelated-histories で pull
git pull origin main --allow-unrelated-histories

# conflict あれば解決
vim README.md
git add README.md
git commit

# push
git push -u origin main

シナリオ2:ローカルの .git を復旧できない

問題:

# 誤って .git 削除
rm -rf .git

# 再init して push できない
git init
git remote add origin https://github.com/user/repo.git
git pull origin main
# fatal: refusing to merge unrelated histories

解決(fresh clone 推奨):

# ローカルの変更をバックアップ
cp -r . ../backup

# 削除して clone
cd ..
rm -rf my-project
git clone https://github.com/user/repo.git my-project

# 変更を戻す
cp -r ../backup/* my-project/
cd my-project
git add .
git commit -m "Restore local changes"
git push

シナリオ3:monorepo への統合

問題: 複数のマイクロサービスを1つの monorepo に集約したい。

解決:

# 統合先を作成
mkdir monorepo
cd monorepo
git init
mkdir services
git commit --allow-empty -m "Initial"

# 各サービスを追加
for service in service-a service-b service-c; do
  # 各サービスをサブディレクトリに移動
  cd /path/to/$service
  mkdir $service
  git mv $(ls -A | grep -v $service | grep -v .git) $service/
  git commit -m "Move to subdirectory"
  
  # monorepo に統合
  cd /path/to/monorepo
  git remote add $service /path/to/$service
  git fetch $service
  git merge $service/main --allow-unrelated-histories
done

シナリオ4:Rails プロジェクトの再構築

# 古い Rails 5 → 新規 Rails 8
rails new my-app-new --database=postgresql
cd my-app-new
git init  # 実は rails new で作られる
git add .
git commit -m "New Rails 8 skeleton"

# 古いプロジェクトから重要ファイルを取得
cd ../my-app
git bundle create /tmp/backup.bundle --all

cd ../my-app-new
git remote add old /tmp/backup.bundle
git fetch old
# 必要な部分だけ cherry-pick
git cherry-pick old/main~5..old/main~1

# または特定ディレクトリだけ
git remote add old-remote /path/to/old-repo
git fetch old-remote
git merge old-remote/main --allow-unrelated-histories --allow-empty-message -m ""

詳細はRails 8 アップグレードガイドの記事も参照。

シナリオ5:チームで正しい流れを共有

チーム開発でこのエラーを防ぐ:

# ❌ 悪い例
mkdir new-feature
cd new-feature
git init
# ... 作業 ...
git remote add origin https://github.com/team/repo.git
git pull  # → エラー

# ✅ 良い例
git clone https://github.com/team/repo.git
cd repo
git checkout -b new-feature
# ... 作業 ...
git push origin new-feature

最初から clone するが正解。


予防のベストプラクティス

1. 新規リポジトリは必ず clone

# ❌ 避ける
git init
git remote add origin ...
git pull  # → エラー

# ✅ 正しい
git clone https://github.com/user/repo.git
cd repo
# 作業開始

2. GitHub で新規作成時に README を作らない(ローカル既存の場合)

GitHub で新規リポジトリ作成時:

  • 既にローカルにコードがある: README なし・.gitignore なしで作成
  • 一から作る: README ありでもOK

これでローカルの git init + push がスムーズ。

3. .git を大切に

# ❌ 危険
rm -rf .git
rm -rf *  # .git も含めて削除

# ✅ 慎重に
git status
git log

4. remote URL を都度確認

git remote -v
# 本当にこの URL でいい?

5. 統合前に fetch と log で確認

git remote add other ...
git fetch other
git log other/main --oneline  # 何が入っているか確認

盲目的な --allow-unrelated-histories を避ける。


トラブルシューティング

–allow-unrelated-histories でも失敗

fatal: refusing to merge unrelated histories

→ Git のバージョン確認:

git --version
# Git 2.9 以降が必要

古すぎるなら:

# Ubuntu
sudo apt update && sudo apt upgrade git

# macOS
brew upgrade git

--allow-unrelated-histories を毎回打つのが面倒

恒久設定は非推奨(意図的な保護を無効化):

# ❌ 危険:無効化
git config --global pull.allowUnrelatedHistories true

エラーは本来「注意しろ」の警告。恒久無効化はやめよう。

大量の conflict が発生した

# 中止
git merge --abort

# ステップバイステップに切り替え
# or fresh clone に切り替え

コミット履歴が汚くなった

# reflog で戻す
git reflog
git reset --hard HEAD@{N}

詳細はgit reset vs revert vs restore の記事も参照。

push できなくなった

--allow-unrelated-histories merge 後、push できない場合:

git log --oneline
# 履歴を確認

git push --force-with-lease origin main
# ⚠️ 慎重に、他人が push していないか確認

詳細はgit push rejected の記事も参照。


よくある質問(FAQ)

Q1. --allow-unrelated-histories は毎回打つの?

毎回不要(毎回起きるエラーではない)。初回のみ必要な場合が多い。1度統合すれば、以降は共通祖先ができるので通常の pull/merge で動く。

Q2. なぜ Git はこのエラーを出すの?

Git 2.9(2016年6月)で追加された保護機能。意図しない別リポジトリの merge を防ぐため。「本当にこれ merge していいの?」と確認してくれる親切機能。

Q3. 使うと危険?

盲目的に使うと危険:

  • 間違った remote に接続していた
  • .git が壊れた状態

理解して使えば安全:

  • 新規 init + GitHub 連携
  • 意図的なリポジトリ統合

Q4. コミット履歴はどうなる?

両方の履歴が保持される:

main:  A ─ B ─ C ─ M  ← 統合後
                  /
other:  X ─ Y ─ Z

M は merge commit で、両方を親に持つ。

Q5. rebase でも同じエラー

git rebase origin/main
# fatal: refusing to merge unrelated histories

rebase では --allow-unrelated-histories オプションがない。代わりに:

git rebase --root
# 全コミットを rebase 対象に

または merge に切り替え。

Q6. 初回 push 時のエラーとの違い

初回 push:

! [rejected] main -> main (fetch first)

→ pull すると refusing to merge のエラー。同じ根本原因

対処:

git pull origin main --allow-unrelated-histories
git push -u origin main

Q7. GitHub Desktop / SourceTree で同じエラー

GUI ツールでも発生。それぞれに --allow-unrelated-histories オプションあり:

  • GitHub Desktop: 対応ダイアログでチェック
  • SourceTree: Merge 時のオプション
  • GitKraken: 設定で許可

または CLI で対処してから GUI 使用。

Q8. git init した後で紐付けるべき順序

正しい流れ:

# GitHub で空のリポジトリ作成(README なし)
# ローカル
git init
git add .
git commit -m "First commit"
git branch -M main
git remote add origin https://github.com/user/repo.git
git push -u origin main   # 空のリモートなので成功

README を GitHub 側で作らないのがコツ。

Q9. 既にコミットがある GitHub リポジトリに追加

すでに GitHub にコミットがある + ローカルに新規コード:

# clone してから作業
git clone https://github.com/user/repo.git
cd repo
# 新規コードを移動
mv /path/to/new-code/* .
git add .
git commit -m "Add new code"
git push

Q10. Submodule で発生

git submodule update --remote
# fatal: refusing to merge unrelated histories

対処:

cd submodule-dir
git pull origin main --allow-unrelated-histories
cd ..
git add submodule-dir
git commit -m "Update submodule"

Q11. GitHub Actions で発生

- uses: actions/checkout@v4
- name: Pull
  run: git pull origin main
  # → エラー

CI で発生する場合、通常は checkout の設定ミス:

- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # 全履歴取得

Q12. 一度 merge した後で分けたい

一度統合した履歴を分離するのは非常に困難git filter-repo などのツール使用が必要:

git clone https://github.com/newren/git-filter-repo.git
# ... 複雑な操作 ...

統合前によく考えるのが最善策。


参考リンク・関連資料

Git 公式

関連記事(本サイト)


まとめ

fatal: refusing to merge unrelated histories の解決、要点を再整理します。

最短の解決

git pull origin main --allow-unrelated-histories
# または
git merge origin/main --allow-unrelated-histories

発生の本質

  • Git 2.9 以降、共通祖先のない履歴の merge を拒否
  • 保護機能として動作
  • 意図しない別リポジトリの誤 merge を防止

主な発生パターン

パターン状況
ローカル init + GitHub 連携最頻出
GitHub 既存を clone せず init誤操作
.git 破損・削除事故
別リポジトリの統合正当な用途
fork の大幅分岐

解決方法5つ

  1. --allow-unrelated-histories: 最速、確認してから使う
  2. Fresh Clone: 最も安全、履歴クリーン
  3. サブディレクトリ移動: 統合時にファイル衝突回避
  4. Patch 経由: 特定コミットだけ移植
  5. 新ブランチ経由: リスク分散

使う前の確認

git remote -v                # remote URL 確認
git fetch origin             # 変更取得
git log origin/main --oneline # 相手の履歴
git log --oneline             # 自分の履歴

予防のベストプラクティス

  • 新規は必ず clone
  • 既存ローカルコードがある時は GitHub 側に README を作らない
  • .git を大切に
  • --allow-unrelated-histories を恒久設定しない
  • 統合前に fetch と log で確認

事故防止

  • 盲目的な --allow-unrelated-histories を避ける
  • fresh clone を検討する(履歴が汚れない)
  • reflog を活用(間違えても復旧可能)

これらの知識は、新規プロジェクトのセットアップ・リポジトリ統合・チーム開発の混乱回避・monorepo 移行など、あらゆる場面で活用できます。本記事をブックマークしておけば、このエラーに出会っても慌てず正しく対処できるようになります。


本記事は2026年6月時点の情報をもとに、Git 2.9+(推奨: Git 2.40+)での動作確認・公式ドキュメントに基づき作成しています。Git のバージョンによって挙動が異なる場合があるため、最新の情報はGit公式ドキュメントもあわせてご確認ください。