diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb
--- a/app/helpers/repositories_helper.rb
+++ b/app/helpers/repositories_helper.rb
@@ -176,7 +176,9 @@
   end
   
   def mercurial_field_tags(form, repository)
-      content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
+    content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?))) +
+    content_tag('p', form.select(:path_encoding, [nil] + Setting::ENCODINGS,
+                                 :label => 'Path encoding'))
   end
 
   def git_field_tags(form, repository)
diff --git a/app/models/repository.rb b/app/models/repository.rb
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -42,7 +42,8 @@
   end
 
   def scm
-    @scm ||= self.scm_adapter.new url, root_url, login, password
+    @scm ||= self.scm_adapter.new url, root_url,
+               login, password, path_encoding, nil
     update_attribute(:root_url, @scm.root_url) if root_url.blank?
     @scm
   end
@@ -248,7 +249,7 @@
   end
 
   private
-  
+
   def before_save
     # Strips url and root_url
     url.strip!
diff --git a/lib/redmine/scm/adapters/abstract_adapter.rb b/lib/redmine/scm/adapters/abstract_adapter.rb
--- a/lib/redmine/scm/adapters/abstract_adapter.rb
+++ b/lib/redmine/scm/adapters/abstract_adapter.rb
@@ -63,8 +63,9 @@
           end
         end
 
-        def initialize(url, root_url=nil, login=nil, password=nil)
+        def initialize(url, root_url=nil, login=nil, password=nil,
+                       path_encoding=nil, log_encoding=nil)
           @url = url
           @login = login if login && !login.empty?
           @password = (password || "") if @login
           @root_url = root_url.blank? ? retrieve_root_url : root_url
@@ -67,5 +68,6 @@
           @url = url
           @login = login if login && !login.empty?
           @password = (password || "") if @login
           @root_url = root_url.blank? ? retrieve_root_url : root_url
+          @path_encoding = path_encoding || 'UTF-8'
         end
@@ -71,5 +73,5 @@
         end
-        
+
         def adapter_name
           'Abstract'
         end
@@ -221,6 +223,16 @@
         def strip_credential(cmd)
           self.class.strip_credential(cmd)
         end
+
+        def scm_iconv(to, from, str)
+          return unless str
+          return str if to == from
+          begin
+            Iconv.conv(to, from, str)
+          rescue Iconv::Failure => err
+            raise CommandFailed, "failed to convert path from #{from} to #{to}. #{err}"
+          end
+        end
       end
       
       class Entries < Array
diff --git a/lib/redmine/scm/adapters/cvs_adapter.rb b/lib/redmine/scm/adapters/cvs_adapter.rb
--- a/lib/redmine/scm/adapters/cvs_adapter.rb
+++ b/lib/redmine/scm/adapters/cvs_adapter.rb
@@ -59,7 +59,8 @@
         #  root_url -> the good old, sometimes damned, CVSROOT
         #  login -> unnecessary
         #  password -> unnecessary too
-        def initialize(url, root_url=nil, login=nil, password=nil)
+        def initialize(url, root_url=nil, login=nil, password=nil,
+                       path_encoding=nil, log_encoding=nil)
           @url = url
           @login = login if login && !login.empty?
           @password = (password || "") if @login
diff --git a/lib/redmine/scm/adapters/darcs_adapter.rb b/lib/redmine/scm/adapters/darcs_adapter.rb
--- a/lib/redmine/scm/adapters/darcs_adapter.rb
+++ b/lib/redmine/scm/adapters/darcs_adapter.rb
@@ -54,7 +54,8 @@
           end
         end
 
-        def initialize(url, root_url=nil, login=nil, password=nil)
+        def initialize(url, root_url=nil, login=nil, password=nil,
+                       path_encoding=nil, log_encoding=nil)
           @url = url
           @root_url = url
         end
diff --git a/lib/redmine/scm/adapters/filesystem_adapter.rb b/lib/redmine/scm/adapters/filesystem_adapter.rb
--- a/lib/redmine/scm/adapters/filesystem_adapter.rb
+++ b/lib/redmine/scm/adapters/filesystem_adapter.rb
@@ -32,7 +32,8 @@
           end
         end
 
-        def initialize(url, root_url=nil, login=nil, password=nil)
+        def initialize(url, root_url=nil, login=nil, password=nil,
+                       path_encoding=nil, log_encoding=nil)
           @url = with_trailling_slash(url)
         end
 
diff --git a/lib/redmine/scm/adapters/mercurial/redminehelper.py b/lib/redmine/scm/adapters/mercurial/redminehelper.py
--- a/lib/redmine/scm/adapters/mercurial/redminehelper.py
+++ b/lib/redmine/scm/adapters/mercurial/redminehelper.py
@@ -119,6 +119,9 @@
 
     ui.write('</manifest>\n')
 
+def rhcat(ui, repo, file1, *pats, **opts):
+    return commands.cat(ui, repo, urllib.unquote(file1), *map(urllib.unquote, pats), **opts)
+
 def rhdiff(ui, repo, *pats, **opts):
     """diff repository (or selected files)"""
     change = opts.pop('change', None)
@@ -156,6 +159,9 @@
 # This extension should be compatible with Mercurial 0.9.5.
 # Note that Mercurial 0.9.5 doesn't have extensions.wrapfunction().
 cmdtable = {
+    'rhcat': (rhcat,
+               [('r', 'rev', '', 'revision')],
+               'hg rhcat ([-r REV] ...) FILE...'),
     'rhdiff': (rhdiff,
                [('r', 'rev', [], 'revision'),
                 ('c', 'change', '', 'change made by revision')],
diff --git a/lib/redmine/scm/adapters/mercurial_adapter.rb b/lib/redmine/scm/adapters/mercurial_adapter.rb
--- a/lib/redmine/scm/adapters/mercurial_adapter.rb
+++ b/lib/redmine/scm/adapters/mercurial_adapter.rb
@@ -121,4 +121,5 @@
         private :summary
 
         def entries(path=nil, identifier=nil)
+          p1 = scm_iconv(@path_encoding, 'UTF-8', path)
           manifest = hg('rhmanifest', '-r', hgrev(identifier),
@@ -124,5 +125,5 @@
           manifest = hg('rhmanifest', '-r', hgrev(identifier),
-                        CGI.escape(without_leading_slash(path.to_s))) do |io|
+                        CGI.escape(without_leading_slash(p1.to_s))) do |io|
             begin
               ActiveSupport::XmlMini.parse(io.read)['rhmanifest']['repository']['manifest']
             rescue
@@ -132,9 +133,9 @@
 
           entries = Entries.new
           as_ary(manifest['dir']).each do |e|
-            n = CGI.unescape(e['name'])
+            n = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['name']))
             p = "#{path_prefix}#{n}"
             entries << Entry.new(:name => n, :path => p, :kind => 'dir')
           end
 
           as_ary(manifest['file']).each do |e|
@@ -136,9 +137,9 @@
             p = "#{path_prefix}#{n}"
             entries << Entry.new(:name => n, :path => p, :kind => 'dir')
           end
 
           as_ary(manifest['file']).each do |e|
-            n = CGI.unescape(e['name'])
+            n = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['name']))
             p = "#{path_prefix}#{n}"
             lr = Revision.new(:revision => e['revision'], :scmid => e['node'],
                               :identifier => e['node'],
@@ -180,7 +181,7 @@
             cpmap = Hash[*cpalist.flatten]
 
             paths = as_ary(le['paths']['path']).map do |e|
-              p = CGI.unescape(e['__content__'])
+              p = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['__content__']) )
               {:action => e['action'], :path => with_leading_slash(p),
                :from_path => (cpmap.member?(p) ? with_leading_slash(cpmap[p]) : nil),
                :from_revision => (cpmap.member?(p) ? le['revision'] : nil)}
@@ -203,7 +204,10 @@
           else
             hg_args << '-c' << hgrev(identifier_from)
           end
-          hg_args << CGI.escape(hgtarget(path)) unless path.blank?
+          unless path.blank?
+            p = scm_iconv(@path_encoding, 'UTF-8', path)
+            hg_args << CGI.escape(hgtarget(p))
+          end
           diff = []
           hg *hg_args do |io|
             io.each_line do |line|
@@ -216,7 +220,8 @@
         end
 
         def cat(path, identifier=nil)
-          hg 'cat', '-r', hgrev(identifier), hgtarget(path) do |io|
+          p = CGI.escape(scm_iconv(@path_encoding, 'UTF-8', path))
+          hg 'rhcat', '-r', hgrev(identifier), hgtarget(p) do |io|
             io.binmode
             io.read
           end
