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

もっとエレガントな手順があるのかもしれないが、とりあえず私のやり方である。