Git で「fatal: refusing to merge unrelated histories」が解決できない
共通の祖先を持たない 2 つの履歴を merge / pull すると Git 2.9 以降が安全のため拒否する。
意図的な統合なら --allow-unrelated-histories を付け、そうでなければ clone し直すか subtree を検討する。
#git#merge#pull#history#allow-unrelated-histories
要約
fatal: refusing to merge unrelated histories は、共通の祖先コミットを持たない 2 つの履歴 を git merge または git pull で統合しようとしたときに、Git 2.9 以降が安全装置として拒否する状態。
統合が妥当なら --allow-unrelated-histories を明示的に付けて許可する。
そうでなければ履歴を繋がず別の取り込み方を選ぶ。
よくある原因
- 空リポジトリ + 別履歴: GitHub 側で README 付きリポジトリを作り、手元の
git init済みプロジェクトを後からgit pullした - リモートを後付け: ローカルで何度かコミットした後に
git remote addし、初期コミットがリモートと噛み合わない - 2 リポジトリの統合: 別々に育てたリポジトリを 1 つにまとめようとしている
- 履歴の作り直し:
.gitを削除して再git initし、過去の履歴と分岐した
解決策
1. 意図的な統合なら明示フラグを付ける
git pull origin main --allow-unrelated-histories
# merge を直接呼ぶ場合
git merge other-branch --allow-unrelated-historiesGit 2.9 で既定が「拒否」に変わったため、統合が正しいと判断できるときだけ このフラグで上書きする。
詳細は git-merge 公式ドキュメント と git-pull 公式ドキュメント の --allow-unrelated-histories の項を参照。
2. リモートの初期コミットを取り込む
git remote add origin <url>
git fetch origin
git merge origin/main --allow-unrelated-histories両方の履歴が残る。
同じファイル(README など)が衝突したら、通常のコンフリクト解消(編集 → git add → git commit)で片付ける。
3. ローカルがほぼ空なら clone し直す
git clone <url> project
# 手元の必要ファイルを project/ にコピーして
git add .
git commit -m "import local work"履歴を無理に接続せず、リモートを正として作業を載せ替える方が後で履歴が読みやすい。
4. 別履歴として取り込む
2 つのプロジェクト履歴をどちらも保持したい場合は、merge ではなく subtree を使う。
git subtree add --prefix=vendor/lib <url> mainvendor/lib/ 配下に相手リポジトリを取り込み、自分の履歴とは分けて管理できる。
統合すべきでないものを --allow-unrelated-histories で繋ぐと、後からログ追跡が困難になる点に注意する。