annotate mercurial/scmutil.py @ 15823:a1f818a2b50d

phases: ``{phase}`` template keyword display the phase name ``{phaseidx}`` is providing the phase index as integer. This integer representation is useful when people need to use the fact that phase are ordered. Test keep using the number version for readability purpose.
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
date Fri, 06 Jan 2012 11:20:49 +0100
parents c7a8164c61ab
children 0b05e0bfdc1c
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 _
14980
28e98a8b173d i18n: use UTF-8 string to lower filename for case collision check
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 14861
diff changeset
9 import util, error, osutil, revset, similar, encoding
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
10 import match as matchmod
14861
6ed2a449cb5b scmutil: add missing import of re
Steve Borho <steve@borho.org>
parents: 14746
diff changeset
11 import os, errno, re, stat, sys, glob
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
12
13974
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
13 def checkfilename(f):
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
14 '''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
15 if '\r' in f or '\n' in f:
23f2736abce3 move checkfilename from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13973
diff changeset
16 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
17
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
18 def checkportable(ui, f):
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
19 '''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
20 checkfilename(f)
14138
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
21 abort, warn = checkportabilityalert(ui)
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
22 if abort or warn:
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
23 msg = util.checkwinfilename(f)
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
24 if msg:
14138
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
25 msg = "%s: %r" % (msg, f)
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
26 if abort:
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
27 raise util.Abort(msg)
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
28 ui.warn(_("warning: %s\n") % msg)
14068
04ce8fa1015d add: notify when adding a file that would cause a case-folding collision
Kevin Gessner <kevin@kevingessner.com>
parents: 14067
diff changeset
29
14067
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
30 def checkportabilityalert(ui):
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
31 '''check if the user's config requests nothing, a warning, or abort for
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
32 non-portable filenames'''
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
33 val = ui.config('ui', 'portablefilenames', 'warn')
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
34 lval = val.lower()
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
35 bval = util.parsebool(val)
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
36 abort = os.name == 'nt' or lval == 'abort'
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
37 warn = bval or lval == 'warn'
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
38 if bval is None and not (warn or abort or lval == 'ignore'):
13962
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
39 raise error.ConfigError(
8b252e826c68 add: introduce a warning message for non-portable filenames (issue2756) (BC)
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
40 _("ui.portablefilenames value is invalid ('%s')") % val)
14067
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
41 return abort, warn
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
42
14138
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
43 class casecollisionauditor(object):
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
44 def __init__(self, ui, abort, existingiter):
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
45 self._ui = ui
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
46 self._abort = abort
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
47 self._map = {}
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
48 for f in existingiter:
14980
28e98a8b173d i18n: use UTF-8 string to lower filename for case collision check
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 14861
diff changeset
49 self._map[encoding.lower(f)] = f
14067
e88a4958a6b7 scmutil: refactor ui.portablefilenames processing
Kevin Gessner <kevin@kevingessner.com>
parents: 13986
diff changeset
50
14138
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
51 def __call__(self, f):
14980
28e98a8b173d i18n: use UTF-8 string to lower filename for case collision check
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 14861
diff changeset
52 fl = encoding.lower(f)
14138
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
53 map = self._map
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
54 if fl in map and map[fl] != f:
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
55 msg = _('possible case-folding collision for %s') % f
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
56 if self._abort:
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
57 raise util.Abort(msg)
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
58 self._ui.warn(_("warning: %s\n") % msg)
c18204fd35b0 scmutil: introduce casecollisionauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14097
diff changeset
59 map[fl] = f
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
60
14220
21b8ce4d3331 rename path_auditor to pathauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14167
diff changeset
61 class pathauditor(object):
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
62 '''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
63 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
64
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
65 - ends with a directory separator
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
66 - under top-level .hg
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
67 - 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
68 - contains ".."
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
69 - 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
70 - 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
71 some nested repositories, e.g., subrepositories)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
72 '''
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
73
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
74 def __init__(self, root, callback=None):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
75 self.audited = set()
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
76 self.auditeddir = set()
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
77 self.root = root
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
78 self.callback = callback
15666
37a6e9765015 pathauditor: switch normcase logic according to case sensitivity of filesystem
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15665
diff changeset
79 if os.path.lexists(root) and not util.checkcase(root):
37a6e9765015 pathauditor: switch normcase logic according to case sensitivity of filesystem
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15665
diff changeset
80 self.normcase = util.normcase
37a6e9765015 pathauditor: switch normcase logic according to case sensitivity of filesystem
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15665
diff changeset
81 else:
37a6e9765015 pathauditor: switch normcase logic according to case sensitivity of filesystem
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15665
diff changeset
82 self.normcase = lambda x: x
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
83
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
84 def __call__(self, path):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
85 '''Check the relative path.
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
86 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
87
15721
4751d5133f15 windows: force specified path to be audited in localpath form
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15666
diff changeset
88 path = util.localpath(path)
15666
37a6e9765015 pathauditor: switch normcase logic according to case sensitivity of filesystem
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15665
diff changeset
89 normpath = self.normcase(path)
15664
ec8730886f36 pathauditor: use normcase()-ed path for audit result cache
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 14984
diff changeset
90 if normpath in self.audited:
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
91 return
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
92 # 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
93 if util.endswithsep(path):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
94 raise util.Abort(_("path ends in directory separator: %s") % path)
15665
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
95 parts = util.splitpath(path)
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
96 if (os.path.splitdrive(path)[0]
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
97 or parts[0].lower() in ('.hg', '.hg.', '')
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
98 or os.pardir in parts):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
99 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
100 if '.hg' in path.lower():
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
101 lparts = [p.lower() for p in parts]
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
102 for p in '.hg', '.hg.':
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
103 if p in lparts[1:]:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
104 pos = lparts.index(p)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
105 base = os.path.join(*parts[:pos])
15436
18f1bb70462e cmdutil: don't use repr on paths in pathauditor - it looks strange on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 14984
diff changeset
106 raise util.Abort(_("path '%s' is inside nested repo %r")
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
107 % (path, base))
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
108
15665
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
109 normparts = util.splitpath(normpath)
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
110 assert len(parts) == len(normparts)
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
111
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
112 parts.pop()
15665
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
113 normparts.pop()
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
114 prefixes = []
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
115 while parts:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
116 prefix = os.sep.join(parts)
15665
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
117 normprefix = os.sep.join(normparts)
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
118 if normprefix in self.auditeddir:
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
119 break
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
120 curpath = os.path.join(self.root, prefix)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
121 try:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
122 st = os.lstat(curpath)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
123 except OSError, err:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
124 # 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
125 # 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
126 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
127 raise
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
128 else:
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
129 if stat.S_ISLNK(st.st_mode):
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
130 raise util.Abort(
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
131 _('path %r traverses symbolic link %r')
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
132 % (path, prefix))
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
133 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
134 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
135 if not self.callback or not self.callback(curpath):
15436
18f1bb70462e cmdutil: don't use repr on paths in pathauditor - it looks strange on windows
Mads Kiilerich <mads@kiilerich.com>
parents: 14984
diff changeset
136 raise util.Abort(_("path '%s' is inside nested repo %r") %
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
137 (path, prefix))
15665
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
138 prefixes.append(normprefix)
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
139 parts.pop()
15665
081e795c60e0 pathauditor: preserve case in abort messages
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15664
diff changeset
140 normparts.pop()
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
141
15664
ec8730886f36 pathauditor: use normcase()-ed path for audit result cache
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 14984
diff changeset
142 self.audited.add(normpath)
13972
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
143 # 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
144 # 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
145 self.auditeddir.update(prefixes)
d1f4e7fd970a move path_auditor from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13971
diff changeset
146
14089
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
147 class abstractopener(object):
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
148 """Abstract base class; cannot be instantiated"""
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
149
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
150 def __init__(self, *args, **kwargs):
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
151 '''Prevent instantiation; don't call this from subclasses.'''
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
152 raise NotImplementedError('attempted instantiating ' + str(type(self)))
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
153
14167
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
154 def read(self, path):
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
155 fp = self(path, 'rb')
14097
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
156 try:
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
157 return fp.read()
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
158 finally:
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
159 fp.close()
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
160
14167
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
161 def write(self, path, data):
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
162 fp = self(path, 'wb')
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
163 try:
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
164 return fp.write(data)
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
165 finally:
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
166 fp.close()
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
167
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
168 def append(self, path, data):
0e4753807c93 util & scmutil: adapt read/write helpers as request by mpm
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14138
diff changeset
169 fp = self(path, 'ab')
14097
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
170 try:
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
171 return fp.write(data)
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
172 finally:
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
173 fp.close()
ca3376f044f8 opener: add read & write utility methods
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14090
diff changeset
174
14089
d3f7e110c3c0 opener: introduce an abstact superclass of it
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14068
diff changeset
175 class opener(abstractopener):
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
176 '''Open files relative to a base directory
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
177
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
178 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
179 remote file access from higher level code.
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
180 '''
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
181 def __init__(self, base, audit=True):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
182 self.base = base
14720
36283a7b6856 opener: add self._audit (issue2862)
Adrian Buehlmann <adrian@cadifra.com>
parents: 14672
diff changeset
183 self._audit = audit
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
184 if audit:
14220
21b8ce4d3331 rename path_auditor to pathauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14167
diff changeset
185 self.auditor = pathauditor(base)
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
186 else:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
187 self.auditor = util.always
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
188 self.createmode = None
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
189 self._trustnlink = None
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
190
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
191 @util.propertycache
14261
e3649bcca3f6 opener: rename _can_symlink to _cansymlink
Adrian Buehlmann <adrian@cadifra.com>
parents: 14236
diff changeset
192 def _cansymlink(self):
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
193 return util.checklink(self.base)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
194
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
195 def _fixfilemode(self, name):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
196 if self.createmode is None:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
197 return
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
198 os.chmod(name, self.createmode & 0666)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
199
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
200 def __call__(self, path, mode="r", text=False, atomictemp=False):
14720
36283a7b6856 opener: add self._audit (issue2862)
Adrian Buehlmann <adrian@cadifra.com>
parents: 14672
diff changeset
201 if self._audit:
36283a7b6856 opener: add self._audit (issue2862)
Adrian Buehlmann <adrian@cadifra.com>
parents: 14672
diff changeset
202 r = util.checkosfilename(path)
36283a7b6856 opener: add self._audit (issue2862)
Adrian Buehlmann <adrian@cadifra.com>
parents: 14672
diff changeset
203 if r:
36283a7b6856 opener: add self._audit (issue2862)
Adrian Buehlmann <adrian@cadifra.com>
parents: 14672
diff changeset
204 raise util.Abort("%s: %r" % (r, path))
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
205 self.auditor(path)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
206 f = os.path.join(self.base, path)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
207
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
208 if not text and "b" not in mode:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
209 mode += "b" # for that other OS
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
210
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
211 nlink = -1
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
212 dirname, basename = os.path.split(f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
213 # 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
214 # 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
215 if basename and mode not in ('r', 'rb'):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
216 if atomictemp:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
217 if not os.path.isdir(dirname):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
218 util.makedirs(dirname, self.createmode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
219 return util.atomictempfile(f, mode, self.createmode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
220 try:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
221 if 'w' in mode:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
222 util.unlink(f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
223 nlink = 0
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
224 else:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
225 # nlinks() may behave differently for files on Windows
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
226 # shares if the file is open.
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
227 fd = util.posixfile(f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
228 nlink = util.nlinks(f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
229 if nlink < 1:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
230 nlink = 2 # force mktempcopy (issue1922)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
231 fd.close()
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
232 except (OSError, IOError), e:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
233 if e.errno != errno.ENOENT:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
234 raise
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
235 nlink = 0
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
236 if not os.path.isdir(dirname):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
237 util.makedirs(dirname, self.createmode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
238 if nlink > 0:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
239 if self._trustnlink is None:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
240 self._trustnlink = nlink > 1 or util.checknlink(f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
241 if nlink > 1 or not self._trustnlink:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
242 util.rename(util.mktempcopy(f), f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
243 fp = util.posixfile(f, mode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
244 if nlink == 0:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
245 self._fixfilemode(f)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
246 return fp
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
247
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
248 def symlink(self, src, dst):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
249 self.auditor(dst)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
250 linkname = os.path.join(self.base, dst)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
251 try:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
252 os.unlink(linkname)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
253 except OSError:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
254 pass
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
255
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
256 dirname = os.path.dirname(linkname)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
257 if not os.path.exists(dirname):
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
258 util.makedirs(dirname, self.createmode)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
259
14261
e3649bcca3f6 opener: rename _can_symlink to _cansymlink
Adrian Buehlmann <adrian@cadifra.com>
parents: 14236
diff changeset
260 if self._cansymlink:
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
261 try:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
262 os.symlink(src, linkname)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
263 except OSError, err:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
264 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
265 (src, err.strerror), linkname)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
266 else:
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
267 f = self(dst, "w")
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
268 f.write(src)
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
269 f.close()
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13962
diff changeset
270 self._fixfilemode(dst)
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
271
14404
69b60edfd76c opener: add audit function
Adrian Buehlmann <adrian@cadifra.com>
parents: 14320
diff changeset
272 def audit(self, path):
69b60edfd76c opener: add audit function
Adrian Buehlmann <adrian@cadifra.com>
parents: 14320
diff changeset
273 self.auditor(path)
69b60edfd76c opener: add audit function
Adrian Buehlmann <adrian@cadifra.com>
parents: 14320
diff changeset
274
14090
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
275 class filteropener(abstractopener):
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
276 '''Wrapper opener for filtering filenames with a function.'''
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
277
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
278 def __init__(self, opener, filter):
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
279 self._filter = filter
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
280 self._orig = opener
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
281
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
282 def __call__(self, path, *args, **kwargs):
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
283 return self._orig(self._filter(path), *args, **kwargs)
e24b5e3c2f27 add filteropener abstraction for store openers
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 14089
diff changeset
284
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
285 def canonpath(root, cwd, myname, auditor=None):
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
286 '''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
287 if util.endswithsep(root):
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
288 rootsep = root
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
289 else:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
290 rootsep = root + os.sep
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
291 name = myname
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
292 if not os.path.isabs(name):
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
293 name = os.path.join(root, cwd, name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
294 name = os.path.normpath(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
295 if auditor is None:
14220
21b8ce4d3331 rename path_auditor to pathauditor
Adrian Buehlmann <adrian@cadifra.com>
parents: 14167
diff changeset
296 auditor = pathauditor(root)
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
297 if name != rootsep and name.startswith(rootsep):
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
298 name = name[len(rootsep):]
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
299 auditor(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
300 return util.pconvert(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
301 elif name == root:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
302 return ''
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
303 else:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
304 # 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
305 # 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
306 # 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
307 # `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
308 # 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
309 # name we want.
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
310 root_st = os.stat(root)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
311 rel = []
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
312 while True:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
313 try:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
314 name_st = os.stat(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
315 except OSError:
15797
c7a8164c61ab canonpath: allow canonicalization of non-existant paths
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 15735
diff changeset
316 name_st = None
c7a8164c61ab canonpath: allow canonicalization of non-existant paths
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 15735
diff changeset
317 if name_st and util.samestat(name_st, root_st):
13971
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
318 if not rel:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
319 # 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
320 return ''
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
321 rel.reverse()
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
322 name = os.path.join(*rel)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
323 auditor(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
324 return util.pconvert(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
325 dirname, basename = os.path.split(name)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
326 rel.append(basename)
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
327 if dirname == name:
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
328 break
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
329 name = dirname
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
330
bfeaa88b875d move canonpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13970
diff changeset
331 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
332
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
333 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
334 '''yield every hg repository under path, recursively.'''
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
335 def errhandler(err):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
336 if err.filename == path:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
337 raise err
14961
5523529bd1af walkrepos: use getattr instead of hasattr for samestat
Augie Fackler <durin42@gmail.com>
parents: 14928
diff changeset
338 samestat = getattr(os.path, 'samestat', None)
5523529bd1af walkrepos: use getattr instead of hasattr for samestat
Augie Fackler <durin42@gmail.com>
parents: 14928
diff changeset
339 if followsym and samestat is not None:
14227
94985b5a8278 scmutil: rename local function _add_dir_if_not_there
Adrian Buehlmann <adrian@cadifra.com>
parents: 14226
diff changeset
340 def adddir(dirlst, dirname):
13975
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
341 match = False
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
342 dirstat = os.stat(dirname)
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
343 for lstdirstat in dirlst:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
344 if samestat(dirstat, lstdirstat):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
345 match = True
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
346 break
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
347 if not match:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
348 dirlst.append(dirstat)
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
349 return not match
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
350 else:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
351 followsym = False
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
352
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
353 if (seen_dirs is None) and followsym:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
354 seen_dirs = []
14227
94985b5a8278 scmutil: rename local function _add_dir_if_not_there
Adrian Buehlmann <adrian@cadifra.com>
parents: 14226
diff changeset
355 adddir(seen_dirs, path)
13975
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
356 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
357 dirs.sort()
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
358 if '.hg' in dirs:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
359 yield root # found a repository
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
360 qroot = os.path.join(root, '.hg', 'patches')
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
361 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
362 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
363 if recurse:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
364 # avoid recursing inside the .hg directory
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
365 dirs.remove('.hg')
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
366 else:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
367 dirs[:] = [] # don't descend further
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
368 elif followsym:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
369 newdirs = []
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
370 for d in dirs:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
371 fname = os.path.join(root, d)
14227
94985b5a8278 scmutil: rename local function _add_dir_if_not_there
Adrian Buehlmann <adrian@cadifra.com>
parents: 14226
diff changeset
372 if adddir(seen_dirs, fname):
13975
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
373 if os.path.islink(fname):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
374 for hgname in walkrepos(fname, True, seen_dirs):
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
375 yield hgname
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
376 else:
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
377 newdirs.append(d)
938fbeacac84 move walkrepos from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13974
diff changeset
378 dirs[:] = newdirs
13984
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
379
14224
f4189866c76c rename scmutil.os_rcpath to osrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14220
diff changeset
380 def osrcpath():
13985
26335a817dd0 move os_rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13984
diff changeset
381 '''return default os-specific hgrc search path'''
14225
f0ca440b5722 rename scmutil.system_rcpath to systemrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14224
diff changeset
382 path = systemrcpath()
14226
73cca883370d rename scmutil.user_rcpath to userrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14225
diff changeset
383 path.extend(userrcpath())
13985
26335a817dd0 move os_rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13984
diff changeset
384 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
385 return path
26335a817dd0 move os_rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13984
diff changeset
386
13984
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
387 _rcpath = None
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
388
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
389 def rcpath():
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
390 '''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
391 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
392 else use item.
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
393 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
394 if no HGRCPATH, use default os-specific path.'''
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
395 global _rcpath
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
396 if _rcpath is None:
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
397 if 'HGRCPATH' in os.environ:
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
398 _rcpath = []
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
399 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
400 if not p:
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
401 continue
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
402 p = util.expandpath(p)
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
403 if os.path.isdir(p):
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
404 for f, kind in osutil.listdir(p):
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
405 if f.endswith('.rc'):
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
406 _rcpath.append(os.path.join(p, f))
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
407 else:
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
408 _rcpath.append(p)
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
409 else:
14224
f4189866c76c rename scmutil.os_rcpath to osrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14220
diff changeset
410 _rcpath = osrcpath()
13984
af60153b5e3b move rcpath from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13975
diff changeset
411 return _rcpath
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
412
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
413 if os.name != 'nt':
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
414
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
415 def rcfiles(path):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
416 rcs = [os.path.join(path, 'hgrc')]
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
417 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
418 try:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
419 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
420 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
421 if f.endswith(".rc")])
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
422 except OSError:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
423 pass
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
424 return rcs
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
425
14225
f0ca440b5722 rename scmutil.system_rcpath to systemrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14224
diff changeset
426 def systemrcpath():
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
427 path = []
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
428 # 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
429 if len(getattr(sys, 'argv', [])) > 0:
14527
5867bd6e7cf5 scmutil: improve path calculation for install-relative RC files (issue2841)
Matt Mackall <mpm@selenic.com>
parents: 14484
diff changeset
430 p = os.path.dirname(os.path.dirname(sys.argv[0]))
5867bd6e7cf5 scmutil: improve path calculation for install-relative RC files (issue2841)
Matt Mackall <mpm@selenic.com>
parents: 14484
diff changeset
431 path.extend(rcfiles(os.path.join(p, 'etc/mercurial')))
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
432 path.extend(rcfiles('/etc/mercurial'))
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
433 return path
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
434
14226
73cca883370d rename scmutil.user_rcpath to userrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14225
diff changeset
435 def userrcpath():
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
436 return [os.path.expanduser('~/.hgrc')]
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
437
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
438 else:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
439
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
440 _HKEY_LOCAL_MACHINE = 0x80000002L
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
441
14225
f0ca440b5722 rename scmutil.system_rcpath to systemrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14224
diff changeset
442 def systemrcpath():
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
443 '''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
444 rcpath = []
14236
e949a008999d rename util.executable_path to executablepath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14230
diff changeset
445 filename = util.executablepath()
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
446 # 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
447 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
448 if os.path.isfile(progrc):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
449 rcpath.append(progrc)
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
450 return rcpath
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
451 # 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
452 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
453 if os.path.isdir(progrcd):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
454 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
455 if f.endswith('.rc'):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
456 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
457 return rcpath
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
458 # else look for a system rcpath in the registry
14230
d51630301241 rename util.lookup_reg to lookupreg
Adrian Buehlmann <adrian@cadifra.com>
parents: 14227
diff changeset
459 value = util.lookupreg('SOFTWARE\\Mercurial', None,
d51630301241 rename util.lookup_reg to lookupreg
Adrian Buehlmann <adrian@cadifra.com>
parents: 14227
diff changeset
460 _HKEY_LOCAL_MACHINE)
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
461 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
462 return rcpath
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
463 value = value.replace('/', os.sep)
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
464 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
465 if p.lower().endswith('mercurial.ini'):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
466 rcpath.append(p)
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
467 elif os.path.isdir(p):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
468 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
469 if f.endswith('.rc'):
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
470 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
471 return rcpath
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
472
14226
73cca883370d rename scmutil.user_rcpath to userrcpath
Adrian Buehlmann <adrian@cadifra.com>
parents: 14225
diff changeset
473 def userrcpath():
13986
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
474 '''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
475 home = os.path.expanduser('~')
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
476 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
477 os.path.join(home, '.hgrc')]
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
478 userprofile = os.environ.get('USERPROFILE')
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
479 if userprofile:
9c374cf76b7d move system_rcpath and user_rcpath to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13985
diff changeset
480 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
481 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
482 return path
14319
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
483
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
484 def revsingle(repo, revspec, default='.'):
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
485 if not revspec:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
486 return repo[default]
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
487
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
488 l = revrange(repo, [revspec])
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
489 if len(l) < 1:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
490 raise util.Abort(_('empty revision set'))
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
491 return repo[l[-1]]
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
492
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
493 def revpair(repo, revs):
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
494 if not revs:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
495 return repo.dirstate.p1(), None
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
496
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
497 l = revrange(repo, revs)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
498
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
499 if len(l) == 0:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
500 return repo.dirstate.p1(), None
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
501
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
502 if len(l) == 1:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
503 return repo.lookup(l[0]), None
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
504
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
505 return repo.lookup(l[0]), repo.lookup(l[-1])
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
506
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
507 _revrangesep = ':'
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
508
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
509 def revrange(repo, revs):
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
510 """Yield revision as strings from a list of revision specifications."""
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
511
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
512 def revfix(repo, val, defval):
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
513 if not val and val != 0 and defval is not None:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
514 return defval
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
515 return repo.changelog.rev(repo.lookup(val))
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
516
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
517 seen, l = set(), []
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
518 for spec in revs:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
519 # attempt to parse old-style ranges first to deal with
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
520 # things like old-tag which contain query metacharacters
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
521 try:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
522 if isinstance(spec, int):
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
523 seen.add(spec)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
524 l.append(spec)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
525 continue
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
526
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
527 if _revrangesep in spec:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
528 start, end = spec.split(_revrangesep, 1)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
529 start = revfix(repo, start, 0)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
530 end = revfix(repo, end, len(repo) - 1)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
531 step = start > end and -1 or 1
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
532 for rev in xrange(start, end + step, step):
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
533 if rev in seen:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
534 continue
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
535 seen.add(rev)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
536 l.append(rev)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
537 continue
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
538 elif spec and spec in repo: # single unquoted rev
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
539 rev = revfix(repo, spec, None)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
540 if rev in seen:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
541 continue
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
542 seen.add(rev)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
543 l.append(rev)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
544 continue
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
545 except error.RepoLookupError:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
546 pass
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
547
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
548 # fall through to new-style queries if old-style fails
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
549 m = revset.match(repo.ui, spec)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
550 for r in m(repo, range(len(repo))):
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
551 if r not in seen:
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
552 l.append(r)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
553 seen.update(l)
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
554
b33f3e35efb0 scmutil: move revsingle/pair/range from cmdutil
Matt Mackall <mpm@selenic.com>
parents: 14261
diff changeset
555 return l
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
556
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
557 def expandpats(pats):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
558 if not util.expandglobs:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
559 return list(pats)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
560 ret = []
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
561 for p in pats:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
562 kind, name = matchmod._patsplit(p, None)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
563 if kind is None:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
564 try:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
565 globbed = glob.glob(name)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
566 except re.error:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
567 globbed = [name]
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
568 if globbed:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
569 ret.extend(globbed)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
570 continue
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
571 ret.append(p)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
572 return ret
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
573
14672
785bbc8634f8 scmutil: match no longer accepts repo objects
Matt Mackall <mpm@selenic.com>
parents: 14671
diff changeset
574 def match(ctx, pats=[], opts={}, globbed=False, default='relpath'):
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
575 if pats == ("",):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
576 pats = []
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
577 if not globbed and default == 'relpath':
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
578 pats = expandpats(pats or [])
14670
19197fa4c41c scmutil: match now accepts a context or a repo
Matt Mackall <mpm@selenic.com>
parents: 14669
diff changeset
579
19197fa4c41c scmutil: match now accepts a context or a repo
Matt Mackall <mpm@selenic.com>
parents: 14669
diff changeset
580 m = ctx.match(pats, opts.get('include'), opts.get('exclude'),
14669
2d2604adfdd6 context: add a match builder method
Matt Mackall <mpm@selenic.com>
parents: 14527
diff changeset
581 default)
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
582 def badfn(f, msg):
14671
35c2cc322ba8 scmutil: switch match users to supplying contexts
Matt Mackall <mpm@selenic.com>
parents: 14670
diff changeset
583 ctx._repo.ui.warn("%s: %s\n" % (m.rel(f), msg))
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
584 m.bad = badfn
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
585 return m
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
586
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
587 def matchall(repo):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
588 return matchmod.always(repo.root, repo.getcwd())
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
589
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
590 def matchfiles(repo, files):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
591 return matchmod.exact(repo.root, repo.getcwd(), files)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
592
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
593 def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
594 if dry_run is None:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
595 dry_run = opts.get('dry_run')
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
596 if similarity is None:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
597 similarity = float(opts.get('similarity') or 0)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
598 # we'd use status here, except handling of symlinks and ignore is tricky
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
599 added, unknown, deleted, removed = [], [], [], []
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
600 audit_path = pathauditor(repo.root)
14671
35c2cc322ba8 scmutil: switch match users to supplying contexts
Matt Mackall <mpm@selenic.com>
parents: 14670
diff changeset
601 m = match(repo[None], pats, opts)
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
602 for abs in repo.walk(m):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
603 target = repo.wjoin(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
604 good = True
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
605 try:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
606 audit_path(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
607 except (OSError, util.Abort):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
608 good = False
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
609 rel = m.rel(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
610 exact = m.exact(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
611 if good and abs not in repo.dirstate:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
612 unknown.append(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
613 if repo.ui.verbose or not exact:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
614 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
615 elif repo.dirstate[abs] != 'r' and (not good or not os.path.lexists(target)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
616 or (os.path.isdir(target) and not os.path.islink(target))):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
617 deleted.append(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
618 if repo.ui.verbose or not exact:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
619 repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
620 # for finding renames
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
621 elif repo.dirstate[abs] == 'r':
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
622 removed.append(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
623 elif repo.dirstate[abs] == 'a':
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
624 added.append(abs)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
625 copies = {}
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
626 if similarity > 0:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
627 for old, new, score in similar.findrenames(repo,
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
628 added + unknown, removed + deleted, similarity):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
629 if repo.ui.verbose or not m.exact(old) or not m.exact(new):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
630 repo.ui.status(_('recording removal of %s as rename to %s '
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
631 '(%d%% similar)\n') %
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
632 (m.rel(old), m.rel(new), score * 100))
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
633 copies[new] = old
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
634
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
635 if not dry_run:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
636 wctx = repo[None]
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
637 wlock = repo.wlock()
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
638 try:
14435
5f6090e559fa context: make forget work like commands.forget
Matt Mackall <mpm@selenic.com>
parents: 14404
diff changeset
639 wctx.forget(deleted)
14320
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
640 wctx.add(unknown)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
641 for new, old in copies.iteritems():
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
642 wctx.copy(old, new)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
643 finally:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
644 wlock.release()
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
645
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
646 def updatedir(ui, repo, patches, similarity=0):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
647 '''Update dirstate after patch application according to metadata'''
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
648 if not patches:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
649 return []
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
650 copies = []
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
651 removes = set()
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
652 cfiles = patches.keys()
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
653 cwd = repo.getcwd()
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
654 if cwd:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
655 cfiles = [util.pathto(repo.root, cwd, f) for f in patches.keys()]
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
656 for f in patches:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
657 gp = patches[f]
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
658 if not gp:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
659 continue
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
660 if gp.op == 'RENAME':
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
661 copies.append((gp.oldpath, gp.path))
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
662 removes.add(gp.oldpath)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
663 elif gp.op == 'COPY':
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
664 copies.append((gp.oldpath, gp.path))
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
665 elif gp.op == 'DELETE':
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
666 removes.add(gp.path)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
667
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
668 wctx = repo[None]
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
669 for src, dst in copies:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
670 dirstatecopy(ui, repo, wctx, src, dst, cwd=cwd)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
671 if (not similarity) and removes:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
672 wctx.remove(sorted(removes), True)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
673
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
674 for f in patches:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
675 gp = patches[f]
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
676 if gp and gp.mode:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
677 islink, isexec = gp.mode
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
678 dst = repo.wjoin(gp.path)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
679 # patch won't create empty files
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
680 if gp.op == 'ADD' and not os.path.lexists(dst):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
681 flags = (isexec and 'x' or '') + (islink and 'l' or '')
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
682 repo.wwrite(gp.path, '', flags)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
683 util.setflags(dst, islink, isexec)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
684 addremove(repo, cfiles, similarity=similarity)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
685 files = patches.keys()
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
686 files.extend([r for r in removes if r not in files])
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
687 return sorted(files)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
688
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
689 def dirstatecopy(ui, repo, wctx, src, dst, dryrun=False, cwd=None):
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
690 """Update the dirstate to reflect the intent of copying src to dst. For
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
691 different reasons it might not end with dst being marked as copied from src.
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
692 """
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
693 origsrc = repo.dirstate.copied(src) or src
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
694 if dst == origsrc: # copying back a copy?
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
695 if repo.dirstate[dst] not in 'mn' and not dryrun:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
696 repo.dirstate.normallookup(dst)
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
697 else:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
698 if repo.dirstate[origsrc] == 'a' and origsrc == src:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
699 if not ui.quiet:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
700 ui.warn(_("%s has not been committed yet, so no copy "
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
701 "data will be stored for %s.\n")
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
702 % (repo.pathto(origsrc, cwd), repo.pathto(dst, cwd)))
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
703 if repo.dirstate[dst] in '?r' and not dryrun:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
704 wctx.add([dst])
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
705 elif not dryrun:
3438417a6657 scmutil: fold in wdutil
Matt Mackall <mpm@selenic.com>
parents: 14319
diff changeset
706 wctx.copy(origsrc, dst)
14482
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
707
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
708 def readrequires(opener, supported):
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
709 '''Reads and parses .hg/requires and checks if all entries found
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
710 are in the list of supported features.'''
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
711 requirements = set(opener.read("requires").splitlines())
14746
72e4fcb43227 requirements: show all missing features in the error message.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14720
diff changeset
712 missings = []
14482
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
713 for r in requirements:
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
714 if r not in supported:
14484
4582a4dd1817 requires: note apparent corruption
Matt Mackall <mpm@selenic.com>
parents: 14483
diff changeset
715 if not r or not r[0].isalnum():
4582a4dd1817 requires: note apparent corruption
Matt Mackall <mpm@selenic.com>
parents: 14483
diff changeset
716 raise error.RequirementError(_(".hg/requires file is corrupt"))
14746
72e4fcb43227 requirements: show all missing features in the error message.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14720
diff changeset
717 missings.append(r)
72e4fcb43227 requirements: show all missing features in the error message.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14720
diff changeset
718 missings.sort()
72e4fcb43227 requirements: show all missing features in the error message.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14720
diff changeset
719 if missings:
72e4fcb43227 requirements: show all missing features in the error message.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14720
diff changeset
720 raise error.RequirementError(_("unknown repository format: "
72e4fcb43227 requirements: show all missing features in the error message.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14720
diff changeset
721 "requires features '%s' (upgrade Mercurial)") % "', '".join(missings))
14482
58b36e9ea783 introduce new function scmutil.readrequires
Adrian Buehlmann <adrian@cadifra.com>
parents: 14435
diff changeset
722 return requirements
14928
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
723
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
724 class filecacheentry(object):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
725 def __init__(self, path):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
726 self.path = path
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
727 self.cachestat = filecacheentry.stat(self.path)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
728
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
729 if self.cachestat:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
730 self._cacheable = self.cachestat.cacheable()
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
731 else:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
732 # None means we don't know yet
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
733 self._cacheable = None
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
734
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
735 def refresh(self):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
736 if self.cacheable():
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
737 self.cachestat = filecacheentry.stat(self.path)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
738
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
739 def cacheable(self):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
740 if self._cacheable is not None:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
741 return self._cacheable
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
742
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
743 # we don't know yet, assume it is for now
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
744 return True
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
745
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
746 def changed(self):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
747 # no point in going further if we can't cache it
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
748 if not self.cacheable():
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
749 return True
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
750
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
751 newstat = filecacheentry.stat(self.path)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
752
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
753 # we may not know if it's cacheable yet, check again now
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
754 if newstat and self._cacheable is None:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
755 self._cacheable = newstat.cacheable()
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
756
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
757 # check again
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
758 if not self._cacheable:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
759 return True
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
760
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
761 if self.cachestat != newstat:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
762 self.cachestat = newstat
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
763 return True
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
764 else:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
765 return False
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
766
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
767 @staticmethod
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
768 def stat(path):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
769 try:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
770 return util.cachestat(path)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
771 except OSError, e:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
772 if e.errno != errno.ENOENT:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
773 raise
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
774
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
775 class filecache(object):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
776 '''A property like decorator that tracks a file under .hg/ for updates.
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
777
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
778 Records stat info when called in _filecache.
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
779
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
780 On subsequent calls, compares old stat info with new info, and recreates
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
781 the object when needed, updating the new stat info in _filecache.
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
782
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
783 Mercurial either atomic renames or appends for files under .hg,
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
784 so to ensure the cache is reliable we need the filesystem to be able
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
785 to tell us if a file has been replaced. If it can't, we fallback to
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
786 recreating the object on every call (essentially the same behaviour as
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
787 propertycache).'''
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
788 def __init__(self, path, instore=False):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
789 self.path = path
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
790 self.instore = instore
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
791
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
792 def __call__(self, func):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
793 self.func = func
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
794 self.name = func.__name__
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
795 return self
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
796
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
797 def __get__(self, obj, type=None):
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
798 entry = obj._filecache.get(self.name)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
799
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
800 if entry:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
801 if entry.changed():
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
802 entry.obj = self.func(obj)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
803 else:
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
804 path = self.instore and obj.sjoin(self.path) or obj.join(self.path)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
805
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
806 # We stat -before- creating the object so our cache doesn't lie if
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
807 # a writer modified between the time we read and stat
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
808 entry = filecacheentry(path)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
809 entry.obj = self.func(obj)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
810
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
811 obj._filecache[self.name] = entry
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
812
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
813 setattr(obj, self.name, entry.obj)
dca59d5be12d scmutil: introduce filecache
Idan Kamara <idankk86@gmail.com>
parents: 14861
diff changeset
814 return entry.obj