Patchwork [1,of,4,STABLE] dirstate: use pathutil.normasprefix to ensure os.sep at the end of root

login
register
mail settings
Submitter Katsunori FUJIWARA
Date April 22, 2015, 2:43 p.m.
Message ID <599675fccf2206583d47.1429713836@juju>
Download mbox | patch
Permalink /patch/8760/
State Accepted
Headers show

Comments

Katsunori FUJIWARA - April 22, 2015, 2:43 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1429713532 -32400
#      Wed Apr 22 23:38:52 2015 +0900
# Branch stable
# Node ID 599675fccf2206583d47cfef041dfa5c3398ea61
# Parent  8e9f8d2a2c0cde933eae107efb03c66efbd93c69
dirstate: use pathutil.normasprefix to ensure os.sep at the end of root

3cc630be5f09 replaced "os.path.join(root, '')" by
"root.endswith(os.sep)" examination, because Python 2.7.9 changes
behavior of "os.path.join(path, '')" on UNC path.

But some problematic encodings use 0x5c (= "os.sep" on Windows) as the
tail byte of some multi-byte characters, and replacement above
prevents Mercurial from working on the repository, of which root path
ends with such multi-byte character, regardless of enabling win32mbcs.

This patch uses "pathutil.normasprefix()" instead of
"root.endswith(os.sep)" examination, to ensure "os.sep" at the end of
"dirstate._rootdir" even with problematic encodings.

"root" of dirstate can be passed to "pathutil.normasprefix()" without
normalization, because it is always given from "repo.root" =
"repo.wvfs.base", which is normalized by "os.path.realpath()".

Using "util.endswithsep()" instead of "str.endswith(os.sep)" also
fixes this problem, but this patch chooses "pathutil.normasprefix()"
to centralize "adding os.sep if endswith(os.sep)" logic into it.

Patch

diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -40,10 +40,7 @@  class dirstate(object):
         self._root = root
         # ntpath.join(root, '') of Python 2.7.9 does not add sep if root is
         # UNC path pointing to root share (issue4557)
-        if root.endswith(os.sep):
-            self._rootdir = root
-        else:
-            self._rootdir = root + os.sep
+        self._rootdir = pathutil.normasprefix(root)
         self._dirty = False
         self._dirtypl = False
         self._lastnormaltime = 0