概要
git rebase はマージとは違いヘッドの位置を移動することであたかも別ブランチの修正をマージしたかのように見せます
rebase を使ったほうがコミットログがキレイになる場合があります
しかしなぜか rebase 後は force push しなければならなかったり結局マージと同じことをしている場合がありうまく使えていないことがありました
なので今更ながらちゃんと使い方を把握しておこうと思います
準備
まずは動作確認するための環境を作成します
リモートリポジトリは Github を使います
master ブランチ
touch memo
vim memo
a
git add .
git commit -m "first commit"
git push -u origin master
b1 ブランチの作成
master ブランチから作成します
git branch b1
git checkout b1
vim memo
a
b
git add .
git commit -m "second commit from b1"
git push -u origin b2
b2 ブランチの作成
このブランチは b1 ブランチから更に生やします
git branch b2
git checkout b2
vim memo
a
b
c
git add .
git commit -m "third commit from b2"
git push -u origin b2
でここまでのブランチごとのコミットの状況は以下のようになります
なのこの図は Github の「Insights」->「Network」から確認できます
b1 ブランチで修正が入る
git checkout b1
vim memo
a
b
d
git add .
git commit -m "thrid commit from b1"
b2 ブランチを b1 ブランチに rebase してみる (force push)
やりたいことは先程の b1 ブランチの修正を b2 ブランチにマージではなく rebase することでコミットログをキレイにします
git checkout b2
git rebase b1
何も考えずに上記を行うと当然ですがコンフリクトして rebase できません
エラーの内容は以下の感じです
ファイルにはコンフリクト部分が記載されています
a
b
<<<<<<< HEAD
d
=======
c
>>>>>>> a811605... third commit from b2
このコンフリクトを解消した上で rebase してみます
vim memo
a
b
c
d
git add .
git commit
git rebase --continue
git push -u origin b1
しかし以下のようにエラーが発生します
理由は単純でリモート側のコミットログとローカルで rebase したコミットログが異なるため push できず force push を余儀なくされている感じです
ではどうするかいうと結局 force push するしかなくなります
git push -f origin b2
一応これでコミットログ的には b1 の続きとして b2 が作成されていることになるのでキレイにはなります
しかし force push しなければならないので権限がない場合などこれだと対応できません
force push しないようにするには
ではコンフリクトありの rebase 時に force push しないようにするにはどうすれば良いか考えます
最初はコンフリクトしない rebase なら大丈夫かなと思ったんですが結局ローカル側のコミットID が変わってしまうようなので force push が必要になります
いろいろ考えたのですが rebase -> push を force push なしでやる場合にはリモート側にまだ push していないコミットがある場合にだけ使うしかないと思います
すでにリモート側に push しているコミットがあるブランチで rebase -> push する場合には force push は必須にするしかないと思います
Tips: やり直したい場合は
リモート側に hard reset しましょう
git reset --hard origin/b2
まとめ
merge と rebase の使い分けは以下の通りかなと思います
- 基本は merge
- リモート側にまだ push していないコミットがある場合に限り rebase
- どうしても rebase したい場合は force push を使う
0 件のコメント:
コメントを投稿