rebaseの仕組み
rebase
は、親ブランチの最新状態を基準にして、現在のローカルブランチのコミットを新しいコミットIDで再適用し、履歴を直線的に整理する操作。
つまり、最新のリモートのコミットIDの後ろにローカルで行ったコミットを乗せて、履歴を一直線にする。
よって、マージコミットは発生しない。
git rebase
主な用途の例
一つのタスクに対してコミットが複数になって見にくくなった場合、コミットを一つ(もしくはわかりやすい単位)にまとめて履歴をきれいにする。
git pull --rebase
主な用途の例
- マージコミットがなくなるため、コミットの履歴がきれいになる
- リモートの最新状態を反映した状態でローカルの作業を行うことができる
rebaseとmergeの違い
-
merge:
- 2つのブランチの変更を統合するが、マージコミットが発生し、履歴が分岐してしまう
-
結果の履歴例:
A - B - C (main) \ D - E - F (feature) \ G (merge commit)
-
rebase:
- ブランチの変更を直線的に整理し、マージコミットが発生しない
-
結果の履歴例:
A - B - C - D' - E' - F' (feature)
- 履歴がきれいになるため、コードレビューやデバッグがしやすい
rebaseの注意点
-
履歴が書き換えられる
-
rebase
によって、元のコミットIDが変更されるため、リモートにプッシュ済みのブランチでリベースを行うと履歴が不整合になる。 - 対策: チームで作業中のブランチでは、リモートにプッシュする前にリベースを行う。
-
-
コンフリクトが発生しやすい
- 特に複数の開発者が同じ部分を変更している場合、リベース中にコンフリクトが発生する場合がある
-
対策: コンフリクト解消後、
git rebase --continue
を忘れずに実行する
-
チーム運用に合った使い方を検討する
- チームでリベースを使う場合、ルールを決めておくと混乱を防げる(例: プッシュ前にリベースを徹底する)
実践例
リベースで履歴を整理する
-
現在のブランチで過去3つのコミットを整理:
git rebase -i HEAD~3
pick a1b2c3 修正1 squash d4e5f6 修正2 squash g7h8i9 修正3
A - B - C - 修正まとめ (feature)
※ちなみに、pickとsquashの違い↓
キーワード | 動作 | 結果 |
---|---|---|
pick | コミットをそのまま残す | 履歴がそのまま維持される |
squash | コミットを1つ前のコミットに統合する | 履歴が圧縮され、不要なコミットが消える |
リモート変更を取り込むリベース
git pull --rebase origin main