こんにちは、さるまりんです🐒
Gitでマージ、その時に大量のコンフリクトが出てしまうことがあります。
手動で一つずつ直すのはもちろん通常の手順ですが、状況によっては「リモートを正として」または「ローカルを正として」一括で解決したいこともあります。
今回はその手順をまとめてみました。
以下はorigin/main
をローカルブランチに取り込むときの手順です。
また、merge
前提の手順です(git rebase
ではours/theirs
の意味が変わるので注意)。
0. 前提(いまいるブランチを確認)
git branch # 現在のブランチを確認
git switch <作業ブランチ> # 例: git switch main
# または
git checkout <作業ブランチ> # 例: git checkout main
git status # 作業ツリーの状態を確認
1. リモートの最新情報を取得
git fetch origin
リモートの最新情報をローカルに取得します(この時点でローカルのファイルはまだ変わりません)。
2. ローカルに取り込む
git merge origin/main
リモートのmain(origin/main
)をローカルに取り込みます。
- 問題なし(コンフリクトなし):そのまま[4. マージを完了] → [5. 反映]へ。
- 問題あり(コンフリクト発生):対象ファイルが表示されます → [3. 解消] へ。
3. コンフリクトを解消する(3択)
コンフリクトをどう処理するかで選びます。
A) リモート側の変更を正(--theirs
)
個別ファイル:
git checkout --theirs <ファイルパス>
全部まとめて(スペース/改行を含むファイル名にも安全です):
git diff --name-only -z --diff-filter=U | xargs -0 git checkout --theirs
B) ローカル側の変更を正(--ours
)
個別ファイル:
git checkout --ours <ファイルパス>
全部まとめて:
git diff --name-only -z --diff-filter=U | xargs -0 git checkout --ours
C) 手動で修正(基本はこの手順)
対象ファイルを開き、<<<<<<<
/ =======
/ >>>>>>>
のマーカーを取り除いて内容をまとめ、修正して取り込みます。
補足です。
マージ実行時に「傾向」を先に指定することもできます。
- 全部リモート優先の傾向:
git merge -X theirs origin/main
- 全部ローカル優先の傾向:
git merge -X ours origin/main
これは競合した“行”に対する既定を決めるオプションで、非競合の差分は両方取り込まれます。残った衝突は A/B/C で解消します。
4. マージを完了
ステージ → コミットしてマージを完了します。
git status
# 解消したファイルをステージ
git add -A # 追加/変更/削除をまとめてステージ(安全にいくなら個別指定でもOKです)
# マージコミットを作成
git commit # 既定のマージメッセージのままで大体OKです。
確認:コミット前にgit diff --staged
でステージ済みの差分を目視すると安心です。
5. リモートへ反映
最終的にpush
してリモートにマージ結果を反映します。
git push
6. 困ったときは(やり直し・取り消し)
マージを中断して開始前に戻す:
git merge --abort
(古い環境で戻れない場合はgit reset --merge
、最終手段はgit reset --hard ORIG_HEAD
※破壊的ですが)
未解決ファイルの確認:
git status
git diff --name-only --diff-filter=U
マージは機械で寄せられるところは機械に寄せるのが良いです。
が、そうもいかないときもあります。
「今回はぜんぶリモートを正にしたい」「このファイル群はローカル優先」みたいな判断を、コマンドで一括にしておくと焦らずに済みそうです。
もちろんそんな簡単ではないのが実務だと思いますが。困ったらgit merge --abort
でいったん深呼吸。落ち着いて、再トライ!
ツールはうまく便利に使っていきたいです。
読んでくださってありがとうございました。
それではまた!