〜宣伝〜
個人開発でエンジニア専門マッチングサービスを開発しましたので、是非未経験からエンジニア目指している人!現役エンジニアで教えたい人!使ってみてください!
β版リリース記念キャンペーン中です!
10名様限定、抽選でお好きな技術本1冊プレゼント!
🎉当選者にはメッセージ差し上げます(送付の際に住所はお聞きしません)
詳しくはこちらから↓
概要
- Gitのmergeとrebaseの違いが自分の中で曖昧だったのでまとめてみた。
ことの発端
- 「プルリク出す前に分岐元ブランチの最新状態にrebaseしてください」とよく聞く。
- 「履歴がきれいになるから」とか「差分が見やすいから」とかよく言われているが、実際どんなことなんだろうと気になった。
- なんで「分岐元ブランチの最新状態を作業ブランチにmergeする」はだめなのかもよくわかっていない。
前提情報
-
今回の説明で使用する各ブランチの状況を図にまとめてみた。
-
言葉で説明する。(ごちゃごちゃ記載しているので「?」となったら図だけ見ていただければOK)
- mainブランチとworkブランチがある。
- mainブランチは下記の順でコミットされている。
- first_commit
- コミット1
- コミット2
- コミット3
- workブランチはmainブランチのコミット1の直後から分岐して下記の順でコミットされている。
- first_commit
- コミット1
- 開発コミット01
- 開発コミット02
- mainとwork両ブランチの時系列順のコミット履歴は下記の様になる
- first_commit
- コミット1
- コミット2
- 開発コミット01
- 開発コミット02
- コミット3
merge
-
ローカルリポジトリで下記コマンドを実行して最新のmainブランチをworkブランチにmergeしたとする。
$ git switch main $ git pull origin main $ git switch work $ git merge main
-
下記のような結果になった。
-
mainブランチのコミットとworkブランチのコミットが時系列順にまとめられた。
rebase
-
ローカルリポジトリで下記コマンドを実行して最新のmainブランチの状態にworkブランチをrebaseしたとする。
$ git switch main $ git pull origin main $ git switch work $ git rebase main
-
下記のような結果になった。
-
mainブランチのコミット履歴の後にworkブランチのコミットが並んだ。
まとめ
- 振る舞いとしては下記の様になった。
- merge: 時系列順に両ブランチのコミットをまとめる。
- rebase: 分岐元ブランチのコミット履歴 → 分岐先ブランチのコミット履歴の順に並ぶ。
- mergeとrebaseで大枠の「mainブランチの変更をworkブランチに取り込む」は達成できている。
- しかし、mergeだと「時系列」でみるとコミット履歴はきれいだが、「個々の開発」として見るといろいろなコミットが入り混じってて見にくい。
- 特にこだわりがない限り、プルリク作成前にはrebaseを用いたほうが良さそうだ。(ただし、コンフリクトしている場合はrebaseのほうが面倒な場合もあるのでケースバイケース。とりあえず、毎日こまめにrebaseしたほうがPR作成時に辛くないかも。)
2024/04/11 追記
ぱっとみrebaseのほうが整理されていていい気がする。実際その通りできれいに整理されている。
ただ、mergeやrebase時にコンフリクトが発生するとrebaseはかなり面倒である。コミット2やコミット3などのコミット毎にコンフリクトを修正する必要があるはずである。(間違えてたらすみません。)
絶対に「mergeは許さん」みたいなプロジェクトじゃない場合、コンフリクトしたらmergeで一回のコンフリクト修正で終わらせてしまう方が楽なのかも。
「mergeは許さん」なプロジェクトなら、こまめにrebaseを挟んだほうが楽だと思った。