Index: tracext/hg/backend.py
===================================================================
--- tracext/hg/backend.py	(revision 8365)
+++ tracext/hg/backend.py	(working copy)
@@ -291,7 +291,10 @@
 
     def __init__(self, path, log, ui, options):
         self.ui = ui
+        self.filename_encoding = options.get('filename_encoding')
         # TODO: per repository ui and options?
+        # Note: here we're dealing with the local fs encoding,
+        #       not necessarily the same as the filename_encoding
         if isinstance(path, unicode):
             str_path = path.encode('utf-8')
             if not os.path.exists(str_path):
@@ -350,6 +353,20 @@
         else:
             return nodestr
 
+    def _hgpath_to_unicode(self, path):
+        """Convert a Mercurial filename (bytes) to unicode using configured
+           encoding.
+        """
+        return to_unicode(path, self.filename_encoding)
+
+    def _unicode_to_hgpath(self, path):
+        """Convert a path in unicode to a Mercurial filename (bytes) using 
+           configured encoding.
+        """
+        if isinstance(path, unicode):
+            path = path.encode(self.filename_encoding or 'utf-8', 'replace')
+        return path
+
     def close(self):
         self.repo = None
 
@@ -584,20 +601,14 @@
         self.manifest = manifest
         self._dirnode = dirnode
 
-        if isinstance(path, unicode):
-            try:
-                self._init_path(log, path.encode('utf-8'))
-            except NoSuchNode:
-                self._init_path(log, path.encode('latin-1'))
-                # TODO: configurable charset for the repository, i.e. #3809
-        else:
-            self._init_path(log, path)
+        self._init_path(log, path)
 
     def findnode(self, n_rev, dirnames):
         dirnodes = {}
         log = self.repos.repo.changelog
         for rev in xrange(n_rev, -1, -1):
             for f in self.repos.repo.changectx(rev).files():
+                f = self.repos._hgpath_to_unicode(f)
                 for d in dirnames[:]:
                     if f.startswith(d):
                         dirnodes[d] = log.node(rev)
@@ -612,15 +623,19 @@
 
     def _init_path(self, log, path):
         kind = None
-        if path in self.manifest: # then it's a file
+        hgpath = self.repos._unicode_to_hgpath(path)
+        if hgpath in self.manifest:
+            # it's a file
             kind = Node.FILE
-            self.filectx = self.repos.repo.filectx(path, self.n)
+            self.filectx = self.repos.repo.filectx(hgpath, self.n)
             log_rev = self.filectx.linkrev()
             node = log.node(log_rev)
-        else: # it will be a directory if there are matching entries
+        else:
+            # it will be a directory if there are matching entries
             dir = path and path+'/' or ''
             entries = {}
-            for file in self.manifest.keys():
+            for hgfile in self.manifest.keys():
+                file = self.repos._hgpath_to_unicode(hgfile)
                 if file.startswith(dir):
                     entry = file[len(dir):].split('/', 1)[0]
                     entries[entry] = 1
@@ -633,7 +648,8 @@
                         node = self._dirnode
                     else:
                         # we find the most recent change for a file below dir
-                        node = self.findnode(log.rev(self.n), [dir,] ).values()[0]
+                        node = self.findnode(log.rev(self.n),
+                                             [dir,]).values()[0]
                 else:
                     node = log.tip()
         if not kind:

