comparison mercurial/commands.py @ 820:89985a1b3427

Clean up walk and changes code to use normalised names properly. New function: commands.pathto returns the relative path from one path to another. For example, given foo/bar and baz/quux, it will return ../../baz/quux. This new function is used by the walk and status code to print relative paths correctly. New command: debugwalk exercises the walk code without doing anything more. hg.dirstate.walk now yields normalised names. For example, if you're in the baz directory and you ask it to walk ../foo/bar/.., it will yield names starting with foo/. As a result of this change, all of the other walk and changes methods in this module also return normalised names. The util.matcher function now normalises globs and path names, so that it will match normalised names properly. Finally, util.matcher uses the non-glob prefix of a glob to tell walk which directories to scan. Perviously, a glob like foo/* would scan everything, but only return matches for foo/*. Now, foo/* only scans under foo (using the globprefix function), which is much faster.
author Bryan O'Sullivan <bos@serpentine.com>
date Sun, 31 Jul 2005 17:42:46 -0800
parents 5a55e3011772
children f0446f6963d2
comparison
equal deleted inserted replaced
819:77e121a0d870 820:89985a1b3427
38 return [util.pconvert(os.path.normpath(os.path.join(cwd, x))) 38 return [util.pconvert(os.path.normpath(os.path.join(cwd, x)))
39 for x in args] 39 for x in args]
40 return args 40 return args
41 41
42 def matchpats(cwd, pats = [], opts = {}, head = ''): 42 def matchpats(cwd, pats = [], opts = {}, head = ''):
43 return util.matcher(cwd, pats, opts.get('include'), 43 return util.matcher(cwd, pats or ['.'], opts.get('include'),
44 opts.get('exclude'), head) 44 opts.get('exclude'), head)
45
46 def pathto(n1, n2):
47 '''return the relative path from one place to another'''
48 if not n1: return n2
49 a, b = n1.split(os.sep), n2.split(os.sep)
50 a.reverse(), b.reverse()
51 while a and b and a[-1] == b[-1]:
52 a.pop(), b.pop()
53 b.reverse()
54 return os.sep.join((['..'] * len(a)) + b)
45 55
46 def walk(repo, pats, opts, head = ''): 56 def walk(repo, pats, opts, head = ''):
47 cwd = repo.getcwd() 57 cwd = repo.getcwd()
48 c = 0
49 if cwd: c = len(cwd) + 1
50 files, matchfn = matchpats(cwd, pats, opts, head) 58 files, matchfn = matchpats(cwd, pats, opts, head)
51 for src, fn in repo.walk(files = files, match = matchfn): 59 for src, fn in repo.walk(files = files, match = matchfn):
52 yield src, fn, fn[c:] 60 yield src, fn, pathto(cwd, fn)
53 61
54 revrangesep = ':' 62 revrangesep = ':'
55 63
56 def revrange(ui, repo, revs, revlog=None): 64 def revrange(ui, repo, revs, revlog=None):
57 if revlog is None: 65 if revlog is None:
563 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i)) 571 ui.write("\t%d -> %d\n" % (r.rev(e[4]), i))
564 if e[5] != hg.nullid: 572 if e[5] != hg.nullid:
565 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i)) 573 ui.write("\t%d -> %d\n" % (r.rev(e[5]), i))
566 ui.write("}\n") 574 ui.write("}\n")
567 575
576 def debugwalk(ui, repo, *pats, **opts):
577 items = list(walk(repo, pats, opts))
578 fmt = '%%s %%-%ds %%s' % max([len(abs) for (src, abs, rel) in items])
579 for i in items: print fmt % i
580
568 def diff(ui, repo, *pats, **opts): 581 def diff(ui, repo, *pats, **opts):
569 """diff working directory (or selected files)""" 582 """diff working directory (or selected files)"""
570 revs = [] 583 revs = []
571 if opts['rev']: 584 if opts['rev']:
572 revs = map(lambda x: repo.lookup(x), opts['rev']) 585 revs = map(lambda x: repo.lookup(x), opts['rev'])
1013 M = modified 1026 M = modified
1014 A = added 1027 A = added
1015 R = removed 1028 R = removed
1016 ? = not tracked''' 1029 ? = not tracked'''
1017 1030
1018 files, matchfn = matchpats(repo.getcwd(), pats, opts) 1031 cwd = repo.getcwd()
1032 files, matchfn = matchpats(cwd, pats, opts)
1019 (c, a, d, u) = repo.changes(files = files, match = matchfn) 1033 (c, a, d, u) = repo.changes(files = files, match = matchfn)
1020 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u)) 1034 (c, a, d, u) = [map(lambda x: pathto(cwd, x), n) for n in c, a, d, u]
1021 1035
1022 for f in c: 1036 for f in c:
1023 ui.write("M ", f, "\n") 1037 ui.write("M ", f, "\n")
1024 for f in a: 1038 for f in a:
1025 ui.write("A ", f, "\n") 1039 ui.write("A ", f, "\n")
1158 "copy": (copy, [], 'hg copy SOURCE DEST'), 1172 "copy": (copy, [], 'hg copy SOURCE DEST'),
1159 "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'), 1173 "debugcheckstate": (debugcheckstate, [], 'debugcheckstate'),
1160 "debugstate": (debugstate, [], 'debugstate'), 1174 "debugstate": (debugstate, [], 'debugstate'),
1161 "debugindex": (debugindex, [], 'debugindex FILE'), 1175 "debugindex": (debugindex, [], 'debugindex FILE'),
1162 "debugindexdot": (debugindexdot, [], 'debugindexdot FILE'), 1176 "debugindexdot": (debugindexdot, [], 'debugindexdot FILE'),
1177 "debugwalk": (debugwalk,
1178 [('I', 'include', [], 'include path in search'),
1179 ('X', 'exclude', [], 'exclude path from search')],
1180 'debugwalk [OPTIONS]... [FILE]...'),
1163 "^diff": 1181 "^diff":
1164 (diff, 1182 (diff,
1165 [('r', 'rev', [], 'revision'), 1183 [('r', 'rev', [], 'revision'),
1166 ('I', 'include', [], 'include path in search'), 1184 ('I', 'include', [], 'include path in search'),
1167 ('X', 'exclude', [], 'exclude path from search')], 1185 ('X', 'exclude', [], 'exclude path from search')],