あかね
PRを分割したかっただけなのに、コンフリ地獄になった話
2026年04月14日
見出しはありません
要約を生成中...
「PRを分割しようとしてcherry-pickしたらコンフリクトで壊れました」こんな感じの相談で面談予約が入っていました。
何が起きたか確認していくと、Gitでよくありそうなハマりポイントが詰まっていたので 何が起きていたのか・どう解決するのがよいかを整理してみます。
Gitってこわ〜い🥺ですよね、一つずつ理解したいですね🥳
状況はこんな感じでした👇
個人開発
mainからブランチを切って開発
PRを作成
しかし問題発生!!! 本来別PRにすべき変更もまとめて入れてしまった🤦♀️
こういう失敗は実務に入る前に経験した方が良いと思います👌🏻
仕事でGitミスりたくないです私は、、!
PRを分割するために、新たにブランチを切って
git cherry-pick <コミットハッシュ>このように入れてしまった余計なコミットに対して別ブランチに移動し、その後さらに追加の修正を加えた。
さらに
Prismaのmigration削除
.gitignore変更
などの処理をしたとこのこと!
GitHub上で
This branch has conflicts that must be resolved
さらに
型エラーが出る
ファイルが足りない
コンフリクトが解消できない
まぁ当然に困惑しますよね😱
結論から言うと 履歴が分岐した状態で同じ領域を触っていた ことが原因でコンフリが発生した主な原因です。
元のコミット: D
cherry-pick後: D'見た目は同じでも別コミットです!
同じ差分を別の差分としてコミットコピーしているだけなんです。
cherry-pickは私は全く使わず「コミットを移動できるよ〜」と聞いたことがあるくらいですが、当然に使う現場もあると聞きます👀
Gitは「同じ内容かどうかは知らない。履歴が違えば別変更」と判断して、同じ場所をいじっていたら、どんな差分か関係ない、コンフリ!となります。
そのため
D(元の変更)
D'(コピー)
両方とも別の変更として扱われた結果コンフリが発生🔥という流れだったようですね、!
相談内容で
migrations削除(構造変更)
.gitignore変更
追加コミット
依存関係が増えた状態で、さらに元PRをマージしないままに修正を加えてcherry-pickした方のPRを先にマージしてしまったようです。
なので元のPRがコンフリしたというわけですね!!!
今回のケースでの対処方法としておすすめなのは履歴を一度整理してから積み直すことかなと思います。
① 追加した変更を退避
git checkout 元ブランチ
git checkout -b extra-work② 元ブランチをマージすべきだったLGTM時点に戻す
git checkout 元ブランチ
git reset --hard <LGTMコミット>
git push -f自分以外の人も触っているプロジェクトなら最後のpush -fではなく
git push --force-with-leaseにします。自分以外の変更が入ってたら弾いてくれるので安全にpushを強制できます。
③ PRをマージ
resetで不要な変更がない状態でマージして本来あるべきだった処理を成立させるのを先にやりたいですね。
一回コピーブランチ作ってるので変更が消える心配はしなくて大丈夫です。
④ 続きは別ブランチで再開
git checkout main
git pull
git checkout extra-work
git rebase main履歴のズレをリセットできるからです。
merge は別々の歴史を無理やり合流させて「混ぜました!」という新しい結び目を作る(コミットがそのままになりますよね)
rebase は古い土台をよしなに無視して最新のmainに植え替え、「今ここで初めてブランチ切りました」みたいな顔します
最大の差は、rebaseならcherry-pickで重複した中身をGitが空気を読んで自動でスキップし、履歴を一本道に掃除してくれること
歴史の改ざんができるのが rebase の強みですね!チーム開発では履歴を残す必要がある場合もあるので安易にやってはいけないと思いますが!!!
rebase は最新のmainの上にコミットを積み直す操作であり、その過程で不要な差分や重複に気づきやすくなりますが、自動で全部がいい感じになるわけではないのでチーム開発ではrebaseではなくmergeをするのが原則です。
複数コミットある場合は順番にやらないとおかしいです。
そのコミット単体で完結している
依存がない
といった使える条件もあります
後から分割はコストが高いです、、!
マージのし忘れには御用心🚀
ただしバックアップは取ることですね、、バックアップを使えばミスってもなんとかなる、、!
git checkout -b backupすでにリモートにpush済みの履歴をresetする場合は、履歴を書き換える操作になるため注意が必要です。履歴を書き換えたくない場合はrevert(打ち消すコミットの作成)です。
今回の困惑するコンフリの原因は
cherry-pickで履歴が分岐した
追加変更で依存増加した
構造を変更した
複合的な問題があったと思います。
いや〜gitって怖いですね。。。
コンフリとかしたらヒィエエだるぅぅぅってなります。
マージする順番も大事なのでmainの状態とPRの履歴の状態はどうなってるかよく確認しながら進めたいものです!
mainに直pushは他人の履歴を壊したり、デプロイサイクルを乱したりするからダメですよ🙅♀️
オリアプは誰にも迷惑かけないところなのでこの段階でたくさん失敗して頑張りましょう🙌🏻
要約
コメント
まだコメントはありません。