おはようございます、YASUです。
Gitでは、これまでmergeとコンフリクト解消を扱ってきましたが、もう1つ、rebaseというコマンドがあります。名前は聞いたことがあっても、mergeとの違いがよく分かっていなかったので、シンプルに整理しました。
目次
結論
mergeは「枝分かれした2つの履歴を、合流させる」、rebaseは「自分のブランチの土台を、最新のmainに付け替える」コマンドです。mergeは履歴がそのまま残り、rebaseは履歴が一直線になります。
まず、枝分かれした状態
mainとfeatureが、途中で別々にコミットを積んだ状態を考えます。
* d6e356b feat: add feature ← featureブランチ
| * 5232505 docs: add main ← mainブランチ
|/
* b705951 chore: start ← 分かれる前の共通の履歴
この2つをまとめる方法が、mergeとrebaseです。
merge:合流させる
featureをmainにmergeすると、2つの履歴を合流させる「マージコミット」が1つ増えます。
* 488b925 Merge branch 'feature'
|\
| * d6e356b feat: add feature
* | 5232505 docs: add main
|/
* b705951 chore: start
- それぞれのコミットは、そのまま残る
- 「ここで枝分かれして、ここで合流した」という履歴が見える
- マージコミットが増えるので、履歴がやや複雑になる
rebase:土台を付け替える
featureブランチでgit rebase mainを実行すると、featureのコミットを、いったん取り外して、最新のmainの先頭に付け直します。
* cc2c23d feat: add feature
* 5232505 docs: add main
* b705951 chore: start
- 履歴が、枝分かれのない一直線になる
- マージコミットができないので、履歴が見やすい
- 付け直したコミットは、作り直されて、ハッシュが変わる(上の例では、d6e356bがcc2c23dに変わっている)
この「ハッシュが変わる」というのが、rebaseで一番大事なポイントだと感じました。中身は同じでも、Gitから見ると別のコミットになっています。
使い分けと、注意点
- 履歴を一直線にきれいにしたい、自分だけのブランチ → rebase
- 履歴をそのまま残したい、みんなで使っているブランチ → merge
注意したいのは、すでにpushして、他の人が使っているブランチでは、rebaseしないことです。rebaseはコミットを作り直すので、履歴を書き換えることになります。前に書いた--amendと同じで、push前の、自分だけのコミットに使うのが基本です。
まとめ
- mergeは、枝分かれした履歴を合流させ、マージコミットができる。履歴はそのまま残る
- rebaseは、自分のブランチの土台を、最新のmainに付け替える。履歴が一直線になる
- rebaseでは、コミットが作り直されて、ハッシュが変わる
- push済みで共有されているブランチでは、rebaseしない
mergeは「合流」、rebaseは「付け替え」と覚えておくと、違いがすっきりしました。それでは、また明日!

コメント