[Git] マージしようとするとrefusing to merge unrelated historiesが出たときの対処方法

git mergeでrefusing to merge unrelated historiesが出たら--allow-unrelated-historiesオプションを付けましょう。
2021.07.07

この記事の結論

$ git merge --allow-unrelated-histories target_branch

# コミットを1まとめにしたい場合
$ git merge --allow-unrelated-histories --squash target_branch

始めに

今日は7月7日ですね。何の日かといえば、クラスメソッドの創業記念日です。さて今日は何本の記事が上がるでしょうか。

バージョン管理システムのGitでは、ブランチを分けることによってリポジトリ内のファイルの異なる変更を保持できます。そして分けたブランチはマージすることで変更を取り込み、ひとつのブランチとして統合できます。

さてこのブランチ&マージはとても便利なのですが、通常ブランチの根本(幹)は共通している必要があります。共通していないブランチをマージしようとすると refusing to merge unrelated histories というエラーが出ます。簡単に確認してみましょう。

$ mkdir remote_1
$ git init
$ echo remote_1 > test1.txt
$ git add .
$ git commit -m 'init commit'

$ cd ..

$ mkdir remote_2
$ git init
$ echo remote_2 > test2.txt
$ git add .
$ git commit -m 'init commit'

$ git remote add remo1 ../remote_1/
$ git remote -v
remo1	../remote_1/ (fetch)
remo1	../remote_1/ (push)

$ git fetch remo1
 * [new branch]      main       -> remo1/main

$ git merge remo1/main
fatal: refusing to merge unrelated histories

今回は異なるリポジトリのブランチをマージしようとしてみました(同一リポジトリでも起こり得ます)。もちろん根本は異なるためそのままではマージできません。

オプションを指定する

どうしてもマージできないのか?というと実はそんなことはなく。--allow-unrelated-historiesオプションを指定するとマージできます。実際にやってみましょう。

$ git merge --allow-unrelated-histories --no-edit remo1/main
Merge made by the 'recursive' strategy.
 test1.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 test1.txt

$ git log --graph
*   commit a1beb8cbab897a4e618e754b3f36eb11fba2fb1c (HEAD -> main)
|\  Merge: 63b9c99 a831df0
| | Author: TAKEDA-Takashi <takeda.takashi0308@gmail.com>
| | Date:   Wed Jul 7 22:49:53 2021 +0900
| |
| |     Merge remote-tracking branch 'remo1/main'
| |
| * commit a831df0aca57b98831fde679be99db8a5c192aa3 (remo1/main)
|   Author: TAKEDA-Takashi <takeda.takashi0308@gmail.com>
|   Date:   Wed Jul 7 20:53:31 2021 +0900
|
|       init commit
|
* commit 63b9c999eaaf5d9cc250887a1149847a12bb36bd
  Author: TAKEDA-Takashi <takeda.takashi0308@gmail.com>
  Date:   Wed Jul 7 21:56:50 2021 +0900

      init commit

根本の異なるブランチ2つをマージできました。ちょっと不思議なグラフができあがりますね。ちなみに今回は1コミットしかありませんが、長いコミット履歴をもつブランチをマージすると、すべてのコミットが履歴として出てきます。もし元のブランチの履歴は不要という場合は、--squashオプションを指定すると1コミットにまとまり、履歴がきれいになります。ぜひ試してみてください。

まとめ

おそらく使う機会はそう多くないでしょう。いざ必要になった際、この記事を思い出してもらえると幸いです。