LoginSignup
15

More than 1 year has passed since last update.

ブランチを途中からリベースしたい

Last updated at Posted at 2022-02-22

はじめに

リベースは便利ですよね。
私はよくお世話になっています。

なんていうか、
mainブランチとか真っ直ぐな方が好きだな~なんてw

ほら、普通にマージしたりしていくと、
マージコミットが入って、2本が1本に合流する点ができて
その先にまた別のブランチが合流して・・・

あんまり綺麗に思えないというか・・・。

あと、コンフリクトが発生したときの解消が後回しっていうのが・・・。
問題は先に解決しておきたい派なので、なんだかなーなんて感じてしまいます。

とまぁ、私のような人だと分かってもらえると思うんですけど、
PRを投げて待っている間に実装進めておこうとかすると結構ブランチが直列になるんです。

そして、PRのapproveもらったらsquash mergeでfast-forward mergeして・・・
そうすると、直列先のブランチが残っちゃうんですね。

ここで途中からリベースしたいという需要が生まれる訳です。

方法

いくつか方法はありますが、今回は--ontoを使用したリベースを紹介します。

コマンドとしては、以下のようになります。

コマンド
$ git rebase --onto (移動先) (どこから) (どこまで)

と言っても、このままだと分かりづらいと思うので、
いくつかのパターンを具体例として、どういう動作をするのかを見ていきましょう。

git rebase --onto A B C

このA、B、Cはブランチ名とします。

つまり、以下のような状態だと思ってください。

image01.png

そして、コマンドから読み解くと、以下のようになりますね。

image02.png

これがコマンドを叩くことにより、以下の状態になります。

image03.png

ここで注意する点は、あくまで移動するのはBよりも先だけということです。
Bの最後のコミットは含まれません。

あくまでB(どこから)の指定は、基準に過ぎないということです。

git rebase --onto A hashB C

先程と同様で、A、Cはブランチ名とします。
そして、先程とは異なり、hashBはコミットハッシュです。

ブランチCを途中からAにリベースしたいけど、都合良くブランチがないって感じですね。

image04.png

もう動作は想像できると思いますが、以下のようになりますね!

image05.png

応用編

ここからは応用編です。

git rebase --onto A B B

今回はA、Bをブランチ名として、2種類しか存在しません。
「どこから」と「どこまで」が一致しているという状態です。

image06.png

そして、思い出してほしいのは、
「どこから」の指定は基準で、移動に含まれないということです。

つまり、「Bより先で、Bまで」を移動することになるのですが、
結論から述べますと、何も移動せず、ブランチだけ移動することになります。

image07.png

ブランチ名だけを移動させたり、中身をリセットしたりする用途でも使えるかもしれませんね。

【2022/02/24 9:44 追記 ここから】
ちなみに、以下のコマンドも同様の操作になります。
ちなみに、Bのブランチをチェックアウトしている状態であれば、以下のコマンドでも同様の操作になります。

この指定でも同じ操作(Bのブランチをチェックアウトしている状態であれば・・・)
$ git rebase --onto A B

「どこから」と「どこまで」が一致しているので省略可能ということですね。

これに関しては、誤りでした!!
申し訳ございません!!

操作的には、
git rebase --onto A Bは、git rebase --onto A B headの操作になるため、
Bのブランチをチェックアウトしていない状態だと想定外の動作をして、あなたを混乱させる原因になるところでした!

指定が省略できるからって簡単に省略してはダメですね・・・。

また、

めちゃくちゃになってしまったブランチを元の状態に戻したいなら、リベース前のコミットIDをメモしておいてgit reset --hard 《リベース前のコミットID》を実行しましょう。

というコメントを頂いております。

まだまだ発展途上であることも承知の上での記事作成なので、
こうして誤りを指摘していただけることがありがたい限りです。

今後も自身の知識をアップデートしながら、成長のため誤った内容の記事をまとめることがあるかもしれませんが、
そのときは是非とも「間違ってるよ」って教えていただけると幸いです。

【2022/02/24 9:44 追記 ここまで】

コンフリクトの解消

基本はリベースしたときの解消方法と同様です。

コンフリクトが起きた時点で、リベースが止まりますので、
コンフリクトを解消するためにコードを修正しましょう。

コンフリクトが解消できましたら、
SourceTreeなどを使用しているのであれば、忘れずにステージし、
コマンドであれば、忘れずgit addしましょう。

その後に、
git rebase --continueでリベースを再開する、
という手順ですね。

注意点

もう分かってるよ!っていう方もいると思いますが、念のため・・・。

プッシュする前のリベース作業

元に戻すのが困難になるのでお勧めしません。

プッシュしておけば、
万が一リベースをミスしてもローカルのブランチを破棄して、
リモートからブランチを切ることで簡単に元の状態に戻せます。

プッシュしてからリベース作業は行うようにしましょう。

強制プッシュ

リベースには強制プッシュが付き物ですね。

強制プッシュは簡単にできてしまいますが、
破壊的な操作であることを忘れずに
慎重に操作するようにしましょう。

特に、--force-with-leaseをつけて、
比較的安全に強制プッシュができるようにするのは当然の配慮ですよ!

「どこから」の指定をミスする

慣れない内はやってしまいがちかもしれません。
そのため、プッシュしてからリベース作業を行うことは重要になります。

「どこから」で指定したコミットは移動に含まれませんので、
移動させたい最初のコミットの1つ前のコミットを指定しましょう。

さいごに

少しまとめてみましたが、いかがでしょう。
参考になれば嬉しいです。

ただリベースもコンフリクトも非常にシビアなので、
困ったときは先輩・上司を巻き込むことをお勧めします!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15