Git / command / rebase

ブランチの生えている根っこ部分を別のリビジョンに差し替える操作。そのやらなければいけない目的上、歴史改変の機能を内包している。

基本

名前の通りブランチの根っこの付け替えを行う。非常にいろいろなことができるコマンドではあるがやることは↓になる。

$ git checkout hoge
$ git rebase master

まず差し替えたいブランチに移動して、移動先のブランチを指定する。 そうすると、その差し替えたいブランチとの移動先のブランチの共通の親までの一連のコミットが順番に移動先のブランチの先端にコピー(再構築)される。 その後のにコピーし終わったオリジナルの一連のコミットを破壊する。

移動先に完全コピーを作り直して、元を破壊するので見た目上付け替えたようになるということ。

オリジナルのコピーであってオリジナルではないので完全に同じ作業を手でやるのと同じである。 やったあとで確認するとわかるが、ハッシュが変わっている。つまりまったく別物で本物との繋がりは失われてしまう。 Git は分散型でオリジナルが様々な環境に存在する場合、この連続性の切断が問題を起こすことになるので注意が必要である。

rebase を中止する

rebase は長々と連続でマージ作業を行うこともあり、その中でどうにもうまくいかなかったりする。 そういう場合に中止して前の状態に戻したくなる。それがこれ。

$ git rebase --abort

多段ブランチの rebase

多段ブランチの rebase の場合はどうなるんだという話。

これは開発中に PR でよく起こりうる問題である。PR 出したんだけど、なかなかマージされない、しかしそのマージを前提にした先行開発はしたいという場合このような多段ブランチの運用をやりたくなる。

実際にやるとどうなるのか?

このような構成を考える

branch B                           ---- 8 ---- 9
                                  /
branch A             ---- 5 ---- 6 ---- 7
                    /
master ---- 1 ---- 2 ---- 3 ---- 4

ここで ブランチAmaster 先端へ rebase するとどうなるか?

branch B                           ---- 8 ---- 9
                                  /
branch A             ---- 5 ---- 6       ---- 5'---- 6'--- 7'
                    /                   /
master ---- 1 ---- 2 ---- 3 ---- 4 ---- 

このようになる。通常の rebase 動きの通り ブランチAmastar 先端に別物として再構築されるのだが、ブランチB は元ブランチAだった部分も含め移動せず維持される。 問題は途中まで一緒だった共通部分が別物として増殖してしまうということだ。

では最初の構成から ブランチB を rebase した場合はどうなるか?

branch B                                          ---- 5'---- 6'---- 8'---- 9'
                                                 /
branch A             ---- 5 ---- 6 ---- 7       /
                    /                          /
master ---- 1 ---- 2 ---- 3 ---- 4 -----------

このようになる。同じように共通部分を残したまま先端に再構築される。共通部分が増殖するのも同じである。

なので1回こっきりのスタートとして多段ブランチして進めるというのはありであるが、これを連続で行って開発をやっていくのは厳しいという感じがする。

vcs/git/command/rebase.txt · 最終更新: 2021-07-02 16:58 by ore