Help us understand the problem. What is going on with this article?

GitでSimulinkモデルの競合を解決してマージする

はじめに

Gitはとても便利で強力なバージョン管理ツールです。
覚える用語(コマンド)や概念が多くて最初のハードル高さは否めませんが、いったんあの便利なシステムを使って複数人で同じドキュメント(ソースコード)の管理をすれば、もはやGitなしで開発してた頃が想像つかないほどには中毒性のあるシステムだと思っています。

話は変わりまして、Simulinkモデルはグラフィカルにモデリングできる1D-Simシミュレーションモデルとしての性質もありますが、産業用途では専ら“コントローラモデル”、つまりマイコンプログラムをグラフィカルに描くためのツールとして利用されています1。 そうつまり Simulinkモデル = プログラムソースコード なのです。

こうなってくると、これは是が非でも Simulinkモデルをバージョン管理したい。 そして、あの強力な差分比較とマージ機能を使いたいと思ってしまうのは人間の性というもの。

しかし、Gitはプログラムソースコードなどのテキストファイル(アスキーデータ)には、とても強力な差分比較とマージ機能が使えるのですが、Simulinkモデルファイル(.slx)のような、 “実態はテキストファイルなんだけど、 構造に意味がある系 のアスキーデータ”2 に対してGitでマージをかけると、構造が崩れて 最悪モデルファイルが壊れてしまいます。

この記事では、GitでSimulinkモデルのバージョン管理したいという人に向けて、「自動で競合の解決をしてマージする」手順について説明します。

リポジトリの事前設定

まずは事前準備として、リポジトリ直下の .gitattributes に以下の設定を施します。

*.mlx -crlf -diff -merge
*.mat -crlf -diff -merge
*.fig -crlf -diff -merge
*.mdl -crlf -diff -merge
*.slx -crlf -diff -merge
*.mlapp -crlf -diff -merge
*.p -crlf -diff -merge
*.mdlp -crlf -diff -merge
*.slxp -crlf -diff -merge
*.sldd -crlf -diff -merge
*.slxc -crlf -diff -merge
*.mlproj -crlf -diff -merge
*.mldatx -crlf -diff -merge
*.slreqx -crlf -diff -merge
*.sfx -crlf -diff -merge
*.sltx -crlf -diff -merge

これは、Gitに「Simulinkモデルファイルに対して diff (差分機能)とmerge(マージ機能)を使うんじゃねえ」と明示しています。
そうです、つまり Gitの差分比較とマージ機能は使いません。3

Simulinkモデルファイルをブランチ別に更新してみる

事前設定が終わったので、ここからは実際にSimulinkモデルファイルを競合させてマージしてみたいと思います。
まずは競合のシチュエーションを作るために、以下に示すようにそれぞれのブランチ(master, develop)でSimulinkモデル(ex_git_merge.slx)に変更を施しcommitします。

コミットグラフはこんな感じです。

コミットグラフ

それぞれのコミット(リビジョン)のモデルはこんな感じです。

ベース
masterブランチ変更
developブランチ変更

masterブランチではGainブロックの設定値を変更し、developブランチではブロックを組み替えてみました。
ブランチごとにそれぞれ違うトコロを変更したので、それぞれの変更をうまいこと自動で取り込んでマージしてくれることを期待していますが、果たしてできるのか・・・?

マージの実行 -> 競合の発生

それでは実際にマージさせてみます。
masterブランチにdevelopブランチを取り込みます。

$ git merge develop

すると、Gitから競合の発生を知らせるエラーが返ってきます。

mergeして競合エラー

Gitのマージ機能は .gitattrubutes で無効化しているので、両ブランチに変更があったらGitは 有無も言わず 「競合してるよ!」と知らせておしまいです。

MATLABの3wayマージツールを起動

ではこの状態で、MATLABでこのリポジトリを見てみましょう。
Gitがシステムにインストールされていれば、MATLABの「現在のフォルダー」ペインにもGitのステータスが表示されます。 Simulinkモデルファイルが競合マークになっていることが確認できます。
右クリックをして「ソース管理 > 競合を表示」の順にクリックします。すると、3wayマージツールが起動します。

競合を表示

3wayマージツールで競合を解決する

ここでタネあかしをすると、Simulinkモデルの競合解決はGitのマージ機能ではなく、Simulinkに搭載されている 3wayマージツール を用いて行います。(マージコミット命令自体はGitで操作する必要があります。)

3wayマージツール

3wayマージツールもGitのマージ機能に負けず劣らず優秀なツールでして、モデル内で変更箇所がかぶっていない場合(真に競合がない場合)、つまり今回のようなシチュエーションの場合は、両方の変更を取り込んで 自動でマージされた結果を表示します。 もちろんどちらの変更を採用するか手動で選択することも可能です。
競合箇所がすべて解決されていることを確認して、「確定して閉じる」を押下します。

確定して閉じる

コミットする(リベンジ)

Gitに戻り、ステータスを確認します。

$ git status

競合解決済み

競合が解決していることが確認できたので、再びコミットを行います。

$ git commit

無事に競合が解決され、以下のようにマージコミットが作られました。

merge完了

最後にSimulinkモデルを開いてみましょう。

merge後のモデル

ちゃんと masterブランチの変更(Gain変更)と、developブランチの変更(ブロックの組み替え)がうまく統合されていますね。 めでたしめでたし。

おわりに

今回はGitシステムの操作とSimulink上の操作を明確に区別するために、Git側の操作は別クライアント(Git Bash)で行いましたが、MATLABからもGitの操作は可能ですので4、よりシームレスにマージ作業ができることと思います。
また、今回はSimulinkの3wayマージツールの紹介だけでしたが、この他にもモデルの単純なリビジョン同士の比較なんかもできますので、もうこれで 「GitでSimulinkモデルのマージしたり比較したりするとぶっ壊れるんじゃ・・・((;゚Д゚))ガクガク」 と、漠然とした不安を抱える日々を送らなくてすみますね!(ワタシがずっとそう思ってた)


  1. 拙著「電子工作にモデルベース開発(Model Based Development: MBD)を適用してみた【コントローラモデル編】」を参照下さい(https://qiita.com/mana_544/items/3fe4d150441b12d89ebf

  2. Microsoft WordやExcelファイルなんかも、実態はテキスト(XML)だけど構造に意味がある系のファイルですね。 

  3. この設定も含めて、MATLAB(Simulink)でGitを使う際の細かい設定は公式HPに書いてありますのでご参照下さい。Git ソース管理の設定 - MATLAB & Simulink - MathWorks 日本 

  4. MATLABでGitの操作についてはコチラの方が詳しく解説されていますのでご参照下さい。「MATLABでGitを操作しよう (第1回 : プロジェクト作成とGUIの説明)」(https://qiita.com/stozaki/items/e4fa14c36f6c134e53e7

mana_544
趣味でイラストを描いてますが、画力とセンスがないのでプログラムを駆使してなんとかしてます。 本業は自動車の制御開発エンジニア。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away