【Git】pushもできない初心者が、エラー「fatal: refusing to merge unrelated histories」を乗り越えた話。

# 概要
・ 初心者がgitコマンドで遊んでいたら、いつの間にか`push`できなくなっていた。
・ `push`できない原因を`fatal: refusing to merge unrelated histories`に特定。
・ 最終的に自分が何をやらかしたのか推測(なんのコマンドを実行したか覚えていないため)。

※`fatal: refusing to merge unrelated histories`に対する**結論**は、「**解決法**」に記載がございます。


# 環境
```terminal:terminal
% git --version
git version 2.36.1
```
※リモート名「origin」、ブランチ名「main」で作業しています。

# エラー状況
①.　「main」ブランチを`push`しようとしたところ、エラーが発生
②.　&nbsp;エラー文に基づいて、「main」ブランチを`pull`を実行するも再度エラーが発生
③.　&nbsp;再度出たエラー文に基づいて、`config pull.rebase false`を実行し、再度`pull`するも再再度エラーが発生
<br>
それぞれ状況を確認していきます。


## エラー状況①
「main」ブランチを`push`しようとしたところ、下記のエラーが発生した。

```terminal:terminal
% git push origin main
To https://github.com/xxxxxxxxxxxxxxxxxxx
 ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'https://github.com/xxxxxxxxxxxxxxxxxxx'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```


* エラー文の内容は以下の通り。
    * xxxxxxxxxxxxxxxxxxxに`push`できなかったよ
    * リモートブランチより現在のブランチが古いから、拒否されたよ
    * 再`push`する前に、リモートの変更を統合してね(例えば`git pull`でね)
<br>
エラー文中の<font color="red">(</font>non-fast-forward<font color="red">)</font>について、GitHub Docsによると、

>別の人が同じブランチにすでにプッシュしてしまった場合、Git はあなたの変更をプッシュできません。

https://docs.github.com/ja/get-started/using-git/dealing-with-non-fast-forward-errors

別の人はいない(自分一人でしか作業をしていない)ので、自分が既にリモートリポジトリへ`push`済みであることが原因のよう。


とりあえずエラー文の指示通り、`pull`を実行してみることに...

## エラー状況②
`pull`を実行したところ、またエラーが発生。下記の通り。
```terminal:terminal
% git pull origin main
From https://github.com/xxxxxxxxxxxxxxxxxxx
 * branch            main       -> FETCH_HEAD
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint: 
hint:   git config pull.rebase false  # merge
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint: 
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
```

* エラー文の内容は以下の通り。
    * 分岐したブランチがあって、それらを一致させる方法を指定する必要があるよ
    * 次の`pull`の前に、次のコマンドのうちのどれかを実行すればそれができるよ
    (git config以下略)
<br>

エラー文の指示通り、1つめのコマンド`git config pull.rebase false`を実行し、<br>その後に再度`pull`をしてみることに...

## エラー状況③
`pull`を実行したところ、下記のエラーが発生。また`pull`出来ず...
```terminal:terminal
% git pull origin main
From https://github.com/xxxxxxxxxxxxxxxxxxx
 * branch            main       -> FETCH_HEAD
fatal: refusing to merge unrelated histories
```
* エラー文の内容は以下の通り。
    * 関係ない履歴同士は`merge`できないよ

どうやら<font color="red">問題の根本は`unrelated histories`を`merge`できないこと</font>にありそうです。


# 解決法
下記のコードを実行することで、強制的にリモートリポジトリの内容をローカルに引っ張ってくることができ、最終的に`push`することができました。
```terminal:terminal
% git merge --allow-unrelated-histories origin/main
```
<br>

公式Docによる`--allow-unrelated-histories`オプションの詳細は以下の通りです。

>--allow-unrelated-histories
By default, git merge command refuses to merge histories that do not share a common ancestor. 
This option can be used to override this safety when merging histories of two projects that started their lives independently. 
As that is a very rare occasion, no configuration variable to enable this by default exists and will not be added.

https://git-scm.com/docs/git-merge#Documentation/git-merge.txt---allow-unrelated-histories


* --allow-unrelated-histories
    * "merge"コマンドは、共通の祖先を持っていない履歴同士を"merge"できないよ
    * 独立して生成された2つのプロジェクトの履歴を"merge"したい時は、このオプションを使えばOK！
    (As that以下略)

なるほど、<font size="1" color="red">**共通の祖先を持っていないもの同士を**`merge`**しようとしていた**</font>ことが、**本問題の原因**であると特定できました。

# 自分がやらかしたことを推測

自分が行った行為は下記の通りと推測されます。<br>
①.　&nbsp;`git.init`で「ローカルリポジトリA」を作成
②.　&nbsp;Aで管理されたデータをリモートリポジトリに`push`
③.　&nbsp;`git.init`で別の「ローカルリポジトリB」を作成
④.　&nbsp;Bで新規作成したデータを、②で`push`したのと同じリモートリポジトリ・ブランチに`push`**←ここで最初のエラー発生**
⑤.　&nbsp;共通の祖先を持っていないため`pull`できない**←次のエラー発生**

たぶんこんな感じなのかな？？
<br>

最後に公式Docに出てきた「**共通の祖先を持っている**」とは、**共通の親コミットを持っている**ということなのでしょうか。
上記の③でローカルBを作成後、開幕一発目のコミットデータには当然親コミットは存在しないので、共通の親を持っているどころではありませんね。

大変勉強になりました。


# 参考にした記事


https://www.educative.io/answers/the-fatal-refusing-to-merge-unrelated-histories-git-error