rebase と cherry-pick

INPUT · スライド

履歴を整える(rebase / cherry-pick)

01 / 08

履歴を統合するもう一つの方法(git rebase)

第2章では、branch を統合する方法として git merge を学びました。

git merge は親を2つ持つ「merge commit」を作成し、2つの branch が交わった記録をそのまま残します。

しかし、多人数でのチーム開発が進むと、頻繁な分岐と merge によって commit 履歴が網の目のように複雑化することがあります。

「commit 履歴を一直線で整然とした状態に保ちたい」

その要求に応えるのが、この章で学ぶ git rebase です。

02 / 08

git rebase — branch の分岐基点を付け替える

rebase は「base(分岐基点)を re(再設定)する」コマンドです。

自分の branch で git rebase main を実行すると、自分の branch で行った commit 群を一時的に退避し、main の最新 commit の後ろに1つずつ順番に再適用(replay)します。

これにより、あたかも「最初から最新の main の上で作業を開始した」かのような、きれいな一直線の履歴が形成されます。

$ git switch feature$ git rebase mainSuccessfully rebased and updated refs/heads/feature.

03 / 08

merge と rebase の違い(歴史の残し方)

2つのコマンドの違いは、commit 履歴の残し方にあります。

  • git merge … 「branch が分岐し、ここで合流した」という事実をありのまま記録する。親が2つある merge commit が作成される
  • git rebase … branch の commit を最新の先端へ付け直し、1本の直線にする。不要な merge commit は作られない

どちらが優れているかではなく、チームの branch 運用ルールによって使い分けられます。履歴の可読性を重視するプロジェクトでは rebase が広く採用されています。

04 / 08

rebase で conflict が発生した場合の対処

rebase の実行中も、他方の commit と同じファイルの同一箇所を変更していれば conflict が発生します。

ただし、通常の merge のように git commit で解決を完了してはいけません。

1. conflict したファイルを開いて内容を修正する
2. git add . で解決したファイルを stage する
3. git rebase --continue を実行して、後続 commit の再適用を再開する

もし途中で rebase 作業を完全に中断したい場合は、git rebase --abort を実行すれば rebase 開始前の状態へ完全に安全復帰できます。

$ git add .$ git rebase --continue

05 / 08

共有済み commit は rebase しない(Git の黄金律)

rebase には、世界中の開発者が厳格に遵守している黄金律があります。

「すでに remote repository に push 済みの commit を rebase してはならない」

rebase は commit の親ポインタを書き換えるため、見た目の差分が同じであっても全く新しい別の commit hash が生成されます。すでに共有された branch を local で rebase して書き換えると、他の開発者の履歴と激しく乖離し、重大な事故を引き起こします。

rebase を使用してよいのは、まだ自分の local 環境にしか存在せず、push していない branch のみです。

06 / 08

git cherry-pick — 特定 commit の個別取り込み

もう一つの強力な履歴操作コマンドが git cherry-pick(チェリーピック)です。

「別の branch に存在する特定の commit のみを抽出し、現在の branch に複製・適用する」 コマンドです。

たとえば、長期間開発中の機能 branch の途中で作成した「緊急のバグ修正 commit」だけを、機能 branch 全体の完成を待たずに即座に main branch へ先行反映させたい場面などで不可欠となります。

$ git switch main$ git cherry-pick c3b1e2a[main a4f2c1d] バグを修正した

07 / 08

cherry-pick での conflict 解決

cherry-pick も commit の変更内容を現在の作業ツリーに適用するため、差分が衝突すれば conflict が発生します。

解決手順は rebase と同様です:

1. ファイルの conflict 箇所を編集・解消する
2. git add . で stage する
3. git cherry-pick --continue を実行して commit を完了する

操作を取り消して元の状態に戻したい場合は、git cherry-pick --abort を実行します。

08 / 08

履歴操作のコマンド体系まとめ

履歴を整えるための重要コマンドが揃いました:

  • git rebase <branch> … branch の分岐基点を指定 branch の先端へ付け替える
  • git rebase --continue / --abort … rebase の再開、または完全中断
  • git cherry-pick <commitID> … 指定 commit のみを現在の branch に適用する
  • git cherry-pick --continue / --abort … cherry-pick の再開、または完全中断

それでは、基礎演習から実践してみましょう。