git pushもgit pullもできない状況を解決した
はじめに
これは、リモートとローカルの変更履歴が並行して進んでいたことが原因で起こっている。
ローカルの状態
vue-js-02というコミットは、リモートには反映されていない。

リモートの状態
READMEの変更をリモートで手動で行った。これがローカルに反映されていない。

git push origin mainができない
ローカルの変更をリモートに反映しようとしたが、現在のブランチがビハインドとのこと。
hiroki@shibatahiroshitakanoiMac my-vue-js % git push origin main
To https://github.com/ki-hi-ro/my-vue-js.git
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'https://github.com/ki-hi-ro/my-vue-js.git'
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.
リモートに対してビハインド。
遅れている。
git pull origin mainを行った後のメッセージ
遅れを取り戻すため、git pull origin mainを行う。しかし、これもできない。
hiroki@shibatahiroshitakanoiMac my-vue-js % git pull origin main
From https://github.com/ki-hi-ro/my-vue-js
* 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.
fatal: Need to specify how to reconcile divergent branches.
Need to specify how to reconcile divergent branchesの意味
分岐したブランチを解決する必要があるという意味。
fatal: Need to specify how to reconcile divergent branches.


上記のように、mainブランチがローカルとリモートで分岐している。

vue-js-1から分岐している。
ローカルでは、vue-js-02に進んでいて、リモートでは、READMEに進んでいる。
3つの選択肢
マージか、リバースか、ファストフォワードのみか。
hint: git config pull.rebase false # merge
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
今回は、リモートとローカルの変更点を両方取り込みたいので、マージを選択する。
リバースは、ローカルで加えた変更を無視して、リモートの変更に戻すときに使われるんだろう。
正直よく分からない。
ファストフォワードオンリーはリモートのみだろう。
ということは、リバースは、ローカルのみにするということか?
マージを行う
設定をいじっただけなので何も起こらない。
hiroki@shibatahiroshitakanoiMac my-vue-js % git config pull.rebase false
hiroki@shibatahiroshitakanoiMac my-vue-js %
git pull origin mainを行うと、以下の画面になった。

Merge branch 'main' of https://github.com/ki-hi-ro/my-vue-js
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
~
続行をクリックした。
グラフが以下のようになった。

リモートの変更をマージしたということだろう。

上記の画面は、:q → Enterで抜ける。

git pushに成功した
hiroki@shibatahiroshitakanoiMac my-vue-js % git push origin main
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 12 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 1.72 KiB | 1.72 MiB/s, done.
Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/ki-hi-ro/my-vue-js.git
ac176f6..08b6851 main -> main
リモートの状態

マージコミットが反映された。
まとめ
今回のエラーは、ローカルとリモートの main
ブランチがそれぞれ独自に進んでいたことが原因でした。
つまり、ローカルには vue-js-02
というコミットがあり、リモートには README.md
の手動編集が加わっていた。
このように分岐した状態では、Git は自動で統合方法を決めてくれません。
そこで今回は、リモートとローカルの両方の変更を活かしたいと考え、merge
を選びました。git config pull.rebase false
で設定を行い、git pull origin main
を実行すると、マージコミットの作成画面に移りました。
続行ボタンをクリックしてマージコミットを確定し、その後 git push origin main
が無事に成功しました。
今回の一連の流れを通して、「リモートとローカルが分岐して push/pull できないときに、どう対応すればよいか」が実感できました。
merge / rebase / fast-forward という3つの統合方法の中から、状況に応じて適切なものを選べば、Git はちゃんと応えてくれます。
コメントを残す