この記事はGemini 2.5Proを使用して作成しました。
「よし、開発が終わったからプルリクを出すぞ!」
そう思って差分を確認したら、なぜか関係ないファイルや、他のブランチのコミットが大量に含まれている…。😱
こんな経験はありませんか?
間違えてmain
ブランチをマージしてしまったり、不要なコミットを積んでしまったりすると、プルリクがコンフリクトだらけになったり、レビューしづらくなったりします。
今回は、そんな絶望的な状況から必要なコミットだけを救出し、きれいなブランチに作り直す方法を分かりやすく解説します。
😱 今回の状況
main
ブランチからfeature
ブランチを切って開発していたとします。
きれいな状態なら、feature
ブランチのコミット履歴はこうなっているはずです。
# 理想のコミット履歴
* 0c5b04b (feature) feat: B機能を追加
* 7a2d1f9 feat: A機能を追加
* a1b2c3d (main) mainブランチの最新コミット
しかし、何かの手違いで不要なコミット(chore: 不要なコミット1
, fix: 関係ない修正2
)が混ざってしまいました。
# 絶望的なコミット履歴
* 0c5b04b (feature) feat: B機能を追加
* 8f9e0d1 fix: 関係ない修正2
* 7a2d1f9 feat: A機能を追加
* 6c5b4a3 chore: 不要なコミット1
* a1b2c3d (main) mainブランチの最新コミット
このままではプルリクは出せません。
ここから、feat: A機能を追加
と feat: B機能を追加
の2つのコミットだけを救出します!
✨ 解決手順
手順はたったの3ステップです。
- 救出したいコミットのハッシュ値をコピーする
- ブランチを綺麗な状態に強制リセットする (
reset --hard
) - 必要なコミットだけを摘み取る (
cherry-pick
)
Step 1: 救出したいコミットのハッシュ値をコピーする
まず、今のブランチで残したいコミットがどれなのかを確認し、そのコミットハッシュ(7a2d1f9
のような英数字のID)を控えておきます。
git log --oneline
を使うと、履歴が1行で表示されて見やすいのでおすすめです。
git log --oneline
今回の例では、以下の2つのコミットを救出したいので、ハッシュ値をメモ帳などにコピーしておきます。
-
0c5b04b
(feat: B機能を追加) -
7a2d1f9
(feat: A機能を追加)
Step 2: ブランチを綺麗な状態に強制リセットする (reset --hard
)
次に、今のfeature
ブランチの歴史を一度なかったことにして、分岐元のmain
ブランチと全く同じ状態に戻します。
⚠️ 注意: --hard
オプションは、ローカルでの変更がすべて消える強力なコマンドです。実行する前に、必要なファイルがコミットされているか、または退避(stash)させているか必ず確認してください。
# featureブランチをmainブランチの最新状態に強制リセット
git reset --hard main
このコマンドを実行すると、feature
ブランチのコミット履歴はmain
ブランチと全く同じになります。先ほどの不要なコミットも、救出したかったコミットも、すべて消え去ります。
「え、全部消えちゃって大丈夫!?」と不安になるかもしれませんが、大丈夫です。Step 1でハッシュ値を控えてあるので、次のステップで復活させます。
Step 3: 必要なコミットだけを摘み取る (cherry-pick
)
いよいよ最後の仕上げです。
まっさらになったfeature
ブランチに、Step 1で控えておいたコミットを一つずつ乗せていきます。ここで使うのが git cherry-pick
です。
cherry-pick
は、その名の通り、特定のコミットだけをつまんで(cherry-pickして)、現在のブランチに持ってくることができるコマンドです。
# コピーしておいたハッシュ値を指定
git cherry-pick 7a2d1f9
git cherry-pick 0c5b04b
複数のコミットは、スペース区切りで一度に指定することも可能です。
# 一度に指定する場合 (コミットは古い順に並べるのがおすすめ)
git cherry-pick 7a2d1f9 0c5b04b
これで、main
ブランチの先に、救出したかったコミットだけが綺麗に積み上がった状態になります。
# 理想のコミット履歴が完成!
* c8a9b7d (feature) feat: B機能を追加
* e5f6g1h feat: A機能を追加
* a1b2c3d (main) mainブランチの最新コミット
✅ これで安心してプルリクが出せますね!
⚠️ リモートブランチにPUSHする際の注意点
すでにリモートリポジトリ(GitHubなど)にPUSH済みのブランチに対してこの操作を行った場合、コミット履歴を書き換えているため、通常のgit push
は使えません。
その場合は、--force-with-lease
オプションを使って強制的にPUSHする必要があります。
# 履歴を書き換えたブランチを安全に強制PUSHする
git push origin feature --force-with-lease
--force
よりも安全な--force-with-lease
を使うことで、他の人がリモートブランチを更新していた場合に上書きしてしまう事故を防げます。
まとめ
間違ったコミットを含んでしまっても、この手順を知っていれば慌てる必要はありません。
-
git log
で残したいコミットのハッシュを確認 -
git reset --hard [分岐元ブランチ]
で一度リセット -
git cherry-pick [ハッシュ値]
で必要なコミットを乗せる
この流れを覚えて、きれいなコミット履歴で快適なGitライフを送りましょう!