# HG changeset patch # User Olivier Trempe <oliviertre...@gmail.com> # Date 1488981822 18000 # Wed Mar 08 09:03:42 2017 -0500 # Branch stable # Node ID 2021c3032968bef6b8d1cd7bea5a22996ced994c # Parent 68f263f52d2e3e2798b4f1e55cb665c6b043f93b fsmonitor: match watchman and filesystem encoding
watchman's paths encoding can differ from filesystem encoding. For example, on Windows, it's always utf-8. Before this patch, on Windows, mismatch in path comparison between fsmonitor state and osutil.statfiles would yield a clean status for added/modified files. In addition to status reporting wrong results, this leads to files being discarded from changesets while doing history editing operations such as rebase. diff --git a/hgext/fsmonitor/__init__.py b/hgext/fsmonitor/__init__.py --- a/hgext/fsmonitor/__init__.py +++ b/hgext/fsmonitor/__init__.py @@ -91,6 +91,7 @@ from __future__ import absolute_import +import codecs import hashlib import os import stat @@ -99,6 +100,7 @@ from mercurial import ( context, encoding, + error, extensions, localrepo, merge, @@ -110,6 +112,7 @@ from mercurial import match as matchmod from . import ( + pywatchman, state, watchmanclient, ) @@ -159,6 +162,23 @@ sha1.update('\0') return sha1.hexdigest() +_watchmanencoding = pywatchman.encoding.get_local_encoding() +_fsencoding = sys.getfilesystemencoding() or sys.getdefaultencoding() +_fixencoding = codecs.lookup(_watchmanencoding) != codecs.lookup(_fsencoding) + +def _watchmantofsencoding(path): + """Fix path to match watchman and local filesystem encoding + + watchman's paths encoding can differ from filesystem encoding. For example, + on Windows, it's always utf-8. + """ + try: + decoded = path.decode(_watchmanencoding) + except UnicodeDecodeError as e: + raise error.Abort(e, hint='watchman encoding error') + + return decoded.encode(_fsencoding, 'replace') + def overridewalk(orig, self, match, subrepos, unknown, ignored, full=True): '''Replacement for dirstate.walk, hooking into Watchman. @@ -303,6 +323,8 @@ # for name case changes. for entry in result['files']: fname = entry['name'] + if _fixencoding: + fname = _watchmantofsencoding(fname) if switch_slashes: fname = fname.replace('\\', '/') if normalize: _______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel