selflearn @ ウィキ

MacでのUTF-8-MAC問題を解決する

最終更新:

selflearn

- view
メンバー限定 登録/ログイン
-

MacでのUTF-8-MAC問題を解決する方法

このページでは、MacでSubversionを使用するときにぶち当たる問題「UTF-8-MAC問題」を解決する方法について記します。

NEWS!! 2009/04/27
hayatoさんのコメントによると、この問題に対処するパッチが、ついにMacPortsでのvariantとして取り込まれたとのことです!

『$ sudo port -v install subversion +unicode_path』

と、“+unicode_path”を追加指定すればOKです。そうすれば、このページで紹介している方法をわざわざ実施するまでもありません。
苦節ウン年、ついに報われました・・・。

最終更新日:2009年06月05日 (金) 10時58分51秒;

どんな問題を解決しようとしているの?

Subversionは内部の処理をUTF-8で行い、クライアント環境での文字コードに合わせて適切なコードに変換してから処理を行っています。
けれどもOS Xのファイルシステムでは、実際には「UTF-8-mac」というUTF-8そのものとは少し異なるコードを用いているにも関わらず、Subversionでは「UTF-8」と判断してしまう有名な問題があります。「UTF-8-MAC問題」、と言われている問題です。

本問題により、日本語のファイル名、とくに濁点「゛」や半濁点「゜」を用いたファイルのステータスを見ようとすると、
% svn st
 ? パッチファイル.txt
 ! パッチファイル.txt
% 
というように、ファイルの存在を正しく取り扱えません。ソースコードの管理に使用するだけならアルファベットのファイルしか多分扱わないので問題はないでしょうが、
  • プログラマ以外の人とSubversionを使用する
  • 設計書などのドキュメントをバージョン管理する
  • 他のOS(Windowsなど)を使うユーザとSubversionを共用する
などという場合に非常に厄介な問題になるわけで。

この問題を解決しよう、というのが以下に記述する方法です。

本問題を解決するに当たって、多くのサイトの情報を参考にさせてもらいました。それらはできる限り参考サイトに載せておきましたが、載せられなかった方については、この場を借りてお詫び&お礼を申し上げておきます。

想定環境

ソースコードに直接手を入れているので、ページ初回作成時の環境を明示しておきます。

プログラム バージョン
OS Mac OS X 10.5 Leopard(10.5.4/10.5.5) IntelMac上で使用
MacPorts 1.600
Subversion 1.5.1 (r32289)

同じ方針で修正できるバージョン(確認済み)


バージョン 補足
1.5.1 このページで記載している情報です
1.5.2
1.5.4
1.5.5 hayatoさん、ありがとうございます
1.5.6 DEXさん、ありがとうございます
1.6.0 path.cに手が入ったようで、関数svn_path_cstring_to_utf8()が1070行に移動しています。
それ以外は同じです
1.6.1 同上。
Subversionのソースコードで手を入れるところは少なく、関数名も変わったりしないような部分なので旧バージョンや今後のバージョンでも問題は出にくいでしょうが、ターゲットが異なる方は行番号や関数名などには気を付けてください。

手順

まず、大まかな手順を伝えておきます。
  1. MacPortsでSubversionのソースコードを入手(まだインストールはしない)
  2. ソースコードの変更
  3. MacPortsでインストールの続行

1.MacPortsでSubversionのソースコードを入手

MacPortsのサイトから、MacPortsをインストールしたら、Subversionのソースコードを入手します。そして、
% sudo port patch subversion               
--->  Fetching subversion
--->  Verifying checksum(s) for subversion
--->  Extracting subversion
--->  Applying patches to subversion
%  
と入力します。これによってSubversionで./configureが行われる前の状態まで処理が進み、以下の場所にソースコード一式が保存されます。

/opt/local/var/macports/sources/rsync.macports.org/release/ports/devel/subversion/work/subversion-1.5.1/subversion

この中のファイルを修正します。

2.ソースコードの変更

上に記した場所に移動して、libsvn_subr/path.cをエディタで開きます*1
そして、以下のdiff結果に示すような変更を施します。
% diff -u path.c{_orig,}
--- path.c_orig	2008-09-12 15:30:18.000000000 +0900
+++ path.c	2008-09-12 15:30:13.000000000 +0900
@@ -31,6 +31,9 @@
 #include "svn_io.h"                     /* for svn_io_stat() */
 #include "svn_ctype.h"
 
+#if defined(DARWIN)
+#include <CoreFoundation/CoreFoundation.h>
+#endif /* DARWIN */
 
 /* The canonical empty path.  Can this be changed?  Well, change the empty
    test below and the path library will work, not so sure about the fs/wc
@@ -1349,6 +1352,36 @@
                          apr_pool_t *pool)
 {
   svn_boolean_t path_is_utf8;
+#if defined(DARWIN)
+  svn_error_t *err;
+  /*
+    Compose any decomposed unicode characters precomposed one.
+    This will solve the problem that the 'svn status' command sometime
+    cannot recognize as same file when files suppose to be comtain
+    comopsed characters, like umlaut in some European language or 
+    'Daku-ten' in Japanese, and the files are added on windows machines
+    then you use svn on Mac OS X checking out the files.
+  */
+  CFMutableStringRef cfmsr = CFStringCreateMutable(NULL, 0);
+  CFStringAppendCString(cfmsr, path_apr, kCFStringEncodingUTF8);
+  CFStringNormalize(cfmsr, kCFStringNormalizationFormC);
+  CFIndex path_buff_size = 1 + CFStringGetMaximumSizeForEncoding(
+    CFStringGetLength(cfmsr), kCFStringEncodingUTF8);
+  char *path = apr_palloc(pool, path_buff_size);
+  CFStringGetCString(cfmsr, path, path_buff_size, kCFStringEncodingUTF8);
+
+  SVN_ERR(get_path_encoding(&path_is_utf8, pool));
+
+  if (path_is_utf8)
+    {
+      *path_utf8 = apr_pstrdup(pool, path);
+      err = SVN_NO_ERROR;
+    }
+  else
+    err = svn_utf_cstring_to_utf8(path_utf8, path, pool);
+  CFRelease(cfmsr);
+  return err;
+#else /* DARWIN */
   SVN_ERR(get_path_encoding(&path_is_utf8, pool));
   if (path_is_utf8)
     {
@@ -1357,6 +1390,7 @@
     }
   else
     return svn_utf_cstring_to_utf8(path_utf8, path_apr, pool);
+#endif /* DARWIN */
 }
 
このときの注意点として、関数svn_path_cstring_to_utf8()に手を入れるようにしてください。
最初ボクは間違えてすぐ近くのsvn_path_cstring_from_utf8()に手を入れてしまい、コンパイルできたもののsvnが起動すら出来なくなってしまいました*2。注意!!

なお他の依存関係のあるportは先にインストールしてしまっても構わないので、次のようにしておいた方が楽かもしれません。
% sudo port install subversion               
% sudo port uninstall subversion               
% sudo port patch subversion               
%  

3.MacPortsでインストールの続行

修正したファイルによってSubversionをビルドします。
% sudo port install subversion
--->  Building subversion with target all
--->  Staging subversion into destroot
--->  Installing subversion 1.5.1_0
--->  Activating subversion 1.5.1_0
--->  Cleaning subversion
%  
最後に「which svn」として、/opt/local/binの下にパスが通っていればOK。作業完了です。

補足

  • port installした後、修正したソースコード一式はportによって削除されてしまいます。とっておきたい場合はSubversionのフォルダごと別の場所にコピーしておいてください。
  • SubversionのBTSでは「この問題はけっこう複雑なので、(今回紹介した)パッチをコミットすることはできない」と書いてあります。今のところ問題は出ていませんが、念のためご注意ください(ご利用は自己責任で、ということですスミマセン)。

参考サイト

調べたサイト

  • Subversionでの該当課題(#2464)。本記事ではここに投稿されていたパッチファイルを使用しています。パッチを投稿してくれたHiroshi Saito氏に多謝!
  • Subversion Precomposed UTF-8 patch。上のパッチを投稿した人のサイト。ただ、このブログで紹介されているパッチのリンク先が2008/9/12時点では「Service Temporarily Unavailable」でした。
  • 2007-12-30 OS Xで日本語が通るSubversion環境の作り方。UTF-8-MAC問題の原因が分かったサイト。ただしここで紹介されていたget_ntou_xlate_handle_node()とget_uton_xlate_handle_node()を変更する方法では問題は解決しませんでした。

その他、MacでSubversionを使用するときの有益なサイト


コメント

お気軽にコメントくださいな。
  • 2008/9/25時点の1.5.2でも同様の方法でパッチが当てられることを確認しました。 -- katokichi (2008-09-25 16:11:58)
  • 2008/11/05時点の1.5.4でも大丈夫でした。 -- katokichi (2008-11-05 15:13:23)
  • 2008-12-25時点の1.5.5も全く同じでした。参考にさせていただきました。ありがとうございました。 -- hayato (2008-12-25 19:46:08)
  • hayatoさん、ご連絡ありがとうございます。このパッチ,trunkに取り込まれると良いんですけどね。日本語だけでなく,その他のマルチバイト文字でも影響がある問題なので。 -- katokichi (2008-12-26 11:42:26)
  • portでインストールした 1.5.6でも同じでした。ありがとうございました。 -- DEX (2009-03-17 13:09:40)
  • ご確認ありがとうございます。この辺はもう手が入ることは無いんですかね。毎回の修正は面倒なのに、こまったものです。 -- katokichi (2009-03-17 16:05:49)
  • 1.6でも同じ方法で動かせることを確認。ただしpath.cに手が入ったようで、目的の関数の行が変化していることに注意。 -- katokichi (2009-04-02 10:03:19)
  • 1.6.1でも確認しました。注意点は1.6(.0)のときと同じです -- katokichi (2009-04-13 16:49:48)
  • この問題に対応するvariantの+unicode_pathが用意されていたみたいです。http://d.hatena.ne.jp/fujisan3776/20081231/1230700127 $ sudo port -v install subversion +unicode_path -- hayato (2009-04-26 23:57:58)
  • おお!ありがとうございます!ついに、ついに報われる日が来たという感じですね。このページもとうとう必要のないものになりました。うれしいです・・・。コメントありがとうございました! -- katokichi (2009-04-27 08:56:30)
記事メニュー
目安箱バナー
注釈

*1 ファイルオーナーがrootなので、sudo viなどで開くことに注意。

*2 こうなってしまったら「sudo uninstall subversion」で最初からやり直してください。