comparison mercurial/bundlerepo.py @ 24834:6e31e1274080 stable

bundlerepo: 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 bundlerepo 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 bundle URI (e.g. "bundle:bundlefile" or just "bundlefile") For example: $ hg --cwd \host\share -R \host\sharefoo\repo incoming bundle 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 bundlerepo instead of r"\host\sharefoo\repo" This causes failure of combining "\host\sharefoo\repo" and bundle file: in addition to it, "\host\share\foo\repo" may be combined with bundle file, 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 e0e28e910fa3
children 995003a324da
comparison
equal deleted inserted replaced
24833:cb981009d697 24834:6e31e1274080
14 from node import nullid 14 from node import nullid
15 from i18n import _ 15 from i18n import _
16 import os, tempfile, shutil 16 import os, tempfile, shutil
17 import changegroup, util, mdiff, discovery, cmdutil, scmutil, exchange 17 import changegroup, util, mdiff, discovery, cmdutil, scmutil, exchange
18 import localrepo, changelog, manifest, filelog, revlog, error, phases, bundle2 18 import localrepo, changelog, manifest, filelog, revlog, error, phases, bundle2
19 import pathutil
19 20
20 class bundlerevlog(revlog.revlog): 21 class bundlerevlog(revlog.revlog):
21 def __init__(self, opener, indexfile, bundle, linkmapper): 22 def __init__(self, opener, indexfile, bundle, linkmapper):
22 # How it works: 23 # How it works:
23 # To retrieve a revision, we need to know the offset of the revision in 24 # To retrieve a revision, we need to know the offset of the revision in
350 # In particular, we don't want temp dir names in test outputs. 351 # In particular, we don't want temp dir names in test outputs.
351 cwd = os.getcwd() 352 cwd = os.getcwd()
352 if parentpath == cwd: 353 if parentpath == cwd:
353 parentpath = '' 354 parentpath = ''
354 else: 355 else:
355 cwd = os.path.join(cwd,'') 356 cwd = pathutil.normasprefix(cwd)
356 if parentpath.startswith(cwd): 357 if parentpath.startswith(cwd):
357 parentpath = parentpath[len(cwd):] 358 parentpath = parentpath[len(cwd):]
358 u = util.url(path) 359 u = util.url(path)
359 path = u.localpath() 360 path = u.localpath()
360 if u.scheme == 'bundle': 361 if u.scheme == 'bundle':