リベースとは
以下の図のようなブランチが存在したとしよう。
このとき、topic
ブランチをmaster
ブランチでリベースすると、次のようになる。
$ git checkout topic
$ git rebase master
コミット3'
は、コミット2
とコミット3
の変更を統合したコミットであり、コミット2
を親コミットに持つ。
つまりリベースとは、アバウトに言えば、名前の通りあるブランチのベース(根本)を付け替える操作なのである。
仕上げにmaster
も最新の状態にしよう。コマンドはこちら。
$ git checkout master
$ git merge topic
詳しく言えば、これは分岐の生じないマージ、ファストフォワードなマージである。
リベースのメリット・デメリット
マージと比較した際、リベースのメリットは履歴が簡潔である点である。なぜなら、マージをすると親コミットを2つ持つマージコミットが作成されるが、リベースで作られるコミットは親コミットを1つしか持たない。そのため、履歴が一直線に並ぶのである。
逆にリベースのデメリットはコンフリクトした際の解消が面倒であることである。なぜかは複雑なので今回は省略する。
リベースはするなって本当?
巷ではよく「リベースはするな」という言説が飛び交っている。たしかに、マージで代替できるので、わざわざリベースをする必要はないのかもしれない。ただし、本当にリベースしてはいけないのは、下記の条件をすべて満たすときである。
- コンフリクトが生じないことが明らかである
- リベースするブランチをリモートリポジトリにプッシュしていない
逆に言えば、これらの条件をクリアしていれば、履歴を完結するためにもリベースを採用した方がよい。
2番目の条件について詳しく見ていこう。すでにプッシュしたブランチをリベースするとどうなるだろうか。リベースとは、根元を付け替える、ある種の破壊的な操作である。すると、ローカルとリモートで図のように構造の差異が生じる。
仮に、このあとリモートの方でtopic
に変更があったとしても、構造が違うのでtopic
はプルできない。これが、プッシュしたブランチはリベースしてはいけない理由である。
最後に
今回はリベースを紹介したが、正直どちらを使うかはお好みでよい。ちなみに、プルでは暗黙的にマージを使って変更を統合しているが、リベースを使ってプルを行うこともできる。それは今回の記事では紹介しないので、気になったら調べてみてほしい。それでは。