
MQL5 Algo Forgeへの移行(第2回):複数のリポジトリの操作
はじめに
最初の記事では、MetaEditorに内蔵されているSVNベースのMQL5 Storageから、より柔軟で現代的なソリューションであるGitバージョン管理システムに基づくMQL5 Algo Forgeへの移行を開始しました。この移行の主な理由は、複数のプロジェクトや単一プロジェクト内の異なる機能を同時に開発する際に、リポジトリのブランチ機能を十分に活用する必要があったということです。
移行作業は、新しいリポジトリをMQL5 Algo Forge上に作成することから始まりました。さらに、Visual Studio Codeを用いたローカル開発環境を準備し、必要なMQL5およびGitの拡張機能、ならびに補助ツールを導入しました。その後、標準ファイルや一時ファイルをバージョン管理から除外するために.gitignoreファイルをリポジトリに追加しました。既存のすべてのプロジェクトは専用のarchiveブランチにアップロードし、過去に作成されたコードを保存するアーカイブ領域としました。一方で、mainブランチは空のままとし、新規プロジェクト用ブランチを整理するための基盤としました。こうして、異なるプロジェクトのコードをリポジトリの複数のブランチに分散できる仕組みを整えたのです。
しかし、最初の記事を公開してから現在に至るまでの間に、MetaEditorにおける新しいリポジトリシステムのサポートが大幅に拡張されました。これらの変更により、以前に示したアプローチを再考する必要が生じました。そこで本稿では、当初の計画から若干逸れて、他の公開プロジェクトをコンポーネントとして組み込んだ公開プロジェクトを作成する方法を検討します。今回の対象となるのは、多通貨対応のエキスパートアドバイザー(EA)の開発です。このプロジェクトについては、すでにコードの開発や修正方法を解説する複数の記事が公開されています。ここからは、Gitバージョン管理の機能を最大限に活用し、開発プロセスを整理し、効率化していきます。
道筋の整理
信じがたいことですが、前回の記事の時点ではMetaEditorにはまだファイルのコンテキストメニューからMQL5 Algo Forgeリポジトリを操作するためのGitコマンドが実装されていませんでした。そのため、Visual Studio Codeといった外部ツールを使ってワークフローを構成するには多大な労力が必要でした。MetaEditorが最終的にどのようにリポジトリをサポートするのかが分からなかったため、当時利用可能だったツールに頼るしかありませんでした。
その後、MetaEditorの新しいリリースでMQL5 Algo Forgeのサポートが組み込まれました。さらにMetaQuotesは「MQL5 Algo Forgeのご紹介」という記事を公開し、基本事項や主要機能を解説しました。しかし、私たちが最も重要だと考えるのは、MetaEditorにShared Projects(共有プロジェクト)の仕組みが導入されたことです。
なぜこれが重要なのでしょうか。以前は、MQL5フォルダがMQL5 Algo ForgeのGitサーバー上にホストされたリポジトリとして機能することが分かっていました。そしてそのリポジトリには固定名としてmql5が割り当てられると見られていました。つまり、各ユーザーはAlgo Forge上にmql5という名前のリポジトリを持ち、そのリポジトリを新しいターミナルをインストールした後に、コミュニティにログインしてリポジトリに接続することでMQL5フォルダにクローンされる仕組みでした。同時に、MQL5 Algo Forgeでは常に追加のリポジトリを作成できました。正確に言えば「追加」ではなく、mql5リポジトリとは無関係な別個のリポジトリです。当然ながら、MetaEditorがこれらのリポジトリをどのように扱うのかという疑問が生じました。
ターミナルごとのインストールで利用するリポジトリを選択できるのでしょうか。それともできないのでしょうか。サポートされるのはmql5リポジトリだけで、異なるプロジェクトを区別するにはブランチに分けるしかないのでしょうか。私たちは当初、この最悪のシナリオに備えていました。1つのリポジトリで複数のプロジェクトをブランチで管理するのは特に便利とは言えないからです。幸いなことに、この懸念は杞憂に終わりました。
MetaQuotesは、2つの課題を同時に解決するより洗練されたソリューションを導入しました。1つ目に、メインリポジトリであるmql5が存在します。これは既にMQL5 Storageに慣れているユーザーにとって便利であり、基盤となるバージョン管理システムが何であるかを気にせず、そのままバージョン管理を利用し続けることができます。
一方で、その他すべてのユーザーリポジトリはShared Projects内のフォルダとして利用可能になりました。これにより、既存のMQL5、MQL5/Experts、MQL5/Includeなどと並んで、ユーザーの追加リポジトリのコードを保存するための新しい標準ルートフォルダが用意されたことになります。
例を挙げてみましょう。MQL5 Algo Forgeに2つの別々のリポジトリがあるとします。どちらもデフォルトのmql5リポジトリではありません。1つ目のリポジトリ(Adwizard)はライブラリコードのみを含みます。つまり*.mqhファイルのみを含み、*.mq5インクルードファイルは含まれません。2つ目のリポジトリ(Simple Candles)は*.mq5ファイルを含み、その中で1つ目のリポジトリのインクルードファイルを利用しています。便宜上、1つ目をライブラリリポジトリ、2つ目をプロジェクトリポジトリと呼ぶことにします。
私たちの目的は、プロジェクトリポジトリで開発を進めながら、ライブラリリポジトリのコードをどのように利用するかを確認することです。このシナリオは、たとえばmql5.comのコードベースで共有されたコードが、作者自身によってMQL5 Algo Forgeの公開リポジトリとしてもミラーされる場合など、今後ますます一般的になる可能性があります。そのようなケースでは、1つ以上のリポジトリを外部ライブラリとしてプロジェクトにリンクする方法を、本稿で取り上げる手法で処理できるでしょう。
導入手順
まずは、2つのリポジトリを両方とも所有している開発者の立場から状況を見てみましょう。つまり、Pull Requestの仕組みによるレビューや承認を待たずに、どちらのリポジトリのコードも自由に変更できるということです。最初におこなうのは、空のターミナルフォルダを作成し、既にインストールされているMetaTrader 5のコピーから2つのファイルをコピーすることです。
ターミナルの作業フォルダをファイルシステムの奥深くまで探す手間を避けるため、ターミナルをポータブルモードで実行することを推奨します。Windowsでは、ターミナルの実行ファイルへのショートカットを作成し、そのショートカットのプロパティにある「リンク先」フィールドに「/portable」フラグを追加する方法があります。
ターミナルを起動したら、念のため新しいデモ口座を開設し、最新版に更新した上で、コミュニティにサインインします。そしてF4キーを押してMetaEditorを起動します。MQL5 Algo Forgeが自動的に接続されていなければ、ここで接続します。
ナビゲータに、[Shared Projects]フォルダが表示され、以前Webインターフェースから作成したリポジトリが一覧として現れます。しかし、このフォルダをエクスプローラで開くと、中身はまだ空のままです。つまり、実際のリポジトリファイルはまだローカルにダウンロードされていないということです。
それらをクローンするには、必要な各リポジトリを右クリックし、コンテキストメニューから[Git Clone]を選択します。ログには、AdwizardとSimple Candlesの両方が正常にクローンされたことが確認できます。エクスプローラには、クローンされたリポジトリのフォルダが表示されるようになります。
この時点で、両方のプロジェクトのコードがローカルに揃い、利用できる状態になりました。
最初の問題
SimpleCandles.mq5を開いてコンパイルしてみましょう。
予想通り、コンパイルエラーが発生します。原因を理解してみましょう。これらは致命的なエラーではありません。というのも、このコードは以前は正常にコンパイルできていたからです。変わったのは、ライブラリとプロジェクトファイルの相対的な配置だけです。最初の2つの根本的なエラーは、コンパイラがライブラリファイルを期待する場所で見つけられないことが原因です。多通貨アドバイザーの開発(第28回)(ロシア語のみ)では、ライブラリ部分とプロジェクト部分を保存するために次のフォルダ構造を使うことに合意していました。
つまり、ライブラリリポジトリをプロジェクトリポジトリのサブフォルダ内に配置していました。これにより、ライブラリファイルの位置が予測可能になっていたのです。しかし今回はこれを変更します。プロジェクト内に必須のIncludeサブフォルダを置くのではなく、MQL5/Shared Projectsフォルダを利用することにします。このフォルダは、今後のMetaEditorのバージョンでも安定して存在し、同じ役割を果たし続けることが理想です。
この問題を修正するために、2つのファイルの#includeディレクティブを更新します。ただし、コードを修正する前に、まずは良い開発プラクティスに従い、この限定的なタスク用の独立したブランチを作成します。修正がテストされれば、そのブランチを開発用のmainブランチにマージできます。
では、プロジェクトリポジトリに既に存在するブランチを確認してみましょう。これにはいくつかの方法があります。
- MetaEditorでリポジトリフォルダのコンテキストメニューを使う方法
- リポジトリのWebインターフェースでbranchesページを開く方法
- Visual Studio Codeのような外部Gitツールを使う方法:リポジトリ名の横には現在のブランチ名である前であるmainが表示されています。クリックすると利用可能なブランチの一覧や、新しいブランチを作成するメニュー項目が現れます。
現在、このリポジトリには4つのブランチがあります。
- main:プライマリブランチ。リポジトリ作成時に自動的に生成されます。最も単純な場合、追加のブランチを作らずにすべての作業をここで行えます。より複雑な場合には、このブランチは安定版のコードを保持するために使われ、まだ完成していない変更やテスト前の変更は他のブランチで進めます。
- develop:開発ブランチ。単純なケースでは、ここを唯一のブランチとして使い、新機能を順番に追加していけます。この方法は、新しい機能を順番に実装していく場合に十分です。つまり、前の機能の追加が完了してプロジェクトが安定した状態になるまで、新しい機能の開発を開始しません。新機能の作業を始める前に、developブランチでおこなった編集をmainブランチにマージします。複数の機能を同時に開発する場合は、1つのdevelopブランチで作業するのは不便になるため、追加のフィーチャーブランチ(feature branch)を作成することができます。
- article-17608-close-managerとarticle-17607:フィーチャーブランチ。前者は損益閾値に基づくポジションクローズロジック用のフィーチャーブランチで、すでにdevelopにマージされ、さらにdevelopはmainにマージされています。後者は自動最適化の強化用のフィーチャーブランチで、まだ作業中であり、developやmainにはマージされていません。
重要なのは、Gitが特定のブランチ運用ルールを強制していないという点です。つまり、私たちは自分たちに最も便利な方法を選べます。開発者の中には有用なワークフローを考案し、他者と共有してきた人々がおり、それが「ベストプラクティス」として知られるようになっています。プロジェクトに合ったブランチモデルを自由に採用したり調整したりできます。こちらの記事で紹介されているのも、そのような提案されているブランチ運用の1つです。
ではリポジトリに話を戻しましょう。
疑問を持たれるかもしれない細かい点として、origin/(MetaEditorではrefs/remotes/origin/と表示される)というプレフィックスがあります。これは単に、そのブランチがローカルではなくリモートリポジトリに存在していることを示すものです。通常は、ローカルブランチとリモートブランチを同期させます。MetaEditorでは、Commitコマンドを実行すると自動的にPushも実行され、そのコミットがリモートリポジトリに送信されます。
一方、MetaEditorの外でコミットをおこなう場合、Pushせずにローカルにだけコミットを残すことも可能です。その場合、同じ名前のローカルブランチとリモートブランチの内容が異なることがあります。origin/というプレフィックスは両者を区別する助けになります。このプレフィックス付きならリモートリポジトリのブランチを指し、そうでなければローカルのブランチを指すというわけです。
新しいブランチの作成
今回の修正は、ライブラリ部分の配置変更後もコードが正しくコンパイルされるようにするだけなので、developブランチから新しいブランチを作成します。まずorigin/developに切り替えると、ローカルのdevelopブランチとしてリストに表示されます。
次に新しいブランチを作成(Newコマンドを実行)し、任意の名前を入力します。私たちの命名規則では、記事関連のブランチはarticle-に記事固有のIDを続けて作成します。必要に応じて、記事のトピックを示す短いサフィックスを付けることもできます。今回の新しいブランチはarticle-17698-forge2と名付けました。
ブランチの作成は他の方法でも可能です。Webインターフェース、Visual Studio Codeのインターフェース、あるいはコマンドラインからも作成できます。リポジトリのルートフォルダでコマンドラインを使う場合、次のように実行します。
git checkout -b article-17698-forge2 develop
これはGitに対し、developブランチを基にarticle-17698-forge2という新しいブランチを作成し(-b)、そのブランチに切り替える(checkout)よう指示しています。
Webインターフェース以外でブランチを作成した場合、最初にリモートリポジトリにPushするまではローカルマシン上にしか存在しません。逆に、Webインターフェースでリモートリポジトリに作成したブランチは、最初にリモートからPullするまではローカルに現れません。
変更をPushするには次をおこないます。
または
コマンドラインでPush操作をおこない、新しいブランチを作成する場合は、リモートリポジトリにブランチを作成することを明示的に示す追加パラメータが必要です。
git push --set-upstream origin article-17698-forge2
これで、ブランチはローカルコピーとMQL5 Algo Forge上のリモートリポジトリの両方に存在することになります。この時点で、他のブランチの機能を壊す心配なく、自由に編集を開始できます。
変更の追加
必要な修正は非常に簡単です。SimpleCandles.mq5ファイルでは、Adwizardライブラリのファイルをインクルードしている行を更新します。現在、Simple CandlesリポジトリとAdwizardリポジトリのルートフォルダは、どちらもShared Projectsフォルダ内で同じ階層にあるため、Expert.mqhへのパスはまず1つ上の階層(../)に移動し、その後ライブラリリポジトリのサブフォルダに降りる必要があります。
#include "Include/Adwizard/Experts/Expert.mqh" #include "../Adwizard/Experts/Expert.mqh"
Strategies/SimpleCandlesStrategy.mqhファイルでも同様の修正が必要です。
#include "../Include/Adwizard/Virtual/VirtualStrategy.mqh" #include "../../Adwizard/Virtual/VirtualStrategy.mqh"
これらの変更をおこなうと、SimpleCandles.mq5は再び正常にコンパイルされます。これで、変更をリポジトリにコミットできます。
前述の通り、MetaEditorのインターフェースを使ってコミットすると、自動的にPushコマンドも実行され、変更内容がMQL5 Algo Forge上のリモートリポジトリに送信されます。
コンソールコマンドを使用する場合も同様の操作が可能です。既存ファイルの編集に加えて新しいファイルを作成した場合は、まずリポジトリのインデックスに追加する必要があります。
git add .
このコマンドは、リポジトリフォルダ内のすべての新規ファイルを追加します。特定のファイルだけを追加したい場合は、「.」の部分をファイル名に置き換えます。その後、コメントを指定してコミットし、リモートリポジトリにPushします。
git commit -m "Fix relative paths to include files from Adwizard"
git push
これで、article-17698-forge2ブランチでの変更は完了です。このブランチはdevelopブランチにマージした後、閉じることができます。
2番目の問題
ここで少し不快な驚きに直面します。現在のMetaEditorには、ブランチをマージするためのツールがありません。つまり、新しいブランチは作成できるものの、あるブランチの変更を別のブランチに移すことができないのです。幸いにも、近い将来にはこの機能が追加されることが期待されます。現時点では、再び代替ツールに頼ってリポジトリ操作をおこなう必要があります。
ブランチをマージする方法は主に2つあります。1つ目は、Visual Studio Codeのマージインターフェースや標準的なコンソールコマンドを使う方法です。今回のケースでは、以下のコマンドを使用できます。
git checkout develop
git pull
git merge --no-ff article-17698-forge2
まず、developブランチに切り替えます。次に、念のため更新をおこない(ローカルマシンにまだ反映されていない変更がある場合に備えて)、最後のコマンドで実際にマージをおこないます。マージ競合が発生する可能性はありますが、今回のシナリオでは単一の開発者が作業しているケースを想定しているため、ほとんど起こらないでしょう。複数拠点で作業する場合でも、リポジトリを常に最新の状態に更新していれば、マージ競合は発生しにくくなります。
ただし、この方法の細かいニュアンスについてはここでは深入りしません。代わりに、2つ目の方法に注目しましょう。こちらはMQL5 Algo ForgeのWebインターフェースを使用する方法です。
マージのためのPull Requestの使用
GitHubやGitLab、Bitbucketなどの他のGitベースプラットフォームと同様に、MQL5 Algo ForgeにもPull Request (PR)という仕組みがあります。
Pull Requestは、開発者がブランチでおこなった変更をリポジトリにマージするよう提案できる機能です。言い換えれば、PRを作成することでリポジトリの所有者や他の貢献者に次のように通知できます。「自分のブランチで作業が完了しました。これらの変更をmainブランチ(main/master/develop)にマージしてください。」
PRはGitそのものの機能ではなく、Gitの上に構築された追加レイヤーです。これにより、変更をmainブランチにマージする前にコードレビューや議論を整理することができます。
Pull Requestは、現代の開発でいくつかの重要なタスクも同時に解決します。自動テストによる継続的インテグレーション(CI)、他の開発者による品質管理、PRコメントによる変更内容の文書化などです。しかし、これらのプラクティスは主にチーム開発向けであり、MQL5プロジェクトは通常個人開発が中心です。とはいえ、今後共同開発プロジェクトが増えれば、このワークフローは重要性を増すでしょう。
とはいえ、すでにPRを使った新機能や修正追加の典型的なワークフローの開始手順を再現しています。
-
最新の変更をPullする:作業を開始する前に、ローカルのdevelopブランチを更新。
-
タスク用の新しいブランチを作成する:更新済みのdevelopブランチから、明確な名前のブランチarticle-17698-forge2を作成。
-
新しいブランチで変更をおこなう:複数のファイルを修正・テストし、その変更をコミット。
-
Pull Requestを作成する:MQL5 Algo ForgeのWebインターフェースで、[Pull Requests]タブに移動し、大きな赤い[New pull request]ボタンをクリックします。
これでブランチ選択ページが開きます。この時点ではまだPRは作成されていません。まずどのブランチにマージするかどうかを指定する必要があります。ブランチを選択したら、変更一覧を確認し、再度[New pull request]をクリックします。
新しいページが開き、変更内容の詳細な説明を入力できます。ここでレビュー担当者を割り当てることも可能です。デフォルトでは、自分自身に対してPRが送信されます。今回のケースではこれで十分です。
-
レビューと議論:今回は単独作業なのでこのステップは省略できます。通常は以下が含まれます。
-
レビュー担当者がコードを確認しコメントを残す(一般的なコメントや特定行に関連するコメント)
-
PR作成者がコメントに応答し、同じブランチで修正をおこなう
-
新たにPushされた変更は既存のPRに自動的に反映される
-
-
マージ:レビュー担当者が承認し(存在する場合)、CIが通過したら、PRをマージできます。通常、マージにはいくつかのオプションがあります。
-
Merge commit: 別個のマージコミットを作成し、ブランチの履歴を保持する
-
Squash and merge: PR内の全コミットを1つにまとめてターゲットブランチに追加する(たとえば「タイプミスの修正」のような小さなコミットで履歴が散らからないようにするのに便利)
-
Rebase and merge: PRコミットをターゲットブランチ(今回の場合はdevelop)の先頭に再適用し、クリーンで線形の履歴を作成する
最後に、PR操作の最終ページで[Delete branch ...]オプションをチェックし、開発用の一時ブランチを閉じます。コミット履歴にはブランチが存在していたことが残ります。しかし、目的はすでに達成されているため、このブランチを開いたままにしておく意味はありません。今後、別のタスクを解決する際は新しいブランチを作成します。このようにして、リポジトリのブランチリストは常に現在進行中の並行作業の状況を明確に示します。
その他の設定はそのままにして、[Create merge commit]をクリックします。
これで完了です。article-17698-forge2ブランチはdevelopにマージされ、削除されました。
一般に、自分のリポジトリであってもPull Requestを使うことは推奨される良い習慣です。コミット前にすべての変更を視覚的に確認できるため、コミット時に見落とした不要なコメント、余計なファイル、最適でない編集などを発見できることがあります。要するに、自己規律の一形態です。また、このワークフローを採用することで、ブランチ運用やコードレビューなどの良い習慣が身につきます。将来開発チームに参加する際も、すでにこのプロセスに慣れていることになります。
つまり、自分自身にPRを送信することは可能なだけでなく、あらゆる本格的なプロジェクトで推奨されます。コード品質を向上させ、規律を守ることができます。もちろん、1~2回の小さな修正の場合は、直接git mergeでマージしても構いません。しかし、大きな変更の場合はPRを使う方が優れた方法です。
結論
全体として、個人用リポジトリを用いたワークフローは、現在しっかりと確立されています。リポジトリのクローン作成から、変更を加えてもコードが機能し続け、さらに開発を進められるプロセスの洗練までを取り上げました。これにより、プロジェクトリポジトリは他のリポジトリ(場合によっては複数)をライブラリとして有効に利用できるようになりました。
しかし、今回扱ったのは1つのシナリオのみです。それは、同じユーザーがプロジェクトとライブラリの両方のリポジトリを所有している場合です。もう1つのシナリオは、プロジェクト所有者が他人のリポジトリをライブラリとして利用したい場合です。この場合は、状況が簡単ではありません。しかし、コミュニティコードの積極的な再利用や共同開発を前提としたワークフローの構築は、新しいリポジトリシステム導入の目的の1つでもありました。それでも、基盤はすでに整えられています。
今回はここまでにします。次回でお会いしましょう。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/17698
警告: これらの資料についてのすべての権利はMetaQuotes Ltd.が保有しています。これらの資料の全部または一部の複製や再プリントは禁じられています。
この記事はサイトのユーザーによって執筆されたものであり、著者の個人的な見解を反映しています。MetaQuotes Ltdは、提示された情報の正確性や、記載されているソリューション、戦略、または推奨事項の使用によって生じたいかなる結果についても責任を負いません。





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索
キリル文字はほとんどなかった。私はずっと前に、コメントでもキリル文字を使うのをやめた。
どうやら私の思い違いだったようだ。これを.mq5ファイルにUTF-8エンコーディングで追加した:
// キリル文字
保存するとエンコーディングが「UTF-16 LE BOM」に変わった。
MetaEditorのせいらしい。キリル文字を追加し、Notepad++を使ってファイルを保存したところ、エンコーディングはUTF-8のままでした。
また、ローカルリポジトリからブランチを削除できるようにする必要性を主張するのは奇妙だと思います。GitのブランチモデルはGitのキラー機能であり、Gitはブランチの頻繁な作成、削除、マージを推奨しています。
ですから、メインブランチにマージした後にブランチを削除することにも賛成です。ただ、削除した後に、新しいブランチではなく同じ名前の新しいフィッシュ用のブランチを作るというのは初めて聞きました。
diffを見る目的は何ですか?
そうですね、とても必要なものです。私も積極的に使っていますが、VS Codeでしか使っていません。そしてそこでは、不思議なことに、"悪い "エンコーディングのファイルに目を通しても、クラッシュすることはない。
そんなことに遭遇したのは初めてだ。それもかなり予想外のことだ。もしかしたら、正常なファイルが壊れたのは、同じファイルを扱うために異なるMEビルドを同時に使ったせいかもしれない?わからないけど...。
コミット履歴を見たところ、2ヶ月前に追加されたファイルは確かにすでにUTF-8エンコーディングで、3ヶ月前に追加されたファイルはまだUTF-16 LEでした。どうやらその頃にどこかでUTF-8エンコーディングへの切り替えがあったようだ。
私が間違っていたようだ。これを.mq5ファイルにUTF-8エンコーディングで追加しただけだ:
保存後、ファイルのエンコーディングが「UTF-16 LE BOM」に変更されました。
MetaEditorのせいのようです。キリル文字を追加し、Notepad++を使ってファイルを保存したところ、エンコーディングはUTF-8のままでした。
ロシア文字を追加してファイルを保存すると、エンコーディングがUTF-8からUTF-16 LEに変わることを確認しました。ロシア文字をすべて削除して保存しても、UTF-16 LE のままです。
MetaEditorのせいらしい。
UTF-8とキリル文字とGitを互換にできる証明はこちら:
https://forge.mql5.io/junk/utf8-cyrillic-test/commit/e87d37b02e88d44305dea0f7f6630c6173471aea
必要なのは、MetaEditorにファイルのエンコーディングを変更しないように頼むことだけです。
私が間違っていたようだ。これを.mq5ファイルにUTF-8エンコーディングで追加しただけだ:
保存後、ファイルのエンコーディングが「UTF-16 LE BOM」に変更されました。
MetaEditorのせいのようです。キリル文字を追加し、Notepad++を使ってファイルを保存したところ、エンコーディングはUTF-8のままでした。
おそらく、UTF-8はBOMなしだったのだろう。少なくとも以前は、BOMがある場合のみUTF-8のままだった。他のエディターはもっと賢くて、BOMなしで動作します。