Mercurial > hg-stable
comparison mercurial/unionrepo.py @ 24835:e4f75c93f073 stable
unionrepo: use pathutil.normasprefix to ensure os.sep at the end of cwd
Since Python 2.7.9, "os.path.join(path, '')" doesn't add "os.sep" at
the end of UNC path (see issue4557 for detail).
This makes unionrepo incorrectly work, if:
1. cwd is the root of UNC share (e.g. "\host\share"), and
2. mainreporoot is near cwd (e.g. "\host\sharefoo\repo")
- host of UNC path is same as one of cwd
- share of UNC path starts with one of cwd
3. "repopath" isn't specified in URI (e.g. "union:path/to/repo2")
For example:
$ hg --cwd \host\share -R \host\sharefoo\repo incoming union:path\to\repo2
In this case:
- os.path.join(r"\host\share", "") returns r"\host\share",
- r"\host\sharefoo\repo".startswith(r"\host\share") returns True, then
- r"foo\repo" is treated as repopath of unionrepo instead of
r"\host\sharefoo\repo"
This causes failure of combining "\host\sharefoo\repo" and another
repository: in addition to it, "\host\share\foo\repo" may be combined
with another repository, if it accidentally exists.
This patch uses "pathutil.normasprefix()" to ensure "os.sep" at the
end of cwd safely, even with some problematic encodings, which use
0x5c (= "os.sep" on Windows) as the tail byte of some multi-byte
characters.
BTW, normalization before "pathutil.normasprefix()" isn't needed in
this case, because "os.getcwd()" always returns normalized one.
author | FUJIWARA Katsunori <foozy@lares.dti.ne.jp> |
---|---|
date | Wed, 22 Apr 2015 23:38:55 +0900 |
parents | 76f6ae06ddf5 |
children | 83f220c7d6f0 |
comparison
equal
deleted
inserted
replaced
24834:6e31e1274080 | 24835:e4f75c93f073 |
---|---|
13 | 13 |
14 from node import nullid | 14 from node import nullid |
15 from i18n import _ | 15 from i18n import _ |
16 import os | 16 import os |
17 import util, mdiff, cmdutil, scmutil | 17 import util, mdiff, cmdutil, scmutil |
18 import localrepo, changelog, manifest, filelog, revlog | 18 import localrepo, changelog, manifest, filelog, revlog, pathutil |
19 | 19 |
20 class unionrevlog(revlog.revlog): | 20 class unionrevlog(revlog.revlog): |
21 def __init__(self, opener, indexfile, revlog2, linkmapper): | 21 def __init__(self, opener, indexfile, revlog2, linkmapper): |
22 # How it works: | 22 # How it works: |
23 # To retrieve a revision, we just need to know the node id so we can | 23 # To retrieve a revision, we just need to know the node id so we can |
226 # In particular, we don't want temp dir names in test outputs. | 226 # In particular, we don't want temp dir names in test outputs. |
227 cwd = os.getcwd() | 227 cwd = os.getcwd() |
228 if parentpath == cwd: | 228 if parentpath == cwd: |
229 parentpath = '' | 229 parentpath = '' |
230 else: | 230 else: |
231 cwd = os.path.join(cwd,'') | 231 cwd = pathutil.normasprefix(cwd) |
232 if parentpath.startswith(cwd): | 232 if parentpath.startswith(cwd): |
233 parentpath = parentpath[len(cwd):] | 233 parentpath = parentpath[len(cwd):] |
234 if path.startswith('union:'): | 234 if path.startswith('union:'): |
235 s = path.split(":", 1)[1].split("+", 1) | 235 s = path.split(":", 1)[1].split("+", 1) |
236 if len(s) == 1: | 236 if len(s) == 1: |