hg convertを改変してLinuxのSVNリポジトリから CP932リポジトリの取得

406 views
Skip to first unread message

flied onion

unread,
May 29, 2012, 11:19:05 AM5/29/12
to mercur...@googlegroups.com
こんばんは、flied onionです。

hg convertを改造してSVNのリポジトリからWindowsでhg updateできるリポジトリを作成できるようにしています。
まだ実験段階で他のconvertとの共存もできていないような代物なんですが成果や備忘録も兼ねて、板汚しではありますがさらしてみたいと思います。

元としたのはmercurial-2.2-rcに付属のconvertです。
そのままのバージョンでhg convertした場合、utf8なmercurialリポジトリができあがるため、マルチバイトを含むファイル名やディレクトリ名が格納されている場合にWindows環境ではhg updateができません。
そのあたり、なんとかならないのか、望みは無いのかといろいろいじってみました。

現状できていることは
日本語ファイル名でもupdate可能
日本語を含むディレクトリでもupdate可能

できないこと・ためしていないことは
一般化・最適化
サブリポジトリを持つSVNリポジトリ
ダメ字
コミットログの変換(今のところ ????になるがエラーにはなっていない様子)
svn:// 以外でのアクセス
linux以外のsvnリポジトリ
SVN version < 1.5 のリポジトリ
などなど盛りだくさんです (^^;


丸ごとアップしてありますが、修正ファイルは
common.py
subversion.py
の2ファイルで全部で20行も変えてないと思います。
(cp932で検索すればすべての修正箇所周辺にヒットします。)


common.pyの修正は2箇所
converter_sourceクラスの
  self.encodingを cp932固定にした。
  recode()でencodingを cp932固定にした。

  self.encodingもrecode()でしか使われないので、recodeに渡されるsは常にcp932としているだけになります。
  本来ならencoding.encodingを使いたいところですが、書き換えられてしまっているので今のところこんなハードコードとなってます。
  recodeはコミットログやファイルパスをutf8に変換するために使われます。


subversion.pyはいくつか修正されていますが、その前にconvertの流れをざっくりと。
hg convertはSVNとやり取りをして各リビジョンの内容をファイル名をキーにして_changescacheに格納します。
(_getlog()から hg debugsvnlog コマンドが呼び出され、debugsvnlog() からget_log_child()、さらにsvn.ra.get_log()が呼ばれる ) 
その中で、ディレクトリ階層がある場合(?)は再帰的に取得します。
(_iterfile() から svn.client.ls が呼ばれる
対象のリビジョンすべての情報を集めたら、再びSVNと対話してファイルを一つずつ取得し、
(getfile() から svn.ra.get_fileが呼び出され、data = io.getvalue() で内容取得)
hgリポジトリに対してコミットをかけます
(putcommitの self.run0('commit' ・・・ )。

あといろいろな場面で、_checkpath()が呼ばれます。
(svn.ra.check_pathが呼ばれる。対象リビジョンに存在するかのチェックやファイル/ディレクトリ種別取得などに使われている)

細かく見るとあっちいったりこっちいったりするんですが、大きくは上記のようなながれになっています。


変換に関して基本的なスタンスは、
「とにかくファイル名をローカルエンコード(今はcp932)で保持しておき、hgのコミットがそのエンコードで行われるようにする。」
で、そのために
1.SVNからリビジョンの情報取ってきたら、キーとしているファイル名をすぐにローカルエンコードに変換する。
2.SVNに(ファイル取得や存在確認の)キーとして渡すときにUTF8に戻して渡す。
3.commit時、エンコードをcp932にする。
としています。

1.は具体的に
_getlog()よってhg debugsvnlog コマンドが実行され(出力先はstdout)。
さらにget_log_child()からsvn.ra.get_log()が呼ばれ、
最終的にreceiver()により、ファイル名と変更情報のdict()になってdumpが出力されます。

このreceiverを改変し、dump出力前にキー(ファイル名)をcp932に変換しています。
(その後はたしかこのdumpはlogstreamとなってリビジョン毎に処理される)

2にもありますが_iterfiles()も結果としてディレクトリ内のファイルを返却するのでこれがcp932で返るようにもしています。

2.は
getfile()でfileをutf8(SVNのエンコード)に変換。
_iterfiles() で、svn.client.lsのためにpathをutf8に変換。さらに結果はcp932で返す。
_checkpath()で、svn.ra.check_pathのためにpathをutf8に変換。
で対応しています。
2に関してはまだ他にもUTF8に戻さないといけない部分が残っているかもしれません。

3.は
putcommit()にて

   output = self.run0('commit',
               username=util.shortuser(commit.author),
               file=messagefile,
               encoding='cp932')
               #encoding='utf-8')

と、utf-8からcp932 に変更することで対応しています。

変更自体はこれだけです。

コミットログやタグ名が正常に変換できるようにするのが当面の目標です。
その他悩ましいのは、enoding.encodingが変更されているので、cp932をどうやって引き継ぐかです。
ほかのコンバータへの影響もあるので、あまり気軽に戻すわけにもいかないように思います。

ここまで改変してみた感じでは、encoding.encodingを変更している理由がまだ見当たらないのですが昔の名残かもしれません。(SVNは勝手にUTF8で返してくるし、Hgはrun0でencoding指定しているし。)


長々と失礼しました。
ご指摘、助言などありましたらよろしくお願いします。
もうすこしマシになったらまた報告させていただきたいと思います。
convert_svn2cp932.zip

flied onion

unread,
May 29, 2012, 6:12:27 PM5/29/12
to mercur...@googlegroups.com
完全なる対処療法ですが、コミットメッセージの変換も以下でうまくいけます。
なぜうまくいくか、というよりpickle.dumpに渡すmessageは何が期待されていて、コミットメッセージの変換をしているconvcmd.pyのrecodeはどういう状態を期待しているか
をきちんとみてないので、とりあえずうまくいったよーというお知らせです。
ひとまず、先の添付に以下の修正を加えれば、タグのない、サブリポジトリのない、ダメ字のないリポジトリはこれでいけるんじゃないかと思います。
相変わらず他のコンバーターの事は無視してますので、お気をつけください。


=subversion.py=

    def receiver(orig_paths, revnum, author, date, message, pool):
        print >> sys.stderr, "    = receiver  receive orig_paths ",orig_paths
        cp932pathsDict = dict()
        if orig_paths is not None:
            for k, v in orig_paths.iteritems():
                kdec = k.decode('utf-8').encode('cp932', 'replace')
                orig_paths[k] = changedpath(v)
                cp932pathsDict[kdec] = changedpath(v)
            print >> sys.stderr, "     =>  ",orig_paths
            print >> sys.stderr, "     =>  ",cp932pathsDict
            #files = map(lambda x: x.decode('utf-8').encode('cp932', 'replace'),files)
            
        if message is not None:
            message = message.decode('utf8') # for cp932 converting
        pickle.dump((cp932pathsDict, revnum, author, date, message),
                    fp, protocol)

Shun-ichi Goto

unread,
May 29, 2012, 10:50:41 PM5/29/12
to mercur...@googlegroups.com
2012年5月30日 0:19 flied onion <flied...@gmail.com>:
> こんばんは、flied onionです。
>
> hg convertを改造してSVNのリポジトリからWindowsでhg updateできるリポジトリを作成できるようにしています。
> まだ実験段階で他のconvertとの共存もできていないような代物なんですが成果や備忘録も兼ねて、板汚しではありますがさらしてみたいと思います。

ないすです。興味あります。
このネタは自分でもやりたかったネタなので。
実際には hgsubversion を fixutf8 不要にする対応をしたかったわけですが。


> 元としたのはmercurial-2.2-rcに付属のconvertです。
> そのままのバージョンでhg
> convertした場合、utf8なmercurialリポジトリができあがるため、マルチバイトを含むファイル名やディレクトリ名が格納されている場合にWindows環境ではhg
> updateができません。
> そのあたり、なんとかならないのか、望みは無いのかといろいろいじってみました。

これについては fixutf8 併用でなんとかならんですかね。
hgsubversion ではいまだに fixutf8 併用でしのいでます。
win32mbcsと fixutf8と共存できないこともあったりややこしい
ことになりがちですが。

fixutf8 はhg内部ではutf8で扱い、ファイルシステム入出力はunicodeで、コンソール出力は
ローカルエンコーディングで、という出入口ラップを

今回はhg APIにアクセスする際にcp932に変換するという方向なわけですが、
その意味で言うと、 hg APIをラップしてエンコード変換するextensionで実現する
という方向もありかな?と夢想してみる。

あと、日本語WIndowsであっても 非cp932な文字が入り込むことはありがちなので、
そこをどう解決するか、というのが悩ましいかも。


> 現状できていることは
> 日本語ファイル名でもupdate可能
> 日本語を含むディレクトリでもupdate可能
>
> できないこと・ためしていないことは
> 一般化・最適化
> サブリポジトリを持つSVNリポジトリ
> ダメ字
> コミットログの変換(今のところ ????になるがエラーにはなっていない様子)
> svn:// 以外でのアクセス
> linux以外のsvnリポジトリ
> SVN version < 1.5 のリポジトリ
> などなど盛りだくさんです (^^;

いいんじゃないですかね。


> 丸ごとアップしてありますが、修正ファイルは
> common.py
> subversion.py
> の2ファイルで全部で20行も変えてないと思います。
> (cp932で検索すればすべての修正箇所周辺にヒットします。)

zipで送るより BitBucket に置くのが吉でしょう。


> common.pyの修正は2箇所
> converter_sourceクラスの
> self.encodingを cp932固定にした。
> recode()でencodingを cp932固定にした。
>
> self.encodingもrecode()でしか使われないので、recodeに渡されるsは常にcp932としているだけになります。
> 本来ならencoding.encodingを使いたいところですが、書き換えられてしまっているので今のところこんなハードコードとなってます。
> recodeはコミットログやファイルパスをutf8に変換するために使われます。

ここは悩みどころですよね。 encoding.encoding を書き換えちゃう実現方法は
いずれ別の枠組みを作って何とかしないと、いまのままでは屋上屋みたいなことに
なりつつあるので。その枠組みをhgに発揮してもらいたいところですが、
そこらへんは藤原さんが奮闘中の件でもありますね。


> コミットログやタグ名が正常に変換できるようにするのが当面の目標です。
> その他悩ましいのは、enoding.encodingが変更されているので、cp932をどうやって引き継ぐかです。
> ほかのコンバータへの影響もあるので、あまり気軽に戻すわけにもいかないように思います。
>
> ここまで改変してみた感じでは、encoding.encodingを変更している理由がまだ見当たらないのですが昔の名残かもしれません。(SVNは勝手にUTF8で返してくるし、Hgはrun0でencoding指定しているし。)

encoding.encoding を utf-8 に変えるというのは、hg に対して、「このプラットフォームは utf-8
ですよ。なので受け渡すデータもメッセージ文字列も utf-8 ですよ」と強制することを意味しています。
なので、おおまかに言えば、hg の APIに対してSJISのバイト列を渡すのであれば
encoding.encoding は cp932 にするのが正しい方向でしょう。
convert は svn サイドのエンコード: utf-8 (固定) とリポジトリ内のエンコード: encoding.encoding
の相互変換を行うように徹底する必要がありそうですが。

>
> 長々と失礼しました。
> ご指摘、助言などありましたらよろしくお願いします。
> もうすこしマシになったらまた報告させていただきたいと思います。

是非 BitBucket におきましょう。
添付の修正は自分も見てみたいと思います。

--
Shun-ichi GOTO

Shun-ichi Goto

unread,
May 30, 2012, 6:35:21 AM5/30/12
to mercur...@googlegroups.com
2012年5月30日 11:50 Shun-ichi Goto <shunic...@gmail.com>:
> 2012年5月30日 0:19 flied onion <flied...@gmail.com>:
>> こんばんは、flied onionです。
>>
>> hg convertを改造してSVNのリポジトリからWindowsでhg updateできるリポジトリを作成できるようにしています。
>> まだ実験段階で他のconvertとの共存もできていないような代物なんですが成果や備忘録も兼ねて、板汚しではありますがさらしてみたいと思います。
>
> ないすです。興味あります。
> このネタは自分でもやりたかったネタなので。
> 実際には hgsubversion を fixutf8 不要にする対応をしたかったわけですが。

とかいっときながら、昔 convert の mbcs 対応にチャレンジしてたことが発覚しました。
あんまりテストしていなかったのですが、今回の flied onion さんの修正を
読んでいて、若干修正が必要なことに気が付き、それを直したら概ねうまく
動くようになりました。

mercurial crew の tip に対する差分を添付します。
# BitBucketにおけよ!というツッコミはスルー

方針としては flied onion さんの方針とは少々違うかな。
内部的には utf-8 のまま処理させ、commit()する直前にcp932に変換するというもの。
もちろんgetfile()を呼び出す際には utf-8 に戻して呼び出します。
言い換えると mercurial_sink の中でhgに渡すファイル名を cp932に変換し、逆に外部へ
出ていくファイル名をutf-8に変換するという方針。

この修正ではミソとなるのは hg.py の mercurial_sink.putcommit() 内の
2ヶ所だけです。
エンコーディングの指定については、 HGENCODING があればそれを使い、なければ
locale.getpreferredencoding を用います。
その設定は mercurial_sink.fs_encoding として保持し、利用しています。

これに win32mbcs を組み合わせると、ログも、ダメ文字を含むファイル名もうまく
いってるっぽいです。
テスト不十分ではありますし、このやり方で十分かどうかはまだ不明ではありますが、
ダメ文字を含むディレクトリ("表")やファイル("表.txt")のコミットや、
漢字名のtags/branches はうまくいってます。日本語ログも正しく記録されるし、
変換中もきちんと表示されます。
filemap はまだ試してないです。

もしよろしければ、こちらの版も試していじめてみてください。

--
Shun-ichi GOTO
convert-mbcs_support

flied onion

unread,
May 30, 2012, 9:11:23 AM5/30/12
to mercur...@googlegroups.com
2012年5月30日水曜日 19時35分21秒 UTC+9 Shun-ichi GOTO:
2012年5月30日 11:50 Shun-ichi Goto <shunic...@gmail.com>:
mercurial crew の tip に対する差分を添付します。
# BitBucketにおけよ!というツッコミはスルー

方針としては flied onion さんの方針とは少々違うかな。
内部的には utf-8 のまま処理させ、commit()する直前にcp932に変換するというもの。
もちろんgetfile()を呼び出す際には utf-8 に戻して呼び出します。
言い換えると mercurial_sink の中でhgに渡すファイル名を cp932に変換し、逆に外部へ
出ていくファイル名をutf-8に変換するという方針。


コメントありがとうございます。
私の場合は単純に「cp932で運用できてるんだからhg内はcp932で持ちまわっちゃえば考えること少なくていいじゃない。」
という考えであぁいう方針になっていましたが、UTF8で持ちまわれるならその方がよさそうですね。
まだソースは見ていませんが、修正箇所も少なそうですし、そのほうがわかりやすくていいですよね。参考にさせてもらいます。
 
これに win32mbcs を組み合わせると、ログも、ダメ文字を含むファイル名もうまく
いってるっぽいです。
テスト不十分ではありますし、このやり方で十分かどうかはまだ不明ではありますが、
ダメ文字を含むディレクトリ("表")やファイル("表.txt")のコミットや、
漢字名のtags/branches はうまくいってます。日本語ログも正しく記録されるし、
変換中もきちんと表示されます。
filemap はまだ試してないです。

もしよろしければ、こちらの版も試していじめてみてください。 

私のほうも日本語ログは正しく記録され、1600と800くらいのリビジョンのリポジトリの変換はうまくいきました。
ダメ字のほうは多分使ってないので(そもそも、Visual Studioが作ってしまう日本語ディレクトリぐらいしか日本語ファイル名は出てこない)試せていません。
明日時間があればGOTOさんのバージョンで変換ためしてみますね。

私はSVNも全然使いこなせてないのでいろんなことやってるリポジトリが試せないのが困ったものです。
# 覚えろよ禁止w

あとは個人的にファイル更新日時を複製できないか模索しないと・・・(今いるチームで重要事項なので)
comit前にsvn.client.lsあたりで更新日とって、TimestampMod拡張用のファイルを生成して追加してやればなんとかなるかなぁなどと妄想中です。
(TimestampMod拡張 では.hgtimestampというファイルがリビジョンにあればその内容でファイル日付上書きしてくれるので)

> 実際には hgsubversion を fixutf8 不要にする対応をしたかったわけですが。
私も発端はhgsubversionでしたが、いろいろ挫折してランクを落としてとっかかりにconvertをいじってみていたのでした(笑)

bitbucketはちょっといろいろ練習してから公開しようかと思います。

Shun-ichi Goto

unread,
May 30, 2012, 9:33:10 AM5/30/12
to mercur...@googlegroups.com
2012年5月30日 22:11 flied onion <flied...@gmail.com>:
> 私の場合は単純に「cp932で運用できてるんだからhg内はcp932で持ちまわっちゃえば考えること少なくていいじゃない。」
> という考えであぁいう方針になっていましたが、UTF8で持ちまわれるならその方がよさそうですね。
> まだソースは見ていませんが、修正箇所も少なそうですし、そのほうがわかりやすくていいですよね。参考にさせてもらいます。

ところでベースのmercurial はどの版を使っていますか?
crewのtipとは結構違うっぽいのと、zipを展開してそのまま使ってみても
変換に失敗するようなので。

失敗の様子はこんなかんじ。3種類ほど試してみましたし、TortoiseHg付属のhg.exeを使っても
同様の結果でした。

[c:\develop\hg\convert-cp932-test]hg convert \svnroot\hoge p
initializing destination p repository
scanning source...
sorting...
converting...
197 Created folder remotely
196 Copied remotely
195 Copied remotely
194 Renamed remotely
193 Copied remotely
transaction abort!
rollback completed
** Unknown exception encountered with possibly-broken third-party extension conv
ert
** which supports versions unknown of Mercurial.
** Please disable convert and try your action again.
** If that fixes the bug please report it to the extension author.
** Python 2.6.7 (r267:88850, Jun 27 2011, 13:56:33) [MSC v.1500 32 bit (Intel)]
** Mercurial Distributed SCM (version 2.2.1+141-e9ae770eff1c)
** Extensions loaded: mq, eol, share, transplant, convert, graphlog, purge, extd
iff, rebase
Traceback (most recent call last):
File "hg", line 38, in <module>
File "mercurial\dispatch.pyc", line 28, in run
File "mercurial\dispatch.pyc", line 65, in dispatch
File "mercurial\dispatch.pyc", line 88, in _runcatch
File "mercurial\dispatch.pyc", line 737, in _dispatch
File "mercurial\dispatch.pyc", line 511, in runcommand
File "mercurial\dispatch.pyc", line 827, in _runcommand
File "mercurial\dispatch.pyc", line 798, in checkargs
File "mercurial\dispatch.pyc", line 734, in <lambda>
File "mercurial\util.pyc", line 463, in check
File "/develop/hg\convert-cp932\__init__.py", line 269, in convert
return convcmd.convert(ui, src, dest, revmapfile, **opts)
File "/develop/hg\convert-cp932\convcmd.py", line 470, in convert
c.convert(sortmode)
File "/develop/hg\convert-cp932\convcmd.py", line 385, in convert
self.copy(c)
File "/develop/hg\convert-cp932\convcmd.py", line 353, in copy
source, self.map)
File "/develop/hg\convert-cp932\hg.py", line 171, in putcommit
self.repo.commitctx(ctx)
File "hgext\eol.pyc", line 347, in commitctx
File "mercurial\localrepo.pyc", line 1249, in commitctx
File "mercurial\context.pyc", line 1196, in __getitem__
File "mercurial\context.pyc", line 1238, in filectx
File "/develop/hg\convert-cp932\hg.py", line 137, in getfilectx
data, mode = source.getfile(f, v)
File "/develop/hg\convert-cp932\convcmd.py", line 88, in getfile
return self.source.getfile(file, rev)
File "/develop/hg\convert-cp932\subversion.py", line 850, in getfile
file = file.decode('cp932').encode('utf8')
UnicodeDecodeError: 'cp932' codec can't decode bytes in position 55-56: illegal
multibyte sequence


--
Shun-ichi GOTO

flied onion

unread,
May 30, 2012, 6:56:02 PM5/30/12
to mercur...@googlegroups.com

Shun-ichi Goto

unread,
May 30, 2012, 7:03:55 PM5/30/12
to mercur...@googlegroups.com
2012年5月30日 19:35 Shun-ichi Goto <shunic...@gmail.com>:
> この修正ではミソとなるのは hg.py の mercurial_sink.putcommit() 内の
> 2ヶ所だけです。
> エンコーディングの指定については、 HGENCODING があればそれを使い、なければ
> locale.getpreferredencoding を用います。
> その設定は mercurial_sink.fs_encoding として保持し、利用しています。

このパッチだとmercurial内のローカライズされたメッセージがダメになって
しまうことがわかりました。ふだん LC_MESSAGE=Cで使ってるもので、
気がつくのが遅れた。。。
つまり encoding.encoding がターミナルエンコーディングと違うと難有り。
hgsubversion もそうですが、encoding.encodingをいじる奴に共通の悩みですね。

やっぱり全体を encoding.encoding = 'cp932' で動かすほう方針の方がシアワセかも。
この場合はコミットメッセージでcp932に収まらないものが失われちゃうのだけど。

--
Shun-ichi GOTO

flied onion

unread,
May 30, 2012, 7:08:35 PM5/30/12
to mercur...@googlegroups.com
空投稿してしまいました(^_^;)
確認ありがとうございます。

使っているの環境は、tortoise2.4のhgをコマンドラインからです。
library.zipをlibrary.zipディレクトリとして解凍して、中のconvert(library.zip/mercurial/hgext/convertだったかな…
)を入れ替えています。

ログ見る限り、windows上のsvnserveのように見えるのでそこも違いといえば違いですね。(未だにlinuxのリポジトリにsvn://でしか試していません。)ないとは思いますがもしそれが原因だとするとなかなか衝撃的です((((;゚Д゚)))))))

あとはdebug用の出力消すとかにしくじった可能性大ですが(今はmq使ってますが当時は手でコンペアしながら消してたので)orz
--debugerのlistが上手く動作してくれなくてstderrに吐きまくってました。

いろいろと確認してみます。ありがとうございます。

Shun-ichi Goto

unread,
May 30, 2012, 7:11:19 PM5/30/12
to mercur...@googlegroups.com
2012年5月31日 8:08 flied onion <flied...@gmail.com>:

> 使っているの環境は、tortoise2.4のhgをコマンドラインからです。
> library.zipをlibrary.zipディレクトリとして解凍して、中のconvert(library.zip/mercurial/hgext/convertだったかな…
> )を入れ替えています。
>

自分は convert = /foo/bar/convert で指定して試してるので、そこらでなにか間違いが
起きてる可能性も。。。

> ログ見る限り、windows上のsvnserveのように見えるのでそこも違いといえば違いですね。(未だにlinuxのリポジトリにsvn://でしか試していません。)ないとは思いますがもしそれが原因だとするとなかなか衝撃的です((((;゜Д゜)))))))

いえ、file:// に相当する、ただの相対パス指定です

--
Shun-ichi GOTO

Shun-ichi Goto

unread,
May 31, 2012, 3:25:40 AM5/31/12
to mercur...@googlegroups.com
2012年5月31日 8:03 Shun-ichi Goto <shunic...@gmail.com>:
> 2012年5月30日 19:35 Shun-ichi Goto <shunic...@gmail.com>:
>> この修正ではミソとなるのは hg.py の mercurial_sink.putcommit() 内の
>> 2ヶ所だけです。
>> エンコーディングの指定については、 HGENCODING があればそれを使い、なければ
>> locale.getpreferredencoding を用います。
>> その設定は mercurial_sink.fs_encoding として保持し、利用しています。
>
> このパッチだとmercurial内のローカライズされたメッセージがダメになって
> しまうことがわかりました。ふだん LC_MESSAGE=Cで使ってるもので、
> 気がつくのが遅れた。。。
> つまり encoding.encoding がターミナルエンコーディングと違うと難有り。
> hgsubversion もそうですが、encoding.encodingをいじる奴に共通の悩みですね。

メッセージ出力の問題にも対応した版を作ってみました。
また、今回はデフォルトでは今までと同じ動きとし、
~/.hgrc などにて
[convert]
hg.fs_encoding = cp932
のように明示した時のみ、そのエンコーディングに変換する仕様にしました。

いまのところ svn -> mercurial でしか試していませんし、
mercurial への変換の部分だけにしか対処しておらず、
mercurial からの変換はまだ今までどおりです。

> やっぱり全体を encoding.encoding = 'cp932' で動かすほう方針の方がシアワセかも。
> この場合はコミットメッセージでcp932に収まらないものが失われちゃうのだけど。

これについては先のパッチと同じく encoding.encoding = 'utf-8'な状態で、utf-8のまま
持ち回る方向です。その代わり gettext() というか _() をラップして
utf-8 で返ってくる文字列を cp932 (orig_encoding)に直すようにすることで対応。

本来ならば、 terminal_encoding とかを導入して gettext()はこのエンコーディングを使う
ようにするといった方向に向かうべきなのでしょうけど、そこらへんは近頃話題(?)の
mercurial内部UTF-8化の話とあわせて考えていきたいものでもあるので。

変換の様子と結果ははこんな感じ。使用したsvnリポジトリも添付しておきますので、
色々試してくれると嬉しいです。
-------------------------------------------------------------------------------------
[c:\convert-mbcs-test]hg convert svnrepo
変換先として svnrepo-hg を想定
変換先リポジトリ svnrepo-hg の初期化中
変換元リポジトリの走査中...
並べ替え中...
変換中...
7 intial directory structure
6 ASCIIファイル名と漢字ファイル名の2つのファイルを追加
5 漢字ファイル名の内容を修正してみた。
4 ASCIIファイル名から漢字(ダメ文字)ファイル名にリネームしてみた。
3 ダメ文字なディレクトリを作って、ダメ文字なファイルをそこへ移動。
2 漢字ファイル名をASCIIにリネームしてみた
1 ascii名でブランチを作ってみる
0 漢字名でブランチを作ってみる
タグの更新中

[c:\convert-mbcs-test]cd svnrepo-hg

[c:\convert-mbcs-test\svnrepo-hg]hg up
3 files updated, 0 files merged, 0 files removed, 0 files unresolved

[c:\convert-mbcs-test\svnrepo-hg]hg man
.hgtags
kanji-filename.txt
表/表.txt

[c:\convert-mbcs-test\svnrepo-hg]hg log -v
チェンジセット: 8:65ab92f920c6
タグ: tip
親: 5:322bfa7cd3b3
ユーザ: convert-repo
日付: Wed May 30 22:10:44 2012 +0000
ファイル: .hgtags
説明:
update tags


チェンジセット: 7:5dad9873154d
ブランチ: ブランチ1
親: 5:322bfa7cd3b3
ユーザ: gotoh
日付: Wed May 30 10:01:13 2012 +0000
説明:
漢字名でブランチを作ってみる


チェンジセット: 6:be18d707e1cb
ブランチ: branch1
ユーザ: gotoh
日付: Wed May 30 10:00:41 2012 +0000
説明:
ascii名でブランチを作ってみる


チェンジセット: 5:322bfa7cd3b3
タグ: ascii-tag-1
ユーザ: gotoh
日付: Wed May 30 09:57:27 2012 +0000
ファイル: kanji-filename.txt 漢字ファイル名.txt
説明:
漢字ファイル名をASCIIにリネームしてみた


チェンジセット: 4:23ff3a2d1454
ユーザ: gotoh
日付: Wed May 30 09:51:31 2012 +0000
ファイル: 表.txt 表/表.txt
説明:
ダメ文字なディレクトリを作って、ダメ文字なファイルをそこへ移動。


チェンジセット: 3:1709fb3143f1
タグ: 日本語タグをつけてみた
ユーザ: gotoh
日付: Wed May 30 09:49:44 2012 +0000
ファイル: a.txt 表.txt
説明:
ASCIIファイル名から漢字(ダメ文字)ファイル名にリネームしてみた。


チェンジセット: 2:55e996c639f1
ユーザ: gotoh
日付: Wed May 30 09:48:36 2012 +0000
ファイル: 漢字ファイル名.txt
説明:
漢字ファイル名の内容を修正してみた。


チェンジセット: 1:97648ffae832
ユーザ: gotoh
日付: Wed May 30 09:48:05 2012 +0000
ファイル: a.txt 漢字ファイル名.txt
説明:
ASCIIファイル名と漢字ファイル名の2つのファイルを追加


チェンジセット: 0:7d8fbcc4184f
ユーザ: gotoh
日付: Wed May 30 09:45:12 2012 +0000
説明:
intial directory structure


[c:\convert-mbcs-test\svnrepo-hg]hg tags
tip 8:65ab92f920c6
ascii-tag-1 5:322bfa7cd3b3
日本語タグをつけてみた 3:1709fb3143f1

[c:\convert-mbcs-test\svnrepo-hg]hg branches
default 8:65ab92f920c6
ブランチ1 7:5dad9873154d
branch1 6:be18d707e1cb
-------------------------------------------------------------------------------------

ちなみに仕事で使ってるsvnリポジトリをごっそり変換してみました。
表とかのダメ文字も結構使ってますが、もほとんどエラーなく変換とupdateできたっぽいです。
細かくは確認していませんが。
出たエラーも python-svn バインディングのメモリリーク問題によるエラーなので
実質なにも問題が出なかったようです。

--
Shun-ichi GOTO
convert-mbcs-20120531.diff
svnrepo-r10.dump.gz

flied onion

unread,
May 31, 2012, 8:37:37 AM5/31/12
to mercur...@googlegroups.com
すみません、デバッグ出力を削除するときのミスでした。 orz

最初に添付したzipから、修正subversion.pyの修正が必要です。
zipからのdiffと、subversion.pyを投稿します。

subversion_py.patch
subversion.py

flied onion

unread,
Jun 1, 2012, 6:14:08 AM6/1/12
to mercur...@googlegroups.com
まだこちらは見てませんが、ひとつ前に方はソースみさせてもらいました。
いいですね、修正1ファイルですし。

コミットのタイミングでなにか細工するときの参考にもなります。

テスト用svndumpもありがたいです。
Reply all
Reply to author
Forward
0 new messages