Stage 3・上級編 ー Lesson 3-5

git rebase と cherry-pick で履歴を編集する

rebase で履歴を一直線にきれいに、cherry-pick で必要なコミットだけ持ってくる

💡 たとえるなら

本の章順を並べ替える(rebase)/別の本から1ページだけコピペする(cherry-pick)

ここからは Git の パワーツール。コミット履歴を後から 編集する 技術です。慣れると非常に便利ですが、「公開済みのコミットを書き換えてはいけない」 という大原則だけは絶対に守ってください。

rebase って何?

merge が「枝を合流させる」操作だったのに対し、rebase「枝の根元を別の場所に付け替える」 操作です。

rebase 前 A B E main C D feature rebase 後(feature を main に rebase) A B E main C' D' feature

merge「歴史を残す」 のに対し、rebase「歴史をきれいに整える」。コミット C・D は新しいコミット C’・D’ として 作り直される のがポイント。

rebase してみる

feature ブランチで作業中、main が先に進んだ場合:

# feature にいる状態で
$ git switch feature
# main の最新の上に feature を載せ直す
$ git rebase main

意味は 「自分(feature)のコミットを main の最新の上に積み直す」。コンフリクトしたら手で解決して git rebase --continue、やめたければ git rebase --abort

なぜ rebase を使うのか

  • 履歴が一直線になって読みやすいgit log --graph がスッキリ
  • 「同期だけのマージコミット」が積まれない:feature 開発中に「main の最新を取り込みたい」と git merge maingit pull(マージ方式)を何度もやると、その都度 Merge branch ‘main’ into feature が積まれて履歴が膨らみます。git rebase main に置き換えれば、これが一切残らず履歴が直列のまま保てます
  • チームによっては「最終 merge する前に rebase してから」が作法
💡 最終マージの数は変わらない
「feature を main に取り込む」最終マージは、merge派でも rebase派でも 1機能あたり1コミット。減るのはあくまで 開発中に何度も発生する「同期だけのマージ」 の方です。

ただし 後述の通り、共有済みのコミットには使ってはいけません

interactive rebase:履歴を整える究極の道具

-i オプションで 対話的rebase を起動すると、各コミットを「順番入れ替え」「メッセージ修正」「複数を1つに統合(squash)」「捨てる(drop)」できます。

# 直近3コミットを対話的に編集
$ git rebase -i HEAD~3

エディタが開いて、こんな画面が出ます:

pick a1b2c3d 機能の骨組みを追加
pick e4f5g6h タイポ修正
pick i7j8k9l 細かい調整
# Commands:
# p, pick = use commit
# r, reword = メッセージを書き直す
# s, squash = 直前のコミットに統合
# f, fixup = squash と同じだが、メッセージは捨てる
# d, drop = このコミットを捨てる

picksf に書き換えて保存すると、自動でコミットが統合されます。

よくある使い道

  • 「タイポ修正」みたいな小さなコミットを直前に統合したいf(fixup)
  • コミットメッセージを後から直したいr(reword)
  • 間違って入れてしまったコミットを消したいd(drop)

cherry-pick:1コミットだけ持ってくる

「あのブランチのあのコミットだけ、こっちに欲しい」というとき。

# 取り込みたい先(main)にいる状態で
$ git switch main
# feature ブランチの a1b2c3d だけ持ってくる
$ git cherry-pick a1b2c3d

そのコミットの 変更内容だけを「コピー」して、現ブランチの先頭に新しいコミットとして積みます

⚠️ コミットIDは変わる(rebase と同じ)
cherry-pick で持ってきたコミットは、元のコミットとは別の 新しいID を持ちます。親コミットも作者日時も変わるので、ハッシュは必ず変わるからです。
なので「あれ、同じコミットIDが両方のブランチにある!」とはなりません。中身は同じでも、Gitから見ると 別のコミット です(rebase 後の C・D が C'・D' になるのと同じ理由)。

典型的な使いどころ

  • バグ修正コミットを別ブランチにも適用したいhotfix-1.0 で直したやつを main にも cherry-pick
  • 試作で作ったコミットの一部だけ採用したい

大原則:公開済みのコミットを書き換えない

rebase / 履歴編集は コミットIDを書き換える 操作。一度 push したコミットを書き換えると、チームメンバーのローカルと食い違って 大事故 になります。

🚨 鉄則
自分しか触っていない(push 前の)ローカルコミットだけを rebase / amend する。
push 済み・チームと共有済みのコミットを書き換えたいなら、Stage 2-5 で学んだ git revert で「打ち消しコミット」を積む。

「mainブランチを rebase した」のは禁忌。featureブランチを rebase してから merge する、はOK(自分しか触ってないので)。

merge と rebase、どっちを選ぶ?

mergerebase
履歴の見た目枝分かれが残る一直線
マージコミット作る作らない
共有済みコミット安全NG
取り込まれた経緯残せる消える

チームによって「merge派」「rebase派」がありますが、初心者のうちは 「自分のfeatureを最新のmainに追従させる時は rebase、main にfeatureを取り込む時は merge」 くらいの分担が安全です。

やってみよう ①:3つのコミットを rebase -i で1つに squash する

「ちまちまコミット → 最後にきれいにまとめる」という王道フローを再現します。

# feature ブランチで小さいコミットを3つ作る
$ git switch -c feature-tidy
$ echo "草案" > draft.txt && git add draft.txt && git commit -m "草案"
$ echo "本文追加" >> draft.txt && git commit -am "本文追加"
$ echo "タイポ修正" >> draft.txt && git commit -am "タイポ修正"
$ git log --oneline -3
8d3f2a1 タイポ修正
4b9c1e7 本文追加
7a2e9f3 草案
# 3つを対話的にまとめる
$ git rebase -i HEAD~3
# エディタが開くので、4b9c1e7 と 8d3f2a1 の "pick" を "fixup" (f) に書き換える:
pick 7a2e9f3 草案
f 4b9c1e7 本文追加
f 8d3f2a1 タイポ修正
# 保存して閉じると…
# 1コミットにまとまった!
$ git log --oneline -3
5c6d8b2 草案 ← 新しいID!(元の 7a2e9f3 とは別物)
…(その前のmainコミット)
⚠️ メッセージは残っても ID は変わる
fixup で残るのは 最初のコミットのメッセージだけ(「草案」)。中身は3コミット分が統合され、親は同じでも tree(中身)が変わるのでハッシュは別物 になります。7a2e9f35c6d8b2 のように ID が変わるのが、まさに「履歴を書き換えた」証拠。だから push 済みコミットには使ってはいけません。

3つの「ちまちまコミット」が 1つの整ったコミット になりました。チームに見せる前にこうして履歴を整えるのが「rebase の作法」。

やってみよう ②:別ブランチから1コミットだけ cherry-pick

# feature-tidy にあるコミットIDをメモ
$ git log --oneline -1
a1b2c3d 草案
# main に戻って、その1コミットだけ移植
$ git switch main
$ git cherry-pick a1b2c3d
$ ls
draft.txt memo.txt ← draft.txt が main にも来た!

ブランチ全体をマージせず、特定の1コミットだけ 持ってこれます。バグ修正をリリース版にも適用したい時の定番。

このレッスンのまとめ

できるようになったこと
git rebase で枝の根元を付け替えられる
rebase -i でコミットの統合・並べ替え・修正ができる
cherry-pick で1コミットだけ持ってこれる
公開済みコミットを書き換えてはいけない大原則を守る
✅ merge と rebase の使い分けを理解した

✏️ 理解度チェック

0 / 3 正解

各問題、選んだ瞬間に正解と解説が表示されます。気軽に試してください。

  1. Q1. git rebase の主な効果は?
  2. Q2. 他のブランチから1コミットだけ持ってくるコマンドは?
  3. Q3. 公開済み(push 済み)のコミットを rebase してはいけない理由は?

© 2026 git-ready-easy — プログラミング未経験でもわかる git 入門