series ファイルを直接編集せずにパッチ適用を制御
TokyoMercurial #1 で話題になった件の詳細シリーズ - その3。
MQ で管理しているパッチが複数ある場合、適用順序を入れ替えたり、適用の要否を制御したくなったりすることが多々ある。
純粋に適用順序を入れ替えたい場合、僕なら脊椎反射的に .hg/patches/series ファイルを編集しちゃうのだけれど、これが皆に薦められる手法か?と言うと、流石にちょっと不恰好で美しくない。
1つ2つ程度の順序入れ替えであれば:
$ hg qseries 1st 2nd 3rd 4th $ hg qapplied $ hg qpush --move 3rd applying 3rd now at: 3rd $ hg qseries 3rd 1st 2nd 4th $ hg qapplied 3rd $
上記のような "hg qpush" への "--move" オプション指定によって、パッチ適用順序を変更してやれば良い。
一時的にパッチの適用を抑止したい場合は、パッチ順序の入れ替えではなく、qguard/qselect を使用するのが便利。
例えば、先の例のように 1st 〜 4th のパッチが MQ 管理下にあって、何らかの理由により一時的にパッチ 2nd の適用だけを除外したい場合、適用順序を入れ替えて 2nd を末尾に移動させた上で、適用対象から除外しても良いのだけれど、『うっかり戻すのを忘れた』とかで痛い目に会うのが目に見えている。少なくとも僕は、あまり自分を信用していないので (^ ^;;)。
で、こういった場合は、"hg qguard" を使用することでパッチ 2nd の適用を抑止してやれば良い:
$ hg qapplied $ hg qguard 2nd +drop_temporarily $ hg qpush -a applying 1st skipping 2nd - guarded by '+drop_temporarily' applying 3rd applying 4th now at: 4th $ hg qapplied 1st 3rd 4th $
実行例のように、"hg qpush -a" により『全パッチ適用』を指示しても、『ガード』指定の付いたパッチ 2nd の適用は抑止される。
2nd を適用したい場合は、2nd に設定した『ガード』を、"hg qselect" によって選択してやれば良い:
$ hg qapplied $ hg qselect drop_temporarily number of unguarded, unapplied patches has changed from 3 to 4 $ hg qpush -a applying 1st applying 2nd applying 3rd applying 4th now at: 4th $ hg qapplied 1st 2nd 3rd 4th $
# "hg qselect" への指定では drop_temporarily に "+" が付かない点に注意!
"hg qguard" によって各パッチに設定される『ガード』には、『正(+)のガード』と『負(-)のガード』の2種類があって、"hg qselect" による『ガード選択』と組み合わせることで、以下のようにパッチ適用が制御できる:
- 『正のガード』は『ガード選択』された場合にのみ適用
- 『負のガード』は『ガード選択』されない場合にのみ適用
例えば "+A", "+B", "-C" の3つのガードが設定されたパッチは、"hg qselect" によって A および B が選択され、且つ C が選択されない場合にのみ適用される。
人によっては、あまり『ガード』の利用シーンが想像できないかもしれないけれど、例えば僕の場合だと:
本番環境の特殊な機材の挙動を、テスト環境で擬似実現するための実装を MQ パッチで管理。
複数のテスト環境/機材毎に個別のパッチを作成し、それぞれに『正のガード』を設定。
テストを実施する環境/機材に応じた『ガード選択』の後にパッチを適用。
とか:
リリースブランチと開発ブランチの差分が一時的に肥大して、同一の MQ パッチでは適用が難しくなってしまった場合。
各ブランチ向けに個別パッチを作成して、それぞれに『正のガード』を設定。
適用対象ブランチに応じた『ガード選択』の後にパッチを適用。
といった運用をしていた。
MQ パッチで適用する変更内容も成果物に含めて良いなら、もうちょっと根本的な (= 環境依存性を下げる) 対応をするのだけれど、受託開発の場合、発注元がその手の成果物の混入を嫌がるケースが多々あるのだ。
後者の運用に関しては:
リリースブランチ向けパッチには『正のガード』(e.g.: "+RELEASE")を、開発ブランチ向けパッチには同名の『負のガード』(e.g.: "-RELEASE") を設定。
『ガード選択』の有無に応じて、必ずどちらかが適用される。
という運用方法も考えられる。
どちらを選択するかは、状況&趣味に応じて、というところかな?
TokyoMercurial #1 に参加した Kouichi Akatsuka 氏によるエントリでも、qguard/qselect に関する言及アリ。