エンジニアの友達にgithubなどgitを使用した共同開発時の豆知識を教えてもらったので、忘れないようにメモしておきます。Thanks, Shawn!
マスターとのマージ時には事前にgit rebaseを使う
gitを使って共同開発をすると、たまにこんなコミットメッセージを見る機会があるかもしれません。
- Merge branch ‘master’ of git://github.com/hogehoge
これは、最新のマスターを私のブランチにマージしたわよ、という意味合いのコミットメッセージなのですが、正直いりません。開発者それぞれがブランチとマスターをマージするたびにこのようなメッセージをログに残してしまうと、それだけでコミット履歴を占有し、重要な情報をたどるのが困難になります。
このマージ時のコミットメッセージが発生してしまう原因は、左側の図のようにpull requestを出す前に最新のマスターを自分のブランチにマージしたいためです。ここで、git pullやgit merge origin/masterをする代わりに、git rebase masterを使いましょう。
git rebase masterで自分のベース(ブランチを作った位置)を最新のマスターと置き換えることにより、自分のコミット(図で言うとadd new function X, modify function Y, fix issue Aの3つ)は最新のマスター以降に起こったものとなり、最新のマスターを自分のブランチにマージするという作業、コミットがなくなります。後にpull request #3をマスターにマージした時も、左側の図だとmerge branch ‘master’ of git…を含めた合計4つのコミット履歴が残るのに対して、rebaseした場合は3つの履歴しか残りません。
注意: rebaseを行ったあとは、ブランチを普通のpushではなくforce pushする必要があります。コマンドは
- git push -f origin [branch_name]
rebaseの時にconflictが起こる場合
これを教えてくれた私の友人は、一度ブランチを作ってしまうと作業中のファイル群はほぼ自分しか修正を加えないので、rebaseの際にconflictが起こることは少ないと言っていましたが、もちろんconflictが起こる可能性もあります。その場合は、conflictを解消しgit rebase –continueを行うか、なにかちょっと良くないことが起きている時はあきらめてgit rebase –abortしてrebaseする前の状態まで戻します。
git -i rebaseを使ってインタラクティブにrebaseする
PythonにはPEP8という公式のコーディングスタイルがあり、それに基づいたチェックができます。しかし、例えば上の図でいうとfix issue Aまで終わってからPEP8をしていなかったという事に気づき、PEP8をしたところ新たに少し変更が生じたとしましょう。それをpep8 fixesとしてコミットしてしまうのはあまりに申し訳ない感じです。
こんな時、git rebaseをするときに-iを追加することで、インタラクティブにrebaseが行えて、このrebaseの際に申し訳ない感じのコミットを一つ前のコミットに吸収合併させることができます。また、あの時勢いで適当に書いてしまったコミットメッセージも編集できます。
ここで、例の図のfix issue Aの後ろにpep8 fixesというコミットがあったと仮定すると、git rebase -i masterを行った時に出てくるインタラクティブな画面(というかテキスト編集画面)は以下のようになります。
pick a123456 add new function X pick b123456 modify function Y pick c123456 fix issue A pick d123456 pep8 fixes # Rebase a123456 . . d123456 onto z123456 # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like squash, but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. #
細かいそれぞれのコマンドの説明はどこかにあると信じて、今はとにかくpep8 fixesをコミット履歴に残さないようにしたいので、対象行のpickの部分をfに書き換えて変更した部分自体は前のfix issue Aに混ぜてもらって、コミットログメッセージはなかったことにします。vimの要領で書き換えでき、:wqで保存して終了できるので、書き換えた後は終了してrebase処理を実行します。Successfully rebased and updated refs/heads/master.が出たら成功です。
Leave a Reply