「入門Mercurial Linux/Windows対応」発売中(詳細は「執筆情報」参照)


文字コード

注意: 他環境での Mercurial インストール経験があっても、 別環境で Mercurial をインストールする際には、 以下の節を一通り確認することを強くお勧めします。

Mercurial での日本語利用における文字コードの扱いに関してまとめてみました。

備考: ここでは、文字集合体系とその符号化に関する包括的な領域を、 慣習的な点から「文字コード」と表現しています。

文字コード設定の確認

Mercurial 固有の明示的な設定(後述)を行わない場合、 Python 標準の locale モジュールが提供する getpreferredencoding() メソッドの戻り値で文字コードが決定されます (文字コード確定手順の詳細は、 Mercurial ソースの mercurial/encoding.py 冒頭の try 節を参照ください)。

例えば私が主に使用している環境(cygwin)では

% python
> import locale
> locale.getpreferredencoding()
'US-ASCII'
文字コード設定の確認

となるため、日本語は使えません。

この段階で希望する文字コードが選択されているなら、 Mercurial は問題なく日本語を通してくれます。

文字列変換で不正なバイト列が検出された場合の Mercurial の基底動作が「中断」となっているため、 例えば日本語を含むファイル commit.ja.log の内容をメッセージとして commit しようとすると、 以下のようなエラーとなります (ページ表示の都合上、 Python が不正とみなす文字を "xxxx" で置換しています)。

% hg commit -l commit.ja.log
abort: decoding near 'xxxx': 'ascii' codec can't decode byte 
       0xe6 in position 0: ordinal not in range(128)!
transaction abort!
rollback completed
文字コード不正で commit 中断

明示的な文字コードの設定

Mercurial は、 "HGENCODING" 環境変数により、 ロケール系環境変数 (e.g.: LC_CTYPELC_ALLLANG) とは独立して文字コード指定を行うことができます。

特に Cygwin 環境では、ロケール系環境変数(と Python の locale モジュール) は機能しないと考えたほうが良いですので、 HGENCODING を使用しましょう。

% echo ${HGENCODING}
cp932
% hg commit -l commit.ja.log
% hg log
changeset:   0:65b7f27315f7
tag:         tip
user:        FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date:        Sun Sep 23 18:29:46 2007 +0900
summary:     日本語のログメッセージ
日本語のログメッセージ

設定する文字コード名の可否に関しては:

% python
>>> unicode('abcdefg', '文字コード名')"
文字コード名の確認

といったスクリプトを Python に実行させてみて、 正常に終了するか否かで判定することができます。

備考: Windows 環境の Python では "mbcs" 指定によりロケールに応じた文字コードが選択される、 という仕様になっていますが、 Cygwin 上の Python では (少なくとも Cygwin 1.5.24 と Python 2.4 の組み合わせでは) 機能しませんので注意が必要です。

また、 不正な文字コードが検出された場合の Mercurial の挙動を制御するための HGENCODINGMODE という環境変数も存在しますが、 危険を承知でデフォルトの「中断」("strict" を指定) 以外に設定する必要性は低いと思われます。

各環境変数の仕様に関する詳細は、 "hg help environment" が出力するヘルプを参照してください。

日本語 Windows 環境でのファイル名問題

注意: この問題は、 Windows 環境でバイナリ版 Mercurial を使用する場合に固有の問題です。

setup.exe 経由やソースからのビルドでインストールした Mercurial を Cygwin 上で使う場合、 パス区切りにはスラッシュを使用しますので、 この問題は発生しません。

但し、 Cygwinwrap を併用している場合は、 必ず 0.6 版以降にアップデートしてください。

日本語 Windows 環境では、 ファイル名自身の文字コードには cp932(厳密には違いますが、 「Shift_JIS」と言ったほうが通りが良いかもしれません) が使用されています。

cp932 符号化方式では、 幾つかの2バイト文字が2バイト目に 0x5c、 すなわち「バックスラッシュ」と同じコード値を持つ (例えばカタカナの「ソ」を表すバイト列は 0x83 0x5c)ため、 OS のパス区切りとの区別が付かないことから、 これらの文字を含むファイル・ディレクトリ名を適切に扱うことができません。

この問題は HGENCODING 環境変数を設定しても解決しません (解決しても良さそうなものなのですが…)ので:

余計な手間をかけたくない場合:

日本語ファイル名の使用を諦めるか、 0x5c を含まない文字を使用するしかありません。

もっとも「0x5c を含まない文字」 か否かをいちいち判定していたのでは面倒なことこの上ありませんから、 実質「日本語ファイル名の使用を諦める」一択しかないでしょう。

多少は手間をかけても良い場合:

Mercurial の 1.0 版、 ないし TortoiseHG の 0.3 版以降であれば、 win32mbcs エクステンションを利用することで、 この問題を解決可能です。

但し、 このエクステンションはデフォルトでは無効化されていますので、 適切な場所の Mercurial.ini ないし hgrc で 有効化する必要があります。

といった対応が必要です。

注意: HGENCODING 環境変数や win32mbcs イクステンションを使用することで、 hg コマンドレベルではファイル名やログメッセージの日本語を正しく扱えますが、 TortoiseHG レベルでは (少なくとも 2008/03/01 時点で最新の 0.3 版では) ファイル・ディレクトリ名やログメッセージに日本語は使えない、 と考えておいたほうが良いでしょう。

例えば、 事前にコマンドラインで日本語のコミットメッセージでコミットしておいたものを TortoiseHG で表示させる場合、 ある程度は表示できるようですが、 特定の条件(数?文字?)下で "View ChangeLog" が機能しなくなります。

また、 事前にコマンドラインで日本語ファイル名のファイルをコミットした場合、 確実に "View ChangeLog" が機能しなくなります。

Emacs の hg モード利用における留意点

Emacs の hg モード経由で Mercurial を利用する場合、 ファイル名やログメッセージに日本語を使用するに当たって、 確認が必要な点が2つあります。

まず第1は、 hg モード経由での Mercurial 利用はシェルを経由しないため、 当該 Emacs プロセスそのものに対して HGENCODING 環境変数が設定されていることを確認してください。 Meadow のような非 Cygwin プロセスの場合は、 「システムプロパティ」の「環境変数設定」による設定が必要です。

第2に、 以下の lisp 変数にも HGENCODING (および稼働環境の OS) と辻褄の合う適切な値が設定されていることが必要です。

以上の2点が適切であることが確認できれば:

hg モードにおける日本語利用(画像)

日本語ファイル名のファイルを add することも、 日本語のログメッセージを入力することも (勿論、日本語のログメッセージの閲覧も)可能です。

備考: 厳密に言えば、 開いてあるファイルに対する "hg-add" によって、 構成管理への追加をする必要が無ければ、 おそらく file-name-coding-system の設定は不要と思われます。

しかし、hg モードを使用しているのに、 ファイルの追加だけコマンドラインで実施、 という状況は普通に考えて有り得ないですから、 この lisp 変数も設定しておくことをお薦めします。

分散リポジトリ間での日本語ファイル名問題

HGENCODING 環境変数を使用することで、 Mercurial は日本語ファイル名を使用することができるようになるのですが:

  1. Windows 環境下で HGENCODING=cp932 を設定
  2. Windows 環境下で日本語ファイル名のファイルを構成管理対象に追加
  3. Linux 環境下で HGENCODING=euc-jp を設定
  4. Windows 環境下のリポジトリから Linux 環境下のリポジトリへ push
  5. Linux 環境下で "hg update" を実施

といった手順を踏んだ場合、 Linux 環境下では euc-jp なファイル名のファイルが取り出せることを期待するでしょうが、 そのようには振舞ってくれません。 cp932 そのままのファイル名が作成されます。

少なくとも Mercurial 1.0 版時点では:

ファイル名を UTF-8 等の中間コードで保持しておいて、 HGENCODING に応じてリポジトリごとに異なる文字コードでファイル生成

といった仕様にはなっていませんので、 複数プラットフォーム間の連携には注意が必要です。

但し、 「作業は専ら Windows 環境、 Linux 環境は成果集積のためのリポジトリサーバ専用」 といった使い方であれば、 日本語ファイル名の使用は特に問題はありません。

備考: ひょっとすると:

  • Windows 上は CP932
  • Linux 上は euc-jp
  • MacOS 上は utf-8
  • 所によっては iso-2022-jp

などという文字コードマニアな事情は、 日本固有の話なのかもしれません。


次節「マージプログラム」へ