merge の形式(メモ代わり)
merge pr の時、選択は三つあります
- 普通の merge
- rebase merge
- squash merge
この三つ何か違うのは、ローカルブランチ使って説明していきます
##masterブランチモデル
例えばこのブランチに幾つのcommitあったとして
そして、また新しいブランチを作って、開発し幾つのコミットをします、そうすると、全体図はこういうふうになります
普通の Merge
ブランチを合併する時、よくあるのは以下の操作になります
masterブランチにcheckoutして,合併
:git merge devel
そして用済みのブランチを削除
:git branch -D devel
リモートブランチへpush
:git push origin master
一見何の問題もないけど、でも実際どんな結果になったのでしょうか,合併前のブランチは以下の様です
操作後は
一見悪くない、真っ直ぐなcommitラインになってます,develブランチ内のコミットも全部masterブランチに記録されている、でも、果たしてこんなに多くのコミット記録する必要があったのでしょうか
例えば数十人も参加するおおきなプロジェクトがあったとして、一つ修正のために、ちょっとしたミスで数十個のコミットをPRしてしまい、しかもmergeされました,その時、このプロジェクトのヒストリーにどうでもいいcommit数十個増えてしまう、マネージャーそれを見ると困惑するでしょ、しかも何回も繰り返しをすれば、rollbackも大変な作業になるでしょ
squash merge
複数のcommitを一つに合併する時、 git commit --amend,使えば 自分のcommit履歴が確認出来,pick で選び,squash 合併など。同様に,merge の時も出来ます、手順は二つだけ
ブランチを切り替え:git checkout master
squash 形式でmerge merge:git merge --squash devel
この時masterブランチで未提出のcommitが出てきます、注意すべきのは、それが自分のcommitであること,つまりcommitのauthorを変えた、結果、以下の様になります
普通のmergeよりはいい、今commitは一つになった,サブブランチでいくらcommitしたとしてもここは一つしかない!
rebase merge
もし合併して更に作者のデータを残したければ、rebaseを使ってみましょう
まず devel ブランチへcheckout:git checkout devel
リベース:git rebase -i master
master ブランチへ戻る :git checkout master
合併: git merge devel
二番目の操作は、develでmasterを参照にリベース、リベースはつまり、ふたつのブランチの共通の先祖に移動して、現在のブランチで先祖から今までのcommitを合併,なので二番目の操作ではこのcommitたちの処理方法が選べる、この時masterにmergeしても、commit記録は一つしか残らない、以下の様に
現在のcommit historyはよくなったが、注意すべき点は元のcommit historyを変換したければブランチの開発者は自分でリベースしなければならない
この三つの方式を比較すれば、いくつの結論が得られます:
- rebase masterを綺麗な状態にし、author の識別もしやすい
- squash もmasterを綺麗な状態にたもてるが,masterのauthorは全部maintainerであって、元のownerではない
- merge masterの履歴汚しますが、全てのcommit historyが記録された