mercurial: branchで行ったバグフィックスをtrunkに適用する
Mercurialのような分散型のソースコード管理システムには、subversionのようなtrunkとbranchの区別はないけれど、実際の運用ではそれに類似した概念をみんな使っていると思う。
数日後にウェブアプリケーションのβ版をリリースする予定だとすれば、mainのレポジトリからbetaをcloneする。このbetaがブランチである。
% hg clone main beta
ひと月後に控えた正式リリースまでには、まだ機能を追加しなければならないので、プログラマーたちはmainレポジトリに対してpushを続ける。
β版はすでに本番サーバにデプロイされていて、テスト担当者たちが徹底的に動作確認をしており、バグが見つかればプログラマーたちは急いでソースコードを修正し、betaレポジトリにpushする。
さて、このバグの修正をmainレポジトリに反映させるにはどうすればいいか。
私は以下のように行った。
% cd beta_work
% hg export 123 > ../bugfix.patch
% cd ../main_work
% hg import --no-commit ../bugfix.patch
数字の123はバグを修正したchangesetの番号である。番号は複数指定することもできる。
importコマンドの--no-commitは重要。テストもしないでコミットしてはならない。
問題の修正箇所に関わるファイルがbeta_workとmain_workの間で変化していなければパッチの適用は成功するが、そうでなければ失敗するかもしれない。その場合は、次のようなメッセージが表示される。
patching file app/models/user.rb
Hunk #1 FAILED at 23
1 out of 1 hunk FAILED -- saving rejects to file app/models/user.rb.rej
このときは、app/models/user.rb.rejの中身を見て、手動でapp/models/user.rbを修正する。
修正が終わったら、もちろんテストをする。
% rake
テストが通り、問題がないようであれば、commitしてpushする。
% hg commit -m 'Bug fix'
% hg push
もっとエレガントな手順があるのかもしれないが、とりあえず私のやり方である。