annotate mercurial/scmutil.py @ 14019:fbbd5f91d5e1

run-tests: do chdir for tests under a lock for thread safety
author Matt Mackall <mpm@selenic.com>
date Mon, 25 Apr 2011 17:01:34 -0500
parents 9c374cf76b7d
children e88a4958a6b7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
1 # scmutil.py - Mercurial core utility functions
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
2 #
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
3 # Copyright Matt Mackall <mpm@selenic.com>
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
4 #
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
7
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
8 from i18n import _
13984
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
9 import util, error, osutil
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
10 import os, errno, stat, sys
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
11
13974
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
12 def checkfilename(f):
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
13 '''Check that the filename f is an acceptable filename for a tracked file'''
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
14 if '\r' in f or '\n' in f:
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
15 raise util.Abort(_("'\\n' and '\\r' disallowed in filenames: %r") % f)
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
16
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
17 def checkportable(ui, f):
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
18 '''Check if filename f is portable and warn or abort depending on config'''
13974
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
19 checkfilename(f)
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
20 val = ui.config('ui', 'portablefilenames', 'warn')
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
21 lval = val.lower()
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
22 abort = os.name == 'nt' or lval == 'abort'
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
23 bval = util.parsebool(val)
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
24 if abort or lval == 'warn' or bval:
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
25 msg = util.checkwinfilename(f)
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
26 if msg:
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
27 if abort:
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
28 raise util.Abort("%s: %r" % (msg, f))
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
29 ui.warn(_("warning: %s: %r\n") % (msg, f))
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
30 elif bval is None and lval != 'ignore':
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
31 raise error.ConfigError(
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
32 _("ui.portablefilenames value is invalid ('%s')") % val)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
33
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
34 class path_auditor(object):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
35 '''ensure that a filesystem path contains no banned components.
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
36 the following properties of a path are checked:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
37
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
38 - ends with a directory separator
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
39 - under top-level .hg
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
40 - starts at the root of a windows drive
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
41 - contains ".."
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
42 - traverses a symlink (e.g. a/symlink_here/b)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
43 - inside a nested repository (a callback can be used to approve
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
44 some nested repositories, e.g., subrepositories)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
45 '''
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
46
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
47 def __init__(self, root, callback=None):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
48 self.audited = set()
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
49 self.auditeddir = set()
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
50 self.root = root
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
51 self.callback = callback
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
52
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
53 def __call__(self, path):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
54 '''Check the relative path.
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
55 path may contain a pattern (e.g. foodir/**.txt)'''
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
56
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
57 if path in self.audited:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
58 return
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
59 # AIX ignores "/" at end of path, others raise EISDIR.
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
60 if util.endswithsep(path):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
61 raise util.Abort(_("path ends in directory separator: %s") % path)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
62 normpath = os.path.normcase(path)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
63 parts = util.splitpath(normpath)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
64 if (os.path.splitdrive(path)[0]
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
65 or parts[0].lower() in ('.hg', '.hg.', '')
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
66 or os.pardir in parts):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
67 raise util.Abort(_("path contains illegal component: %s") % path)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
68 if '.hg' in path.lower():
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
69 lparts = [p.lower() for p in parts]
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
70 for p in '.hg', '.hg.':
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
71 if p in lparts[1:]:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
72 pos = lparts.index(p)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
73 base = os.path.join(*parts[:pos])
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
74 raise util.Abort(_('path %r is inside nested repo %r')
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
75 % (path, base))
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
76
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
77 parts.pop()
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
78 prefixes = []
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
79 while parts:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
80 prefix = os.sep.join(parts)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
81 if prefix in self.auditeddir:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
82 break
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
83 curpath = os.path.join(self.root, prefix)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
84 try:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
85 st = os.lstat(curpath)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
86 except OSError, err:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
87 # EINVAL can be raised as invalid path syntax under win32.
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
88 # They must be ignored for patterns can be checked too.
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
89 if err.errno not in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
90 raise
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
91 else:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
92 if stat.S_ISLNK(st.st_mode):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
93 raise util.Abort(
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
94 _('path %r traverses symbolic link %r')
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
95 % (path, prefix))
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
96 elif (stat.S_ISDIR(st.st_mode) and
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
97 os.path.isdir(os.path.join(curpath, '.hg'))):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
98 if not self.callback or not self.callback(curpath):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
99 raise util.Abort(_('path %r is inside nested repo %r') %
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
100 (path, prefix))
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
101 prefixes.append(prefix)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
102 parts.pop()
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
103
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
104 self.audited.add(path)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
105 # only add prefixes to the cache after checking everything: we don't
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
106 # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
107 self.auditeddir.update(prefixes)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
108
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
109 class opener(object):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
110 '''Open files relative to a base directory
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
111
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
112 This class is used to hide the details of COW semantics and
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
113 remote file access from higher level code.
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
114 '''
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
115 def __init__(self, base, audit=True):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
116 self.base = base
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
117 if audit:
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
118 self.auditor = path_auditor(base)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
119 else:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
120 self.auditor = util.always
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
121 self.createmode = None
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
122 self._trustnlink = None
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
123
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
124 @util.propertycache
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
125 def _can_symlink(self):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
126 return util.checklink(self.base)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
127
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
128 def _fixfilemode(self, name):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
129 if self.createmode is None:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
130 return
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
131 os.chmod(name, self.createmode & 0666)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
132
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
133 def __call__(self, path, mode="r", text=False, atomictemp=False):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
134 r = util.checkosfilename(path)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
135 if r:
13973
366fa83f9820 scmutil: fix erroneous Abort call
Adrian Buehlmann <adrian@cadifra.com>
parents: 13972
diff changeset
136 raise util.Abort("%s: %r" % (r, path))
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
137 self.auditor(path)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
138 f = os.path.join(self.base, path)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
139
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
140 if not text and "b" not in mode:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
141 mode += "b" # for that other OS
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
142
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
143 nlink = -1
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
144 dirname, basename = os.path.split(f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
145 # If basename is empty, then the path is malformed because it points
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
146 # to a directory. Let the posixfile() call below raise IOError.
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
147 if basename and mode not in ('r', 'rb'):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
148 if atomictemp:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
149 if not os.path.isdir(dirname):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
150 util.makedirs(dirname, self.createmode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
151 return util.atomictempfile(f, mode, self.createmode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
152 try:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
153 if 'w' in mode:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
154 util.unlink(f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
155 nlink = 0
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
156 else:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
157 # nlinks() may behave differently for files on Windows
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
158 # shares if the file is open.
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
159 fd = util.posixfile(f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
160 nlink = util.nlinks(f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
161 if nlink < 1:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
162 nlink = 2 # force mktempcopy (issue1922)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
163 fd.close()
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
164 except (OSError, IOError), e:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
165 if e.errno != errno.ENOENT:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
166 raise
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
167 nlink = 0
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
168 if not os.path.isdir(dirname):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
169 util.makedirs(dirname, self.createmode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
170 if nlink > 0:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
171 if self._trustnlink is None:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
172 self._trustnlink = nlink > 1 or util.checknlink(f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
173 if nlink > 1 or not self._trustnlink:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
174 util.rename(util.mktempcopy(f), f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
175 fp = util.posixfile(f, mode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
176 if nlink == 0:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
177 self._fixfilemode(f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
178 return fp
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
179
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
180 def symlink(self, src, dst):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
181 self.auditor(dst)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
182 linkname = os.path.join(self.base, dst)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
183 try:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
184 os.unlink(linkname)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
185 except OSError:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
186 pass
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
187
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
188 dirname = os.path.dirname(linkname)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
189 if not os.path.exists(dirname):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
190 util.makedirs(dirname, self.createmode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
191
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
192 if self._can_symlink:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
193 try:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
194 os.symlink(src, linkname)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
195 except OSError, err:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
196 raise OSError(err.errno, _('could not symlink to %r: %s') %
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
197 (src, err.strerror), linkname)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
198 else:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
199 f = self(dst, "w")
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
200 f.write(src)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
201 f.close()
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
202 self._fixfilemode(dst)
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
203
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
204 def canonpath(root, cwd, myname, auditor=None):
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
205 '''return the canonical path of myname, given cwd and root'''
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
206 if util.endswithsep(root):
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
207 rootsep = root
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
208 else:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
209 rootsep = root + os.sep
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
210 name = myname
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
211 if not os.path.isabs(name):
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
212 name = os.path.join(root, cwd, name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
213 name = os.path.normpath(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
214 if auditor is None:
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
215 auditor = path_auditor(root)
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
216 if name != rootsep and name.startswith(rootsep):
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
217 name = name[len(rootsep):]
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
218 auditor(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
219 return util.pconvert(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
220 elif name == root:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
221 return ''
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
222 else:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
223 # Determine whether `name' is in the hierarchy at or beneath `root',
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
224 # by iterating name=dirname(name) until that causes no change (can't
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
225 # check name == '/', because that doesn't work on windows). For each
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
226 # `name', compare dev/inode numbers. If they match, the list `rel'
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
227 # holds the reversed list of components making up the relative file
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
228 # name we want.
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
229 root_st = os.stat(root)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
230 rel = []
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
231 while True:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
232 try:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
233 name_st = os.stat(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
234 except OSError:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
235 break
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
236 if util.samestat(name_st, root_st):
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
237 if not rel:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
238 # name was actually the same as root (maybe a symlink)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
239 return ''
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
240 rel.reverse()
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
241 name = os.path.join(*rel)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
242 auditor(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
243 return util.pconvert(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
244 dirname, basename = os.path.split(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
245 rel.append(basename)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
246 if dirname == name:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
247 break
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
248 name = dirname
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
249
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
250 raise util.Abort('%s not under root' % myname)
13975
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
251
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
252 def walkrepos(path, followsym=False, seen_dirs=None, recurse=False):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
253 '''yield every hg repository under path, recursively.'''
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
254 def errhandler(err):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
255 if err.filename == path:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
256 raise err
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
257 if followsym and hasattr(os.path, 'samestat'):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
258 def _add_dir_if_not_there(dirlst, dirname):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
259 match = False
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
260 samestat = os.path.samestat
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
261 dirstat = os.stat(dirname)
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
262 for lstdirstat in dirlst:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
263 if samestat(dirstat, lstdirstat):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
264 match = True
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
265 break
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
266 if not match:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
267 dirlst.append(dirstat)
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
268 return not match
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
269 else:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
270 followsym = False
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
271
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
272 if (seen_dirs is None) and followsym:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
273 seen_dirs = []
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
274 _add_dir_if_not_there(seen_dirs, path)
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
275 for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
276 dirs.sort()
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
277 if '.hg' in dirs:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
278 yield root # found a repository
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
279 qroot = os.path.join(root, '.hg', 'patches')
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
280 if os.path.isdir(os.path.join(qroot, '.hg')):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
281 yield qroot # we have a patch queue repo here
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
282 if recurse:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
283 # avoid recursing inside the .hg directory
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
284 dirs.remove('.hg')
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
285 else:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
286 dirs[:] = [] # don't descend further
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
287 elif followsym:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
288 newdirs = []
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
289 for d in dirs:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
290 fname = os.path.join(root, d)
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
291 if _add_dir_if_not_there(seen_dirs, fname):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
292 if os.path.islink(fname):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
293 for hgname in walkrepos(fname, True, seen_dirs):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
294 yield hgname
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
295 else:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
296 newdirs.append(d)
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
297 dirs[:] = newdirs
13984
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
298
13985
26335a817dd0 move os_rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13984
diff changeset
299 def os_rcpath():
26335a817dd0 move os_rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13984
diff changeset
300 '''return default os-specific hgrc search path'''
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
301 path = system_rcpath()
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
302 path.extend(user_rcpath())
13985
26335a817dd0 move os_rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13984
diff changeset
303 path = [os.path.normpath(f) for f in path]
26335a817dd0 move os_rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13984
diff changeset
304 return path
26335a817dd0 move os_rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13984
diff changeset
305
13984
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
306 _rcpath = None
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
307
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
308 def rcpath():
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
309 '''return hgrc search path. if env var HGRCPATH is set, use it.
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
310 for each item in path, if directory, use files ending in .rc,
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
311 else use item.
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
312 make HGRCPATH empty to only look in .hg/hgrc of current repo.
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
313 if no HGRCPATH, use default os-specific path.'''
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
314 global _rcpath
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
315 if _rcpath is None:
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
316 if 'HGRCPATH' in os.environ:
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
317 _rcpath = []
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
318 for p in os.environ['HGRCPATH'].split(os.pathsep):
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
319 if not p:
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
320 continue
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
321 p = util.expandpath(p)
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
322 if os.path.isdir(p):
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
323 for f, kind in osutil.listdir(p):
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
324 if f.endswith('.rc'):
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
325 _rcpath.append(os.path.join(p, f))
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
326 else:
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
327 _rcpath.append(p)
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
328 else:
13985
26335a817dd0 move os_rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13984
diff changeset
329 _rcpath = os_rcpath()
13984
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
330 return _rcpath
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
331
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
332 if os.name != 'nt':
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
333
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
334 def rcfiles(path):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
335 rcs = [os.path.join(path, 'hgrc')]
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
336 rcdir = os.path.join(path, 'hgrc.d')
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
337 try:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
338 rcs.extend([os.path.join(rcdir, f)
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
339 for f, kind in osutil.listdir(rcdir)
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
340 if f.endswith(".rc")])
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
341 except OSError:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
342 pass
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
343 return rcs
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
344
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
345 def system_rcpath():
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
346 path = []
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
347 # old mod_python does not set sys.argv
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
348 if len(getattr(sys, 'argv', [])) > 0:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
349 path.extend(rcfiles(os.path.dirname(sys.argv[0]) +
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
350 '/../etc/mercurial'))
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
351 path.extend(rcfiles('/etc/mercurial'))
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
352 return path
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
353
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
354 def user_rcpath():
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
355 return [os.path.expanduser('~/.hgrc')]
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
356
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
357 else:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
358
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
359 _HKEY_LOCAL_MACHINE = 0x80000002L
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
360
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
361 def system_rcpath():
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
362 '''return default os-specific hgrc search path'''
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
363 rcpath = []
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
364 filename = util.executable_path()
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
365 # Use mercurial.ini found in directory with hg.exe
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
366 progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
367 if os.path.isfile(progrc):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
368 rcpath.append(progrc)
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
369 return rcpath
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
370 # Use hgrc.d found in directory with hg.exe
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
371 progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d')
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
372 if os.path.isdir(progrcd):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
373 for f, kind in osutil.listdir(progrcd):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
374 if f.endswith('.rc'):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
375 rcpath.append(os.path.join(progrcd, f))
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
376 return rcpath
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
377 # else look for a system rcpath in the registry
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
378 value = util.lookup_reg('SOFTWARE\\Mercurial', None,
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
379 _HKEY_LOCAL_MACHINE)
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
380 if not isinstance(value, str) or not value:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
381 return rcpath
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
382 value = value.replace('/', os.sep)
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
383 for p in value.split(os.pathsep):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
384 if p.lower().endswith('mercurial.ini'):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
385 rcpath.append(p)
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
386 elif os.path.isdir(p):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
387 for f, kind in osutil.listdir(p):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
388 if f.endswith('.rc'):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
389 rcpath.append(os.path.join(p, f))
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
390 return rcpath
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
391
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
392 def user_rcpath():
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
393 '''return os-specific hgrc search path to the user dir'''
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
394 home = os.path.expanduser('~')
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
395 path = [os.path.join(home, 'mercurial.ini'),
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
396 os.path.join(home, '.hgrc')]
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
397 userprofile = os.environ.get('USERPROFILE')
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
398 if userprofile:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
399 path.append(os.path.join(userprofile, 'mercurial.ini'))
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
400 path.append(os.path.join(userprofile, '.hgrc'))
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
401 return path