##// END OF EJS Templates
Teach walk code about absolute paths....
Bryan O'Sullivan -
r870:a82eae84 default
parent child Browse files
Show More
@@ -14,9 +14,6 b' demandload(globals(), "errno socket vers'
14 class UnknownCommand(Exception):
14 class UnknownCommand(Exception):
15 """Exception raised if command is not in the command table."""
15 """Exception raised if command is not in the command table."""
16
16
17 class Abort(Exception):
18 """Raised if a command needs to print an error and exit."""
19
20 def filterfiles(filters, files):
17 def filterfiles(filters, files):
21 l = [x for x in files if x in filters]
18 l = [x for x in files if x in filters]
22
19
@@ -39,8 +36,8 b' def relpath(repo, args):'
39 for x in args]
36 for x in args]
40 return args
37 return args
41
38
42 def matchpats(cwd, pats = [], opts = {}, head = ''):
39 def matchpats(repo, cwd, pats = [], opts = {}, head = ''):
43 return util.matcher(cwd, pats or ['.'], opts.get('include'),
40 return util.matcher(repo, cwd, pats or ['.'], opts.get('include'),
44 opts.get('exclude'), head)
41 opts.get('exclude'), head)
45
42
46 def pathto(n1, n2):
43 def pathto(n1, n2):
@@ -55,7 +52,7 b' def pathto(n1, n2):'
55
52
56 def makewalk(repo, pats, opts, head = ''):
53 def makewalk(repo, pats, opts, head = ''):
57 cwd = repo.getcwd()
54 cwd = repo.getcwd()
58 files, matchfn = matchpats(cwd, pats, opts, head)
55 files, matchfn = matchpats(repo, cwd, pats, opts, head)
59 def walk():
56 def walk():
60 for src, fn in repo.walk(files = files, match = matchfn):
57 for src, fn in repo.walk(files = files, match = matchfn):
61 yield src, fn, pathto(cwd, fn)
58 yield src, fn, pathto(cwd, fn)
@@ -89,7 +86,7 b' def revrange(ui, repo, revs, revlog=None'
89 try:
86 try:
90 num = revlog.rev(revlog.lookup(val))
87 num = revlog.rev(revlog.lookup(val))
91 except KeyError:
88 except KeyError:
92 raise Abort('invalid revision identifier %s', val)
89 raise util.Abort('invalid revision identifier %s', val)
93 return num
90 return num
94 for spec in revs:
91 for spec in revs:
95 if spec.find(revrangesep) >= 0:
92 if spec.find(revrangesep) >= 0:
@@ -144,7 +141,7 b' def make_filename(repo, r, pat, node=Non'
144 i += 1
141 i += 1
145 return ''.join(newname)
142 return ''.join(newname)
146 except KeyError, inst:
143 except KeyError, inst:
147 raise Abort("invalid format spec '%%%s' in output file name",
144 raise util.Abort("invalid format spec '%%%s' in output file name",
148 inst.args[0])
145 inst.args[0])
149
146
150 def make_file(repo, r, pat, node=None,
147 def make_file(repo, r, pat, node=None,
@@ -387,7 +384,7 b' def annotate(ui, repo, *pats, **opts):'
387 return name
384 return name
388
385
389 if not pats:
386 if not pats:
390 raise Abort('at least one file name or pattern required')
387 raise util.Abort('at least one file name or pattern required')
391
388
392 bcache = {}
389 bcache = {}
393 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
390 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
@@ -501,7 +498,7 b' def commit(ui, repo, *pats, **opts):'
501 if not pats and cwd:
498 if not pats and cwd:
502 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
499 opts['include'] = [os.path.join(cwd, i) for i in opts['include']]
503 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
500 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']]
504 fns, match = matchpats((pats and repo.getcwd()) or '', pats, opts)
501 fns, match = matchpats(repo, (pats and repo.getcwd()) or '', pats, opts)
505 if pats:
502 if pats:
506 c, a, d, u = repo.changes(files = fns, match = match)
503 c, a, d, u = repo.changes(files = fns, match = match)
507 files = c + a + [fn for fn in d if repo.dirstate.state(fn) == 'r']
504 files = c + a + [fn for fn in d if repo.dirstate.state(fn) == 'r']
@@ -543,7 +540,7 b' def debugcheckstate(ui, repo):'
543 ui.warn("%s in manifest1, but listed as state %s" % (f, state))
540 ui.warn("%s in manifest1, but listed as state %s" % (f, state))
544 errors += 1
541 errors += 1
545 if errors:
542 if errors:
546 raise Abort(".hg/dirstate inconsistent with current parent's manifest")
543 raise util.Abort(".hg/dirstate inconsistent with current parent's manifest")
547
544
548 def debugstate(ui, repo):
545 def debugstate(ui, repo):
549 """show the contents of the current dirstate"""
546 """show the contents of the current dirstate"""
@@ -592,7 +589,7 b' def diff(ui, repo, *pats, **opts):'
592 revs = map(lambda x: repo.lookup(x), opts['rev'])
589 revs = map(lambda x: repo.lookup(x), opts['rev'])
593
590
594 if len(revs) > 2:
591 if len(revs) > 2:
595 raise Abort("too many revisions to diff")
592 raise util.Abort("too many revisions to diff")
596
593
597 files = []
594 files = []
598 roots, match, results = makewalk(repo, pats, opts)
595 roots, match, results = makewalk(repo, pats, opts)
@@ -626,7 +623,7 b' def doexport(ui, repo, changeset, seqno,'
626 def export(ui, repo, *changesets, **opts):
623 def export(ui, repo, *changesets, **opts):
627 """dump the header and diffs for one or more changesets"""
624 """dump the header and diffs for one or more changesets"""
628 if not changesets:
625 if not changesets:
629 raise Abort("export requires at least one changeset")
626 raise util.Abort("export requires at least one changeset")
630 seqno = 0
627 seqno = 0
631 revs = list(revrange(ui, repo, changesets))
628 revs = list(revrange(ui, repo, changesets))
632 total = len(revs)
629 total = len(revs)
@@ -722,7 +719,7 b' def import_(ui, repo, patch1, *patches, '
722 files.append(pf)
719 files.append(pf)
723 patcherr = f.close()
720 patcherr = f.close()
724 if patcherr:
721 if patcherr:
725 raise Abort("patch failed")
722 raise util.Abort("patch failed")
726
723
727 if len(files) > 0:
724 if len(files) > 0:
728 addremove(ui, repo, *files)
725 addremove(ui, repo, *files)
@@ -732,7 +729,7 b' def init(ui, source=None):'
732 """create a new repository in the current directory"""
729 """create a new repository in the current directory"""
733
730
734 if source:
731 if source:
735 raise Abort("no longer supported: use \"hg clone\" instead")
732 raise util.Abort("no longer supported: use \"hg clone\" instead")
736 hg.repository(ui, ".", create=1)
733 hg.repository(ui, ".", create=1)
737
734
738 def locate(ui, repo, *pats, **opts):
735 def locate(ui, repo, *pats, **opts):
@@ -1037,7 +1034,7 b' def status(ui, repo, *pats, **opts):'
1037 ? = not tracked'''
1034 ? = not tracked'''
1038
1035
1039 cwd = repo.getcwd()
1036 cwd = repo.getcwd()
1040 files, matchfn = matchpats(cwd, pats, opts)
1037 files, matchfn = matchpats(repo, cwd, pats, opts)
1041 (c, a, d, u) = [[pathto(cwd, x) for x in n]
1038 (c, a, d, u) = [[pathto(cwd, x) for x in n]
1042 for n in repo.changes(files=files, match=matchfn)]
1039 for n in repo.changes(files=files, match=matchfn)]
1043
1040
@@ -1420,8 +1417,6 b' def dispatch(args):'
1420 if options['traceback']:
1417 if options['traceback']:
1421 traceback.print_exc()
1418 traceback.print_exc()
1422 raise
1419 raise
1423 except util.CommandError, inst:
1424 u.warn("abort: %s\n" % inst.args)
1425 except hg.RepoError, inst:
1420 except hg.RepoError, inst:
1426 u.warn("abort: ", inst, "!\n")
1421 u.warn("abort: ", inst, "!\n")
1427 except SignalInterrupt:
1422 except SignalInterrupt:
@@ -1449,7 +1444,7 b' def dispatch(args):'
1449 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename))
1444 u.warn("abort: %s: %s\n" % (inst.strerror, inst.filename))
1450 else:
1445 else:
1451 u.warn("abort: %s\n" % inst.strerror)
1446 u.warn("abort: %s\n" % inst.strerror)
1452 except Abort, inst:
1447 except util.Abort, inst:
1453 u.warn('abort: ', inst.args[0] % inst.args[1:], '\n')
1448 u.warn('abort: ', inst.args[0] % inst.args[1:], '\n')
1454 sys.exit(1)
1449 sys.exit(1)
1455 except TypeError, inst:
1450 except TypeError, inst:
@@ -300,6 +300,11 b' class dirstate:'
300 def wjoin(self, f):
300 def wjoin(self, f):
301 return os.path.join(self.root, f)
301 return os.path.join(self.root, f)
302
302
303 def getcwd(self):
304 cwd = os.getcwd()
305 if cwd == self.root: return ''
306 return cwd[len(self.root) + 1:]
307
303 def ignore(self, f):
308 def ignore(self, f):
304 if not self.ignorefunc:
309 if not self.ignorefunc:
305 bigpat = []
310 bigpat = []
@@ -687,9 +692,7 b' class localrepository:'
687 return filelog(self.opener, f)
692 return filelog(self.opener, f)
688
693
689 def getcwd(self):
694 def getcwd(self):
690 cwd = os.getcwd()
695 return self.dirstate.getcwd()
691 if cwd == self.root: return ''
692 return cwd[len(self.root) + 1:]
693
696
694 def wfile(self, f, mode='r'):
697 def wfile(self, f, mode='r'):
695 return self.wopener(f, mode)
698 return self.wopener(f, mode)
@@ -16,7 +16,8 b' def unique(g):'
16 seen[f] = 1
16 seen[f] = 1
17 yield f
17 yield f
18
18
19 class CommandError(Exception): pass
19 class Abort(Exception):
20 """Raised if a command needs to print an error and exit."""
20
21
21 def always(fn): return True
22 def always(fn): return True
22 def never(fn): return False
23 def never(fn): return False
@@ -68,7 +69,20 b" def globre(pat, head = '^', tail = '$'):"
68
69
69 _globchars = {'[': 1, '{': 1, '*': 1, '?': 1}
70 _globchars = {'[': 1, '{': 1, '*': 1, '?': 1}
70
71
71 def matcher(cwd, names, inc, exc, head = ''):
72 def canonpath(repo, cwd, myname):
73 rootsep = repo.root + os.sep
74 name = myname
75 if not name.startswith(os.sep):
76 name = os.path.join(repo.root, cwd, name)
77 name = os.path.normpath(name)
78 if name.startswith(rootsep):
79 return name[len(rootsep):]
80 elif name == repo.root:
81 return ''
82 else:
83 raise Abort('%s not under repository root' % myname)
84
85 def matcher(repo, cwd, names, inc, exc, head = ''):
72 def patkind(name):
86 def patkind(name):
73 for prefix in 're:', 'glob:', 'path:':
87 for prefix in 're:', 'glob:', 'path:':
74 if name.startswith(prefix): return name.split(':', 1)
88 if name.startswith(prefix): return name.split(':', 1)
@@ -76,8 +90,6 b' def matcher(cwd, names, inc, exc, head ='
76 if c in _globchars: return 'glob', name
90 if c in _globchars: return 'glob', name
77 return 'relpath', name
91 return 'relpath', name
78
92
79 cwdsep = cwd + os.sep
80
81 def regex(name, tail):
93 def regex(name, tail):
82 '''convert a pattern into a regular expression'''
94 '''convert a pattern into a regular expression'''
83 kind, name = patkind(name)
95 kind, name = patkind(name)
@@ -85,9 +97,6 b' def matcher(cwd, names, inc, exc, head ='
85 return name
97 return name
86 elif kind == 'path':
98 elif kind == 'path':
87 return '^' + re.escape(name) + '$'
99 return '^' + re.escape(name) + '$'
88 if cwd: name = os.path.join(cwdsep, name)
89 name = os.path.normpath(name)
90 if name == '.': name = '**'
91 return head + globre(name, '', tail)
100 return head + globre(name, '', tail)
92
101
93 def matchfn(pats, tail):
102 def matchfn(pats, tail):
@@ -104,11 +113,22 b' def matcher(cwd, names, inc, exc, head ='
104 root.append(p)
113 root.append(p)
105 return os.sep.join(root)
114 return os.sep.join(root)
106
115
107 patkinds = map(patkind, names)
116 pats = []
108 pats = [name for (kind, name) in patkinds if kind != 'relpath']
117 files = []
109 files = [name for (kind, name) in patkinds if kind == 'relpath']
118 roots = []
110 roots = filter(None, map(globprefix, pats)) + files
119 for kind, name in map(patkind, names):
111 if cwd: roots = [cwdsep + r for r in roots]
120 if kind in ('glob', 'relpath'):
121 name = canonpath(repo, cwd, name)
122 if name == '':
123 kind, name = 'glob', '**'
124 if kind in ('glob', 're'):
125 pats.append(name)
126 if kind == 'glob':
127 root = globprefix(name)
128 if root: roots.append(root)
129 elif kind == 'relpath':
130 files.append(name)
131 roots.append(name)
112
132
113 patmatch = matchfn(pats, '$') or always
133 patmatch = matchfn(pats, '$') or always
114 filematch = matchfn(files, '(?:/|$)') or always
134 filematch = matchfn(files, '(?:/|$)') or always
@@ -129,7 +149,7 b' def system(cmd, errprefix=None):'
129 explain_exit(rc)[0])
149 explain_exit(rc)[0])
130 if errprefix:
150 if errprefix:
131 errmsg = "%s: %s" % (errprefix, errmsg)
151 errmsg = "%s: %s" % (errprefix, errmsg)
132 raise CommandError(errmsg)
152 raise Abort(errmsg)
133
153
134 def rename(src, dst):
154 def rename(src, dst):
135 try:
155 try:
General Comments 0
You need to be logged in to leave comments. Login now