概要
・ 初心者がgitコマンドで遊んでいたら、いつの間にかpush
できなくなっていた。
・ push
できない原因をfatal: refusing to merge unrelated histories
に特定。
・ 最終的に自分が何をやらかしたのか推測(なんのコマンドを実行したか覚えていないため)。
※fatal: refusing to merge unrelated histories
に対する結論は、「解決法」に記載がございます。
環境
% git --version
git version 2.36.1
※リモート名「origin」、ブランチ名「main」で作業しています。
エラー状況
①. 「main」ブランチをpush
しようとしたところ、エラーが発生
②. エラー文に基づいて、「main」ブランチをpull
を実行するも再度エラーが発生
③. 再度出たエラー文に基づいて、config pull.rebase false
を実行し、再度pull
するも再再度エラーが発生
それぞれ状況を確認していきます。
エラー状況①
「main」ブランチをpush
しようとしたところ、下記のエラーが発生した。
% 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
でね)
- xxxxxxxxxxxxxxxxxxxに
エラー文中の(non-fast-forward)について、GitHub Docsによると、
別の人が同じブランチにすでにプッシュしてしまった場合、Git はあなたの変更をプッシュできません。
別の人はいない(自分一人でしか作業をしていない)ので、自分が既にリモートリポジトリへpush
済みであることが原因のよう。
とりあえずエラー文の指示通り、pull
を実行してみることに...
エラー状況②
pull
を実行したところ、またエラーが発生。下記の通り。
% 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以下略)
エラー文の指示通り、1つめのコマンドgit config pull.rebase false
を実行し、
その後に再度pull
をしてみることに...
エラー状況③
pull
を実行したところ、下記のエラーが発生。またpull
出来ず...
% git pull origin main
From https://github.com/xxxxxxxxxxxxxxxxxxx
* branch main -> FETCH_HEAD
fatal: refusing to merge unrelated histories
- エラー文の内容は以下の通り。
- 関係ない履歴同士は
merge
できないよ
- 関係ない履歴同士は
どうやら問題の根本はunrelated histories
をmerge
できないことにありそうです。
解決法
下記のコードを実行することで、強制的にリモートリポジトリの内容をローカルに引っ張ってくることができ、最終的にpush
することができました。
% git merge --allow-unrelated-histories origin/main
公式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.
- --allow-unrelated-histories
- "merge"コマンドは、共通の祖先を持っていない履歴同士を"merge"できないよ
- 独立して生成された2つのプロジェクトの履歴を"merge"したい時は、このオプションを使えばOK!
(As that以下略)
なるほど、共通の祖先を持っていないもの同士をmerge
しようとしていたことが、本問題の原因であると特定できました。
自分がやらかしたことを推測
自分が行った行為は下記の通りと推測されます。
①. git.init
で「ローカルリポジトリA」を作成
②. Aで管理されたデータをリモートリポジトリにpush
③. git.init
で別の「ローカルリポジトリB」を作成
④. Bで新規作成したデータを、②でpush
したのと同じリモートリポジトリ・ブランチにpush
←ここで最初のエラー発生
⑤. 共通の祖先を持っていないためpull
できない←次のエラー発生
たぶんこんな感じなのかな??
最後に公式Docに出てきた「共通の祖先を持っている」とは、共通の親コミットを持っているということなのでしょうか。
上記の③でローカルBを作成後、開幕一発目のコミットデータには当然親コミットは存在しないので、共通の親を持っているどころではありませんね。
大変勉強になりました。
参考にした記事