Mercurialではじめる分散構成管理

第6回 勝手に「分散構成管理」 ~非Mercurial環境との共存

この記事を読むのに必要な時間:およそ 4 分

Mercurial Queueによる変更管理

前述した説明では,独自変更が固定的なチェンジセットとして記録される手法でしたが,実はMercurialにはMercurial Queue(MQ)と呼ばれる拡張機能があり,これまでに説明したのと同様の効果を,より便利に得ることができます。

MQは非常に多機能ですので,ここでは簡単な使用方法についての説明に留めます。詳細に関しては,オフィシャルサイトの解説ページや,Bryan O'Sullivan氏によるMQ解説ページを参照してください。特に,変更そのものの構成管理に関しては,"hg qinit -c"や"hg qcommit"のヘルプを参照してください。

重要:MQはDOS改行設定下では適切に動作しない模様ですので,改行設定には注意してください。

初期化

MQはMercurialのイクステンション(extension)として提供される機能ですので,有効にするには以下の記述を設定ファイルに追加する必要があります。

[extensions]
hgext.mq=

"hg showconfig"コマンドの出力に"extensions.hgext.mq="行が表示されないようでしたら,記述を追加した設定ファイルの場所等を確認してください。

上記設定が完了したなら,MQ機能を使用するリポジトリで"hg qinit"を実行します。

次に,未コミットの変更(ファイル追加・削除を含む)が無いことを確認した上で,"hg qnew"を実行します。この時,変更内容を端的に表すような名前を指定してください。ここでは仮に"use_network"とします。

以上で独自改変の準備は整いました。手順に間違いが無ければ,以下のような出力が得られるはずです。

コマンド5

% hg qinit
% hg qnew use_network
% hg qseries
use_network
% hg qapplied
use_network
% 

変更の実施

この時点で"hg parents"等を実行してみると,作成した覚えの無い以下のようなチェンジセットが目に付くことでしょう。

コマンド6

% hg parents
changeset:   2:3547823edb73
tag:         qtip
tag:         use_network
tag:         tip
tag:         qbase
parent:      0:87d13763f6e4
user:        FUJIWARA Katsunori 
date:        Tue Jul 06 14:10:26 2008 +0900
summary:     [mq]: use_network

% 

このチェンジセットは,直前の"hg qnew"によって作成されたものです。"hg log -p"等で変更内容を出力させてみると,何も変更していないことがわかります。

それでは,早速「独自変更」を実施しましょう。但し,MQを使用する場合,"hg commit"ではなく"hg qrefresh"を実施します。

"hg qrefresh"を実施したなら,再度"hg parents"出力を確認してみましょう。

コマンド7

% hg parents
changeset:   2:083ec762dc76
tag:         qtip
tag:         use_network
tag:         tip
tag:         qbase
parent:      0:87d13763f6e4
user:        FUJIWARA Katsunori 
date:        Tue Jul 06 14:18:11 2008 +0900
summary:     [mq]: use_network

% 

概ね同じなのですが,微妙に違いますね?

更に"hg log -p"等で変更内容を出力させてみると,"hg qrefresh"前の変更内容に相当する出力がある点で,明らかに先程表示させたチェンジセットとは異なります。

実は,"hg qnew"で作成されたチェンジセットは,"hg qrefresh"を実行する度に再構築されるのです。

適用対象の更新

独自変更の対象となるFLOSSの最新版の取り込みの際には,それに先立って"hg qpop"を実行します("hg qrefresh"で全ての変更が取り込まれていることを確認してください⁠⁠。

"hg qpop"実行により,"hg tip"出力には見覚えのあるチェンジセットが表示されることでしょう。つまりMercurialの構成管理上は,先程の独自変更は無かったことになっているのです。

それでは折角の独自変更作業が無駄になってしまったのか?

いいえ,独自変更作業の成果はきちんと残っています。

まずは,先の実行では同じだった"hg qseries"と"hg qapplied"の出力が,"hg qpop"実行後は違うものとなっていることを確認してください。

コマンド8

% hg qseries
use_network
% hg qapplied
% 

これは以下の意味を持っています。

"use_network"という変更作業の内容は,MQとして記録している(=qseries出力)が,作業領域への適用(=qapplied出力)はされていない

記録が残っているということで,安心してFLOSSの最新版取り込みを行ってください。

変更の再適用

FLOSSの最新版の取り込みが完了したなら,独自変更を再適用しましょう。

"hg qpush"を実行してみてください。

コマンド9

% hg qpush
applying use_network
Now at: use_network
% 

もし,FLOSSの最新版が,あなたの独自拡張と衝突するような変更を含んでいた場合,以下のようなメッセージが表示されます。

コマンド10

% hg qpush
Hunk #1 FAILED at 0
1 out of 1 hunk FAILED -- saving rejects to file hello.txt.rej
patch failed, unable to continue (try -v)
patch failed, rejects left in working dir
Errors during apply, please fix and refresh use_network
% 

この場合は,最新版に適用可能なように変更を実施して,改めて"hg qrefresh"すれば良いのです。

以後は,"hg qpop"⇒最新版取り込み⇒"hg qpush"(⇒更新+"hg qrefresh")の繰り返しになります。

おわりに

6回にわたって,Mercurialを使った「分散リポジトリ」の活用方法について説明させて頂いた訳ですが,いかがでしたでしょか?

CVSやSubversionといった中央集約形式の構成管理ツールの利用経験があると,最初は何となく面倒な印象のある分散リポジトリですが,ちょっとした発想の切り替えをするだけで,非常に自由度の高い運用を可能にしてくれるのが分散リポジトリの利点です。

Mercurialには,連載において説明したもの以外にも,日常的な作業をより便利にするための様々な機能が提供されていますし,実装言語がPythonであることから,⁠必要であれば作る(or変更する⁠⁠」という方法も選択可能です。

より詳細を知りたい方は,是非ともオフィシャルWikiページや,Bryan O'Sullivan氏による解説ページを参照してみてください。

著者プロフィール

藤原克則(ふじわらかつのり)

Mercurial三昧の日々が嵩じて, いつの間にやら『入門Mercurial Linux/Windows対応』を上梓。凝り性なのが災いして,年がら年中アップアップな一介の実装屋。最近は仕事の縁が元で,OpenSolarisに入れ込む毎日。