Mercurial > hg
annotate mercurial/pathutil.py @ 41247:a89b20a49c13
rust-cpython: using MissingAncestors from Python code
As precedently done with LazyAncestors on cpython.rs, we test for the
presence of the 'rustext' module.
incrementalmissingrevs() has two callers within the Mercurial core:
`setdiscovery.partialdiscovery` and the `only()` revset.
This move shows a significant discovery performance improvement
in cases where the baseline is slow: using perfdiscovery on the PyPy
repos, prepared with `contrib/discovery-helper <repo> 50 100`, we
get averaged medians of 403ms with the Rust version vs 742ms without
(about 45% better).
But there are still indications that performance can be worse in cases
the baseline is fast, possibly due to the conversion from Python to
Rust and back becoming the bottleneck. We could measure this on
mozilla-central in cases were the delta is just a few changesets.
This requires confirmation, but if that's the reason, then an
upcoming `partialdiscovery` fully in Rust should solve the problem.
Differential Revision: https://phab.mercurial-scm.org/D5551
author | Georges Racinet <georges.racinet@octobus.net> |
---|---|
date | Fri, 30 Nov 2018 14:35:57 +0100 |
parents | 21be76e07148 |
children | 2372284d9457 |
rev | line source |
---|---|
25964
d740df4e96cf
pathutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
1 from __future__ import absolute_import |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
2 |
25964
d740df4e96cf
pathutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
3 import errno |
d740df4e96cf
pathutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
4 import os |
d740df4e96cf
pathutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
5 import posixpath |
d740df4e96cf
pathutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
6 import stat |
d740df4e96cf
pathutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
7 |
d740df4e96cf
pathutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
8 from .i18n import _ |
d740df4e96cf
pathutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
9 from . import ( |
d740df4e96cf
pathutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
10 encoding, |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25964
diff
changeset
|
11 error, |
30614
cfe66dcf45c0
py3: replace os.sep with pycompat.ossep (part 2 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30332
diff
changeset
|
12 pycompat, |
25964
d740df4e96cf
pathutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
13 util, |
d740df4e96cf
pathutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
14 ) |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
15 |
23598
c02a05cc6f5e
pathauditor: check for codepoints ignored on OS X
Augie Fackler <raf@durin42.com>
parents:
21568
diff
changeset
|
16 def _lowerclean(s): |
c02a05cc6f5e
pathauditor: check for codepoints ignored on OS X
Augie Fackler <raf@durin42.com>
parents:
21568
diff
changeset
|
17 return encoding.hfsignoreclean(s.lower()) |
c02a05cc6f5e
pathauditor: check for codepoints ignored on OS X
Augie Fackler <raf@durin42.com>
parents:
21568
diff
changeset
|
18 |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
19 class pathauditor(object): |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
20 '''ensure that a filesystem path contains no banned components. |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
21 the following properties of a path are checked: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
22 |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
23 - ends with a directory separator |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
24 - under top-level .hg |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
25 - starts at the root of a windows drive |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
26 - contains ".." |
27232
79a86a95f325
pathauditor: add a way to skip file system check
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
27231
diff
changeset
|
27 |
79a86a95f325
pathauditor: add a way to skip file system check
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
27231
diff
changeset
|
28 More check are also done about the file system states: |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
29 - traverses a symlink (e.g. a/symlink_here/b) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
30 - inside a nested repository (a callback can be used to approve |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
31 some nested repositories, e.g., subrepositories) |
27232
79a86a95f325
pathauditor: add a way to skip file system check
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
27231
diff
changeset
|
32 |
79a86a95f325
pathauditor: add a way to skip file system check
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
27231
diff
changeset
|
33 The file system checks are only done when 'realfs' is set to True (the |
79a86a95f325
pathauditor: add a way to skip file system check
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
27231
diff
changeset
|
34 default). They should be disable then we are auditing path for operation on |
79a86a95f325
pathauditor: add a way to skip file system check
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
27231
diff
changeset
|
35 stored history. |
33649
377e8ddaebef
pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents:
33435
diff
changeset
|
36 |
377e8ddaebef
pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents:
33435
diff
changeset
|
37 If 'cached' is set to True, audited paths and sub-directories are cached. |
377e8ddaebef
pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents:
33435
diff
changeset
|
38 Be careful to not keep the cache of unmanaged directories for long because |
377e8ddaebef
pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents:
33435
diff
changeset
|
39 audited paths may be replaced with symlinks. |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
40 ''' |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
41 |
33649
377e8ddaebef
pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents:
33435
diff
changeset
|
42 def __init__(self, root, callback=None, realfs=True, cached=False): |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
43 self.audited = set() |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
44 self.auditeddir = set() |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
45 self.root = root |
27232
79a86a95f325
pathauditor: add a way to skip file system check
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
27231
diff
changeset
|
46 self._realfs = realfs |
33649
377e8ddaebef
pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents:
33435
diff
changeset
|
47 self._cached = cached |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
48 self.callback = callback |
29889
6f447b9ec263
util: rename checkcase() to fscasesensitive() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
28087
diff
changeset
|
49 if os.path.lexists(root) and not util.fscasesensitive(root): |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
50 self.normcase = util.normcase |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
51 else: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
52 self.normcase = lambda x: x |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
53 |
33435
456626e9c3d1
vfs: allow to pass more argument to audit
Boris Feld <boris.feld@octobus.net>
parents:
30614
diff
changeset
|
54 def __call__(self, path, mode=None): |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
55 '''Check the relative path. |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
56 path may contain a pattern (e.g. foodir/**.txt)''' |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
57 |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
58 path = util.localpath(path) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
59 normpath = self.normcase(path) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
60 if normpath in self.audited: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
61 return |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
62 # AIX ignores "/" at end of path, others raise EISDIR. |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
63 if util.endswithsep(path): |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25964
diff
changeset
|
64 raise error.Abort(_("path ends in directory separator: %s") % path) |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
65 parts = util.splitpath(path) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
66 if (os.path.splitdrive(path)[0] |
23598
c02a05cc6f5e
pathauditor: check for codepoints ignored on OS X
Augie Fackler <raf@durin42.com>
parents:
21568
diff
changeset
|
67 or _lowerclean(parts[0]) in ('.hg', '.hg.', '') |
36647
052351e3e1cd
py3: make os.pardir a bytes
Yuya Nishihara <yuya@tcha.org>
parents:
34980
diff
changeset
|
68 or pycompat.ospardir in parts): |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25964
diff
changeset
|
69 raise error.Abort(_("path contains illegal component: %s") % path) |
23599
6dad422ecc5a
pathauditor: check for Windows shortname aliases
Matt Mackall <mpm@selenic.com>
parents:
23598
diff
changeset
|
70 # Windows shortname aliases |
6dad422ecc5a
pathauditor: check for Windows shortname aliases
Matt Mackall <mpm@selenic.com>
parents:
23598
diff
changeset
|
71 for p in parts: |
6dad422ecc5a
pathauditor: check for Windows shortname aliases
Matt Mackall <mpm@selenic.com>
parents:
23598
diff
changeset
|
72 if "~" in p: |
6dad422ecc5a
pathauditor: check for Windows shortname aliases
Matt Mackall <mpm@selenic.com>
parents:
23598
diff
changeset
|
73 first, last = p.split("~", 1) |
6dad422ecc5a
pathauditor: check for Windows shortname aliases
Matt Mackall <mpm@selenic.com>
parents:
23598
diff
changeset
|
74 if last.isdigit() and first.upper() in ["HG", "HG8B6C"]: |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25964
diff
changeset
|
75 raise error.Abort(_("path contains illegal component: %s") |
23599
6dad422ecc5a
pathauditor: check for Windows shortname aliases
Matt Mackall <mpm@selenic.com>
parents:
23598
diff
changeset
|
76 % path) |
23598
c02a05cc6f5e
pathauditor: check for codepoints ignored on OS X
Augie Fackler <raf@durin42.com>
parents:
21568
diff
changeset
|
77 if '.hg' in _lowerclean(path): |
c02a05cc6f5e
pathauditor: check for codepoints ignored on OS X
Augie Fackler <raf@durin42.com>
parents:
21568
diff
changeset
|
78 lparts = [_lowerclean(p.lower()) for p in parts] |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
79 for p in '.hg', '.hg.': |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
80 if p in lparts[1:]: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
81 pos = lparts.index(p) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
82 base = os.path.join(*parts[:pos]) |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25964
diff
changeset
|
83 raise error.Abort(_("path '%s' is inside nested repo %r") |
36649
d3b893ec5f08
py3: fix formatting of path-auditing errors
Yuya Nishihara <yuya@tcha.org>
parents:
36647
diff
changeset
|
84 % (path, pycompat.bytestr(base))) |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
85 |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
86 normparts = util.splitpath(normpath) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
87 assert len(parts) == len(normparts) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
88 |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
89 parts.pop() |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
90 normparts.pop() |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
91 prefixes = [] |
28087
0b7ce0b16d8a
pathauditor: change parts verification order to be root first
Durham Goode <durham@fb.com>
parents:
27235
diff
changeset
|
92 # It's important that we check the path parts starting from the root. |
30332
318a24b52eeb
spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents:
29889
diff
changeset
|
93 # This means we won't accidentally traverse a symlink into some other |
28087
0b7ce0b16d8a
pathauditor: change parts verification order to be root first
Durham Goode <durham@fb.com>
parents:
27235
diff
changeset
|
94 # filesystem (which is potentially expensive to access). |
0b7ce0b16d8a
pathauditor: change parts verification order to be root first
Durham Goode <durham@fb.com>
parents:
27235
diff
changeset
|
95 for i in range(len(parts)): |
30614
cfe66dcf45c0
py3: replace os.sep with pycompat.ossep (part 2 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30332
diff
changeset
|
96 prefix = pycompat.ossep.join(parts[:i + 1]) |
cfe66dcf45c0
py3: replace os.sep with pycompat.ossep (part 2 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30332
diff
changeset
|
97 normprefix = pycompat.ossep.join(normparts[:i + 1]) |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
98 if normprefix in self.auditeddir: |
28087
0b7ce0b16d8a
pathauditor: change parts verification order to be root first
Durham Goode <durham@fb.com>
parents:
27235
diff
changeset
|
99 continue |
27232
79a86a95f325
pathauditor: add a way to skip file system check
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
27231
diff
changeset
|
100 if self._realfs: |
79a86a95f325
pathauditor: add a way to skip file system check
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
27231
diff
changeset
|
101 self._checkfs(prefix, path) |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
102 prefixes.append(normprefix) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
103 |
33649
377e8ddaebef
pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents:
33435
diff
changeset
|
104 if self._cached: |
377e8ddaebef
pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents:
33435
diff
changeset
|
105 self.audited.add(normpath) |
377e8ddaebef
pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents:
33435
diff
changeset
|
106 # only add prefixes to the cache after checking everything: we don't |
377e8ddaebef
pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents:
33435
diff
changeset
|
107 # want to add "foo/bar/baz" before checking if there's a "foo/.hg" |
377e8ddaebef
pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents:
33435
diff
changeset
|
108 self.auditeddir.update(prefixes) |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
109 |
27231
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
110 def _checkfs(self, prefix, path): |
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
111 """raise exception if a file system backed check fails""" |
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
112 curpath = os.path.join(self.root, prefix) |
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
113 try: |
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
114 st = os.lstat(curpath) |
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
115 except OSError as err: |
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
116 # EINVAL can be raised as invalid path syntax under win32. |
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
117 # They must be ignored for patterns can be checked too. |
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
118 if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL): |
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
119 raise |
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
120 else: |
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
121 if stat.S_ISLNK(st.st_mode): |
36649
d3b893ec5f08
py3: fix formatting of path-auditing errors
Yuya Nishihara <yuya@tcha.org>
parents:
36647
diff
changeset
|
122 msg = (_('path %r traverses symbolic link %r') |
d3b893ec5f08
py3: fix formatting of path-auditing errors
Yuya Nishihara <yuya@tcha.org>
parents:
36647
diff
changeset
|
123 % (pycompat.bytestr(path), pycompat.bytestr(prefix))) |
27235
054cd38a2f19
pathutil: use temporary variables instead of complicated wrapping
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
27232
diff
changeset
|
124 raise error.Abort(msg) |
27231
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
125 elif (stat.S_ISDIR(st.st_mode) and |
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
126 os.path.isdir(os.path.join(curpath, '.hg'))): |
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
127 if not self.callback or not self.callback(curpath): |
27235
054cd38a2f19
pathutil: use temporary variables instead of complicated wrapping
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
27232
diff
changeset
|
128 msg = _("path '%s' is inside nested repo %r") |
36649
d3b893ec5f08
py3: fix formatting of path-auditing errors
Yuya Nishihara <yuya@tcha.org>
parents:
36647
diff
changeset
|
129 raise error.Abort(msg % (path, pycompat.bytestr(prefix))) |
27231
6d29ce250a3d
pathauditor: move file system specific check in their own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26587
diff
changeset
|
130 |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
131 def check(self, path): |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
132 try: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
133 self(path) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
134 return True |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25964
diff
changeset
|
135 except (OSError, error.Abort): |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
136 return False |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
137 |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
138 def canonpath(root, cwd, myname, auditor=None): |
34980
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
139 '''return the canonical path of myname, given cwd and root |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
140 |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
141 >>> def check(root, cwd, myname): |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
142 ... a = pathauditor(root, realfs=False) |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
143 ... try: |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
144 ... return canonpath(root, cwd, myname, a) |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
145 ... except error.Abort: |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
146 ... return 'aborted' |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
147 >>> def unixonly(root, cwd, myname, expected='aborted'): |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
148 ... if pycompat.iswindows: |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
149 ... return expected |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
150 ... return check(root, cwd, myname) |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
151 >>> def winonly(root, cwd, myname, expected='aborted'): |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
152 ... if not pycompat.iswindows: |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
153 ... return expected |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
154 ... return check(root, cwd, myname) |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
155 >>> winonly(b'd:\\\\repo', b'c:\\\\dir', b'filename') |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
156 'aborted' |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
157 >>> winonly(b'c:\\\\repo', b'c:\\\\dir', b'filename') |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
158 'aborted' |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
159 >>> winonly(b'c:\\\\repo', b'c:\\\\', b'filename') |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
160 'aborted' |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
161 >>> winonly(b'c:\\\\repo', b'c:\\\\', b'repo\\\\filename', |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
162 ... b'filename') |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
163 'filename' |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
164 >>> winonly(b'c:\\\\repo', b'c:\\\\repo', b'filename', b'filename') |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
165 'filename' |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
166 >>> winonly(b'c:\\\\repo', b'c:\\\\repo\\\\subdir', b'filename', |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
167 ... b'subdir/filename') |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
168 'subdir/filename' |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
169 >>> unixonly(b'/repo', b'/dir', b'filename') |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
170 'aborted' |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
171 >>> unixonly(b'/repo', b'/', b'filename') |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
172 'aborted' |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
173 >>> unixonly(b'/repo', b'/', b'repo/filename', b'filename') |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
174 'filename' |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
175 >>> unixonly(b'/repo', b'/repo', b'filename', b'filename') |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
176 'filename' |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
177 >>> unixonly(b'/repo', b'/repo/subdir', b'filename', b'subdir/filename') |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
178 'subdir/filename' |
705d0f2bb677
pathutil: add doctests for canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34965
diff
changeset
|
179 ''' |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
180 if util.endswithsep(root): |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
181 rootsep = root |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
182 else: |
30614
cfe66dcf45c0
py3: replace os.sep with pycompat.ossep (part 2 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30332
diff
changeset
|
183 rootsep = root + pycompat.ossep |
20033
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
184 name = myname |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
185 if not os.path.isabs(name): |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
186 name = os.path.join(root, cwd, name) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
187 name = os.path.normpath(name) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
188 if auditor is None: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
189 auditor = pathauditor(root) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
190 if name != rootsep and name.startswith(rootsep): |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
191 name = name[len(rootsep):] |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
192 auditor(name) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
193 return util.pconvert(name) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
194 elif name == root: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
195 return '' |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
196 else: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
197 # Determine whether `name' is in the hierarchy at or beneath `root', |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
198 # by iterating name=dirname(name) until that causes no change (can't |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
199 # check name == '/', because that doesn't work on windows). The list |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
200 # `rel' holds the reversed list of components making up the relative |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
201 # file name we want. |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
202 rel = [] |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
203 while True: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
204 try: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
205 s = util.samefile(name, root) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
206 except OSError: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
207 s = False |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
208 if s: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
209 if not rel: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
210 # name was actually the same as root (maybe a symlink) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
211 return '' |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
212 rel.reverse() |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
213 name = os.path.join(*rel) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
214 auditor(name) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
215 return util.pconvert(name) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
216 dirname, basename = util.split(name) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
217 rel.append(basename) |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
218 if dirname == name: |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
219 break |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
220 name = dirname |
f962870712da
pathutil: tease out a new library to break an import cycle from canonpath use
Augie Fackler <raf@durin42.com>
parents:
diff
changeset
|
221 |
25011
7d6a507a4c53
pathutil: hint if a path is root relative instead of cwd relative (issue4663)
Matt Harbison <matt_harbison@yahoo.com>
parents:
23602
diff
changeset
|
222 # A common mistake is to use -R, but specify a file relative to the repo |
7d6a507a4c53
pathutil: hint if a path is root relative instead of cwd relative (issue4663)
Matt Harbison <matt_harbison@yahoo.com>
parents:
23602
diff
changeset
|
223 # instead of cwd. Detect that case, and provide a hint to the user. |
7d6a507a4c53
pathutil: hint if a path is root relative instead of cwd relative (issue4663)
Matt Harbison <matt_harbison@yahoo.com>
parents:
23602
diff
changeset
|
224 hint = None |
7d6a507a4c53
pathutil: hint if a path is root relative instead of cwd relative (issue4663)
Matt Harbison <matt_harbison@yahoo.com>
parents:
23602
diff
changeset
|
225 try: |
25022
10bbdcd89164
canonpath: fix infinite recursion
Matt Mackall <mpm@selenic.com>
parents:
25011
diff
changeset
|
226 if cwd != root: |
10bbdcd89164
canonpath: fix infinite recursion
Matt Mackall <mpm@selenic.com>
parents:
25011
diff
changeset
|
227 canonpath(root, root, myname, auditor) |
34965
f445b10dc7fb
pathutil: use util.pathto() to calculate relative cwd in canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34254
diff
changeset
|
228 relpath = util.pathto(root, cwd, '') |
38592
21be76e07148
py3: use bytes.endswith() instead of bytes[n]
Yuya Nishihara <yuya@tcha.org>
parents:
36649
diff
changeset
|
229 if relpath.endswith(pycompat.ossep): |
34965
f445b10dc7fb
pathutil: use util.pathto() to calculate relative cwd in canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34254
diff
changeset
|
230 relpath = relpath[:-1] |
f445b10dc7fb
pathutil: use util.pathto() to calculate relative cwd in canonpath()
Matt Harbison <matt_harbison@yahoo.com>
parents:
34254
diff
changeset
|
231 hint = (_("consider using '--cwd %s'") % relpath) |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25964
diff
changeset
|
232 except error.Abort: |
25011
7d6a507a4c53
pathutil: hint if a path is root relative instead of cwd relative (issue4663)
Matt Harbison <matt_harbison@yahoo.com>
parents:
23602
diff
changeset
|
233 pass |
7d6a507a4c53
pathutil: hint if a path is root relative instead of cwd relative (issue4663)
Matt Harbison <matt_harbison@yahoo.com>
parents:
23602
diff
changeset
|
234 |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25964
diff
changeset
|
235 raise error.Abort(_("%s not under root '%s'") % (myname, root), |
25011
7d6a507a4c53
pathutil: hint if a path is root relative instead of cwd relative (issue4663)
Matt Harbison <matt_harbison@yahoo.com>
parents:
23602
diff
changeset
|
236 hint=hint) |
21568
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
237 |
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
238 def normasprefix(path): |
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
239 '''normalize the specified path as path prefix |
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
240 |
23139
e53f6b72a0e4
spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents:
21568
diff
changeset
|
241 Returned value can be used safely for "p.startswith(prefix)", |
21568
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
242 "p[len(prefix):]", and so on. |
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
243 |
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
244 For efficiency, this expects "path" argument to be already |
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
245 normalized by "os.path.normpath", "os.path.realpath", and so on. |
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
246 |
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
247 See also issue3033 for detail about need of this function. |
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
248 |
34254
cd022a11ec83
py3: use bytes os.sep in doctest of pathutil.py
Yuya Nishihara <yuya@tcha.org>
parents:
34131
diff
changeset
|
249 >>> normasprefix(b'/foo/bar').replace(pycompat.ossep, b'/') |
21568
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
250 '/foo/bar/' |
34254
cd022a11ec83
py3: use bytes os.sep in doctest of pathutil.py
Yuya Nishihara <yuya@tcha.org>
parents:
34131
diff
changeset
|
251 >>> normasprefix(b'/').replace(pycompat.ossep, b'/') |
21568
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
252 '/' |
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
253 ''' |
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
254 d, p = os.path.splitdrive(path) |
30614
cfe66dcf45c0
py3: replace os.sep with pycompat.ossep (part 2 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30332
diff
changeset
|
255 if len(p) != len(pycompat.ossep): |
cfe66dcf45c0
py3: replace os.sep with pycompat.ossep (part 2 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents:
30332
diff
changeset
|
256 return path + pycompat.ossep |
21568
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
257 else: |
8dd17b19e722
subrepo: normalize path in the specific way for problematic encodings
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20033
diff
changeset
|
258 return path |
25281
660b178f49c7
pathutil: add dirname and join functions
Durham Goode <durham@fb.com>
parents:
25022
diff
changeset
|
259 |
25286
127a11f705d9
pathutil: demote two local functions to just be forwards
Augie Fackler <augie@google.com>
parents:
25285
diff
changeset
|
260 # forward two methods from posixpath that do what we need, but we'd |
127a11f705d9
pathutil: demote two local functions to just be forwards
Augie Fackler <augie@google.com>
parents:
25285
diff
changeset
|
261 # rather not let our internals know that we're thinking in posix terms |
127a11f705d9
pathutil: demote two local functions to just be forwards
Augie Fackler <augie@google.com>
parents:
25285
diff
changeset
|
262 # - instead we'll let them be oblivious. |
127a11f705d9
pathutil: demote two local functions to just be forwards
Augie Fackler <augie@google.com>
parents:
25285
diff
changeset
|
263 join = posixpath.join |
127a11f705d9
pathutil: demote two local functions to just be forwards
Augie Fackler <augie@google.com>
parents:
25285
diff
changeset
|
264 dirname = posixpath.dirname |