Simulinkモデルのバージョン管理(7)

Simulinkモデルのバージョン管理(6)からの続きです。

前回の差分表示に引き続き、medini uniteによるマージ作業をご紹介します。それなりに使えそうだな、と思っていただけるのではないでしょうか。

Kiln(Mercurial)設定

Kilnからmedini uniteをマージツールとして起動できるようにするため、Mercurial.iniに次の項目を追加します。

[merge-tools]
mediniunite_merge.executable = C:\Program Files (x86)\ikv++ technologies ag\mediniUnite\mediniUnite.exe
mediniunite_merge.args = -a $base -t $local -s $other -r $output
[merge-patterns]
**.mdl = mediniunite_merge

これで準備は完了です。

Diffの時には mediniunite という項目を定義しましたが、ここでは mediniunite_merge という項目を定義しました。これがポイントです。こうしないと、diffの場合とマージの場合でmedini uniteへの引数が違うために正常動作しなくなります。

マージの実行

(中央サーバー、および開発PCを使用する)

マージを開始する

開発者Aと開発者Bが、それぞれ独立してモデルを修正する。バラバラに編集しているうちは幸せなのですが、いつかはモデルを出荷しないといけません。出荷前のマージ作業・・・モデルのマージを手でするのは悪夢のような作業です。

子供のころ、新聞の日曜版に載っていた「7つの間違いを探せ」ゲームをよくやっていました。2つの絵がならんでいて、微妙なところに違いがあるやつです。ボウシの色が違ったり、窓から誰かがのぞいていたり・・・子供だからという事もありますが、7つ見つけるのに結構苦労したものです。Simulinkモデルの場合、微妙に違うだけでなくそれが階層構造になっているわけで、これをマージしようだなんて気が遠くなる作業です。ここはぜひ、ツールの力を借りましょう。

そんな時は、バージョン管理システムでもって、3点マージを行います。

開発者Bの立場に立ってやってみましょう。まず、開発者Aがさきに作業を終え、Kilnに変更をPushしました。次にわれわれ(開発者B)が変更をKilnにPushしようとすると、失敗します。開発者Aの変更内容と衝突があるためです。

そんな時はまず、TortoiseHG > Synchronizeにて、Pullを実施します。

Pullを実施する

すると、枝分かれしたバージョンの情報が開発者Bのマシンに取り込まれます。これをTortoiseHGのHG Repository Browserで見てみると、こんな感じになります。

枝分かれしたバージョン

この枝分かれしたバージョンを、再び1つにマージしましょう。ここで3点マージです。HG Repository Browser上で、tip を選択し、Merge with… を選択します。

tip で Merge with

すると、次のように表示されます。

3点比較画面

テキストの場合と違い、画面には2つしかモデルが表示されません。開発者Aのモデル、われわれ(開発者B)のモデルの2つのみが表示されます。ベースとなったモデルは、プロパティのみ表示されるのですがモデルとして表示されることはありません。

マージは、どちらかを選択する作業になる

テキストファイルのマージの場合、「現在のファイル」「過去のファイル」を見比べた上で、マージされたファイルを手書きします。

一方、medini uniteの場合はそうではありません。

現在のモデルでは、Constantブロックのパラメータは1ですよ

過去のモデルでは、Constantブロックのパラメータは2ですよ

で、どうするの?1にするの?2にするの?選んで!さぁ!

という感じになります。

マージ済みにする=現在のモデルを採用  右をすべて取り込む=過去のモデルを採用

ツリーの右クリックメニューにて、現在のファイルの値を採用するか、過去のファイルの値を採用するかを選択できます。

過去のモデルの値を採用し、「済み」になった

このように、現在のモデル、過去のモデル、どちらを選ぶのか?をひたすら選択していく事により、マージを実施します。

プロパティ変更だけでなく、

  • 現在のモデルには無く、過去のモデルにはあるブロック
  • 現在のモデルにはあるが、過去のモデルには無いブロック

についても、

  • ブロックを増やすか?
  • ブロックを削るか?
  • 現状維持するか?

から選択する形で、マージを行います。

おおよそのところは、これでOKだと思います。

ひと工夫必要な点

だいたいは、過去のモデル、現在のモデル、どちらかを選ぶだけでOKだと思います。しかし、単純に選ぶだけでは済まないケースも出てきます。

その場合、直接パラメータを編集したいところですが、medini uniteは、そういったモードを直接サポートしていません。これでは不便です・・・

そんなときは、ちょっとした裏技を使いましょう。ただし、この裏技を使う前に、選択によるマージはすべて済ませておいてください。

さて、まずは左側に表示されているモデルのブロックを、なんでもいいのでちょっとズラそうとします。

適当なブロックを、ずらそうとする

すると、次のようなダイアログが出るので、「ロックを解除」をクリックします。

ロックを解除

いったんこうしてしまうと、プロパティを直接編集できるようになります。

そして、いろいろ編集して、これでOKと思ったら、結果を保存する必要があります。

保存する際は、medini uniteのメニューではなく、埋め込まれたSimulinkのメニューを使います。

ファイル>保存 で、保存を行う

これで、直接編集する事もできます。ただし、ここで編集した値はmedini uniteからは認識されませんので、注意が必要です。

もう1つ注意点があります。この裏技は、ちょこちょこっと直接編集したい場合には有効ですが、大規模な修正には向きません。

大規模に修正したい場合には、

  • いったんmedini uniteによるマージを終える
  • medini uniteで、現在のモデルと、過去のモデルの差分表示をする
  • Simulinkを起動して、現在のモデルを編集する

といった作業を行ったほうがよいでしょう。

まとめ

medini uniteは使いやすいと思います

medini uniteは、差分表示はとても秀逸です。通常のテキスト用Diffとほぼ同じ使用感です。一方、マージ作業は、「現在のバージョン」「過去のバージョン」のいずれかを採用するか?の2択になります。この方式は、「どの部分がマージ済みか?」を確認しやすいのが利点ですが、2択では済まない場合には対応できません。そのため、差分表示させつつ、直接Simulinkを起動してマージ作業を行った方が良い場合もあるかと思います。

今回の一連の記事によって、Mercurialなどの分散バージョン管理システム+medini uniteによって、テキストの場合と遜色のない環境が構築できる事が分かりました。

「つなぎ」に苦労する場合も

環境が出来あがってしまえば、とても快適なのですが、それまでが大変です。今回一番苦労したのは、バージョン管理システムとmedini uniteとのつなぎの部分です。上の方にある「Kiln設定」ですが、この方法を見つけるのに2~3時間かかりました。Diffとマージで設定が干渉してしまう、という所が一番の悩みどころで、上記の回避方法を見つけるまでに右往左往してしまいました。

なお、medini uniteのドキュメントには、Subversion, StarTeam, ClearCase, AccuRevとのつなぎの設定例が載っています。これらを既にお使いの方は苦労する事はないと思います。今回Mercurial対応もやりましたので、MercurialもOKです。それ以外のバージョン管理システムをお使いの方は、ひょっとすると苦労する事になるかも分かりません。今後、もっともっと設定例が増えていけば、より使いやすくなるのではないかと思います。

とりあえず終了です

以上でバージョン管理システムのシリーズは終了です。とはいえ、medini uniteについてはザックリとしたご紹介しかできませんでした。まだまだ細かい点がいっぱいあるのですが、残念ながら評価期間が過ぎてしまいました。ほかの企画もいっぱいあってスケジュールが押してますので、とりあえず今回はこれで終了とします。機会があれば、もっとつっこんだレビューをしてみようかと思います。