TL;DR
一度もpushしていないブランチの場合、rebaseを使う。
push済みブランチの場合、merge —-squashを使う。
はじめに
GitHub Flowで開発中、自分の作業topicブランチに対して、他の人の作業内容をmasterからマージするとき、git merge master
を使うとマージコミットログが残る。
その後、プルリクエストのコミットログにmasterから作業topicブランチへのマージコミットログが残ってしまう問題がある。
マージコミットログは「作業ログ」であって、masterへのコミットログに含めるのは不自然な気もするので、対策を考える。
rebase
masterからマージするときに、git rebase master
を使う。
ただし、一度もpushしていないブランチに限る。理由はこちら
Git rebaseの影響で同内容のコミットが量産される件について
「pushはプルリクエスト直前に1回のみ」という前提で採用できる。
コンフリクトが発生する場合は、作業topicブランチにコミット毎に解消する必要がある。
開発人数が多いと、コンフリクトが発生する可能性が高くなるため、別の手段を検討したほうがよい。
merge --squash
複数のコミットを1つのコミットに集約するコマンド。
使い方としては、
- masterから作業topicブランチへのマージは
git merge master
を使う - pushも可能
- masterへのプルリクエスト時、masterから新たにプルリクエスト用ブランチを作成し、作業topicブランチのコミット内容を
git merge --squash 作業topicブランチ
でマージする
こうすることで、masterから作業topicブランチへのマージコミットログは消え、プルリクエスト用ブランチにはコミットログが1つだけ残る。
ローカルでの作業topicブランチへのコミットログも消えてしまうため、細かい単位でmasterへマージしたい場合は、その都度プルリクエスト用ブランチの作成→マージを繰り返すので、ちと面倒くさい。
rebase + push -f
「push済みのブランチではrebaseしてはいけない」という制限事項は、正確にはrebaseはできるが、リモートへのpush時にエラーとなることに起因する。(rebaseするとハッシュ値が変わるため)
そのため、-fオプションを使えばpush済みブランチであっても、rebase可能となる。
しかし、-fオプションを使うと、リモートの内容を強制的にローカルで書き換えるため、そのブランチで他の人がコミットしていた内容が消えてしまうリスクがある。
言い換えると、自分しか使っていないことが保証できるブランチであれば、問題ない。
参考
git rebase に関するメモ
こわくないGit
慣れてきたらコミットをまとめてPull Requestしよう(git merge --squash)