06
2009

Redmine + CVS + PostgreSQL で invalid byte sequence

CATEGORY開発環境
またまた、Redmine + CVSで、文字コード絡みの話(汗
バージョンは引き続き0.8.4。CVSサーバーがCVSNTで、DBがPostgreSQL 8.4。
今回のは内容的にこういう構成じゃない人には関係ない(?)と思われる。

現象としては、CVSに日本語のファイル名が含まれる場合に、DB周りで下記のようなエラーが発生して、Redmineのリポジトリとして使用できないというもの。
ActiveRecord::StatementInvalid (PGError: ERROR:  invalid byte sequence for encoding "UTF8"
: 0x82
HINT: This error can also happen if the byte sequence does not match the encoding expecte
d by the server, which is controlled by "client_encoding".
: SELECT "changes".* FROM "changes" INNER JOIN changesets ON changes.changeset_id = chang
esets.id WHERE ("changes"."path" = E'/src/examp<82><8c>e/Test.java' AND "changes"."revision" = E'1.2') AND (("changesets".repository_i
d = 2)) LIMIT 1):
invalid byte sequence for encoding "UTF8"」はPostgreSQL側のエラーで、DBがUTF-8なのに、UTF-8じゃないコードが渡されたぞ(#゚Д゚)ゴルァ!!ってエラーメッセージで、Redmineに限らず設定があってないときなんかによく見かけるもの。

なので、サーバー側でRedmineがCVSクライアントを動かすときの文字コードか、CVSサーバー側の文字コードを何とかすればいいと思われるのだが・・・。
後者は他のクライアントのことを考えると難しく(?)、前者はShift_JISにするのもまた別に問題が置きそうでいやだったので、結局ソースをいじることにした。

改造箇所は、redmine/lib/redmine/scm/adapters/cvs_adapter.rb の revisions メソッド。
          path_with_project="#{url}#{with_leading_slash(path)}"
cmd = "#{CVS_BIN} -d #{root_url} rlog"
cmd << " -d\">#{time_to_cvstime(identifier_from)}\"" if identifier_from
cmd << " #{shell_quote path_with_project}"
cmd << " | /usr/local/bin/nkf -Sw"
shellout(cmd) do |io|
SELECTを投げる前のファイル名を取ってくるところが駄目なようだったので、そこだけ nkf でエンコードするようにした。
nkfがフルパスなのは、今回の環境では後から別途インストールしてて、かつリポジトリにはcronでアクセスさせているから。
その他、RedmineからはUTF-8に見えるようになるので、「設定」の「コミットメッセージのエンコーディング」は「UTF-8」に戻す
これでOK。CVSコマンド投げてるところ全部やらなきゃ駄目かと思っていたが、これだけで対処できたようだ。

# しかし、0.8.7は脆弱性の修正らしいので、いい加減会社のRedmineもアップデートせねばな。
スポンサーサイト

Tag: Redmine CVS

0 Comments

Leave a comment