--rebase
をつけた場合とつけない場合でどのような違いがあるかについて理解していなかったので、調べてみたのでその内容をまとめたいと思います。
前提
Mainブランチあり、そこからFeatureブランチを切って開発しているとします。そこで、他の人の変更がMainブランチに入り、自分はその変更を使いたいケースを考えます。
この場合の方法は2種類あります。一つはプルする方法、もう一つはリベースする方法です。まずはプルする方法からまとめます。
プルする方法
コマンドは簡単で、featureブランチからgit pull origin main
です。
こうすると、FeatureブランチにMainブランチの変更がまず入り、そこにFeatureブランチの変更が加えられます。コミットはそのまま使われ、また必ずマージコミットが追加されます。
文字で書いても意味不明なので、図で書くとこんな感じになります。
- Featureブランチのコミットがそのまま使われる
- 必ずマージコミットが打たれる
次にリベースする方法を見ていきます。
リベースする方法
こちらはプルするときにオプションで--rebase
を指定し、git pull --rebase origin main
とします。
こうすると、FeatureブランチにMainブランチの変更が入るところまでは一緒で、そこからFeatureブランチの変更が加えられるのですが、そのやり方に差があります。
リベースでは変更されると、そこで新しくコミットされる形をとります。コンフリクトが起こった場合はリベースの度に解消していき、結果的に下のような図の状態となります。
- Featureブランチのコミットとは別のコミットが打たれる
- マージコミットは打たれない
このような特徴があるため、リベース前の状態でリモートブランチにプッシュしてある場合、リベースをした後はコミットが書き換わるので、プッシュできなくなります。そのため、--force
オプションをつけて強制プッシュをする必要があります。
そのブランチが自分だけのものだった場合は大丈夫ですが、他の人も共用で使っている場合には大惨事になるので注意が必要な操作です。
リベースだと作業が増えるのでプルでいいやとなりがちですが、リベースの場合だと他のブランチを取り込んでもFeatureブランチのコミット履歴が汚れないため、リベース派の人も多くいる印象です。
操作ログ
実際に上のことが起きていることを確かめたログを貼っておきます。間違えて3のコミットを2回打ってしまいましたが、影響ないのでスルーでお願いしますmm
Mainブランチ
$ git log --oneline 2022-09-23 15:30
f96a5f1 (HEAD -> main, origin/main) 4
97b2afe 3
6ae9a4d 3
0d054ed 2
9aa26f4 initial commit
取り込み前のFeatureブランチ
$ git log --oneline 2022-09-23 15:32
590a047 (HEAD -> main) 6
bbb4f5f 5
9aa26f4 initial commit
プル後のFeatureブランチ
9fc36 (HEAD -> feature) Merge branch 'main' of github.com:shun0211/git-demo into feature
590a047 6
bbb4f5f 5
f96a5f1 4
97b2afe 3
6ae9a4d 3
0d054ed 2
9aa26f4 initial commit
リベース後のFeatureブランチ
$ git log --oneline 2022-09-23 15:26
1a9747b (HEAD -> feature) 6
6f3cf43 5
f96a5f1 (origin/main, main) 4
97b2afe 3
6ae9a4d 3
0d054ed 2
9aa26f4 initial commit
プル後ではFeatureブランチのコミットが使われているのに対して、リベースでは書き換えられているのが分かりますね。また、マージコミットが打たれていないことも分かります。
まとめ
以上、今さらな内容かと思いますがまとめてみました。
分かりにくいやアドバイス等ありましたらコメントくださると幸いです。では!
Twitterもやってますので、フォローしていただけるとうれしいです。