##// END OF EJS Templates
Merge with BOS
mpm@selenic.com -
r824:0932bc2f merge default
parent child Browse files
Show More
@@ -40,16 +40,24 b' def relpath(repo, 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
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)
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
@@ -565,6 +573,11 b' def debugindexdot(ui, file_):'
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 = []
@@ -1015,9 +1028,10 b' def status(ui, repo, *pats, **opts):'
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()
1019 (c, a, d, u) = repo.changes(files = files, match = matchfn)
1032 files, matchfn = matchpats(cwd, pats, opts)
1020 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
1033 (c, a, d, u) = [[pathto(cwd, x) for x in n]
1034 for n in repo.changes(files=files, match=matchfn)]
1021
1035
1022 for f in c:
1036 for f in c:
1023 ui.write("M ", f, "\n")
1037 ui.write("M ", f, "\n")
@@ -1160,6 +1174,10 b' table = {'
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'),
@@ -440,32 +440,43 b' class dirstate:'
440 dc = self.map.copy()
440 dc = self.map.copy()
441 # walk all files by default
441 # walk all files by default
442 if not files: files = [self.root]
442 if not files: files = [self.root]
443 known = {'.hg': 1}
444 def seen(fn):
445 if fn in known: return True
446 known[fn] = 1
443 def traverse():
447 def traverse():
444 for f in util.unique(files):
448 for f in util.unique(files):
445 f = os.path.join(self.root, f)
449 f = os.path.join(self.root, f)
446 if os.path.isdir(f):
450 if os.path.isdir(f):
447 for dir, subdirs, fl in os.walk(f):
451 for dir, subdirs, fl in os.walk(f):
448 d = dir[len(self.root) + 1:]
452 d = dir[len(self.root) + 1:]
449 if d == '.hg':
453 nd = os.path.normpath(d)
454 if seen(nd):
450 subdirs[:] = []
455 subdirs[:] = []
451 continue
456 continue
452 for sd in subdirs:
457 for sd in subdirs:
453 ds = os.path.join(d, sd +'/')
458 ds = os.path.join(nd, sd +'/')
454 if self.ignore(ds) or not match(ds):
459 if self.ignore(ds) or not match(ds):
455 subdirs.remove(sd)
460 subdirs.remove(sd)
461 subdirs.sort()
462 fl.sort()
456 for fn in fl:
463 for fn in fl:
457 fn = util.pconvert(os.path.join(d, fn))
464 fn = util.pconvert(os.path.join(d, fn))
458 yield 'f', fn
465 yield 'f', fn
459 else:
466 else:
460 yield 'f', f[len(self.root) + 1:]
467 yield 'f', f[len(self.root) + 1:]
461
468
462 for k in dc.keys():
469 ks = dc.keys()
470 ks.sort()
471 for k in ks:
463 yield 'm', k
472 yield 'm', k
464
473
465 # yield only files that match: all in dirstate, others only if
474 # yield only files that match: all in dirstate, others only if
466 # not in .hgignore
475 # not in .hgignore
467
476
468 for src, fn in util.unique(traverse()):
477 for src, fn in util.unique(traverse()):
478 fn = os.path.normpath(fn)
479 if seen(fn): continue
469 if fn in dc:
480 if fn in dc:
470 del dc[fn]
481 del dc[fn]
471 elif self.ignore(fn):
482 elif self.ignore(fn):
@@ -868,7 +879,7 b' class localrepository:'
868 def walk(self, node = None, files = [], match = util.always):
879 def walk(self, node = None, files = [], match = util.always):
869 if node:
880 if node:
870 for fn in self.manifest.read(self.changelog.read(node)[0]):
881 for fn in self.manifest.read(self.changelog.read(node)[0]):
871 yield 'm', fn
882 if match(fn): yield 'm', fn
872 else:
883 else:
873 for src, fn in self.dirstate.walk(files, match):
884 for src, fn in self.dirstate.walk(files, match):
874 yield src, fn
885 yield src, fn
@@ -69,24 +69,27 b" def globre(pat, head = '^', tail = '$'):"
69 _globchars = {'[': 1, '{': 1, '*': 1, '?': 1}
69 _globchars = {'[': 1, '{': 1, '*': 1, '?': 1}
70
70
71 def matcher(cwd, names, inc, exc, head = ''):
71 def matcher(cwd, names, inc, exc, head = ''):
72 def patlike(name):
72 def patkind(name):
73 for prefix in 're:', 'glob:', 'path:':
73 for prefix in 're:', 'glob:', 'path:':
74 if name.startswith(prefix): return True
74 if name.startswith(prefix): return name.split(':', 1)
75 for c in name:
75 for c in name:
76 if c in _globchars: return True
76 if c in _globchars: return 'glob', name
77 return 'relpath', name
78
79 cwdsep = cwd + os.sep
77
80
78 def regex(name, tail):
81 def regex(name, tail):
79 '''convert a pattern into a regular expression'''
82 '''convert a pattern into a regular expression'''
80 if name.startswith('re:'):
83 kind, name = patkind(name)
81 return name[3:]
84 if kind == 're':
82 elif name.startswith('path:'):
85 return name
83 return '^' + re.escape(name[5:]) + '$'
86 elif kind == 'path':
84 elif name.startswith('glob:'):
87 return '^' + re.escape(name) + '$'
85 return head + globre(name[5:], '', tail)
88 if cwd: name = os.path.join(cwdsep, name)
89 name = os.path.normpath(name)
90 if name == '.': name = '**'
86 return head + globre(name, '', tail)
91 return head + globre(name, '', tail)
87
92
88 cwdsep = cwd + os.sep
89
90 def under(fn):
93 def under(fn):
91 """check if fn is under our cwd"""
94 """check if fn is under our cwd"""
92 return not cwd or fn.startswith(cwdsep)
95 return not cwd or fn.startswith(cwdsep)
@@ -95,22 +98,28 b' def matcher(cwd, names, inc, exc, head ='
95 """build a matching function from a set of patterns"""
98 """build a matching function from a set of patterns"""
96 if pats:
99 if pats:
97 pat = '(?:%s)' % '|'.join([regex(p, tail) for p in pats])
100 pat = '(?:%s)' % '|'.join([regex(p, tail) for p in pats])
98 if cwd:
99 pat = re.escape(cwdsep) + pat
100 return re.compile(pat).match
101 return re.compile(pat).match
101
102
102 pats = filter(patlike, names)
103 def globprefix(pat):
103 files = [n for n in names if not patlike(n)]
104 '''return the non-glob prefix of a path, e.g. foo/* -> foo'''
104 if pats: plain = []
105 root = []
105 elif cwd: plain = [cwdsep + f for f in files]
106 for p in pat.split(os.sep):
106 else: plain = files
107 if patkind(p)[0] == 'glob': break
108 root.append(p)
109 return os.sep.join(root)
110
111 patkinds = map(patkind, names)
112 pats = [name for (kind, name) in patkinds if kind != 'relpath']
113 files = [name for (kind, name) in patkinds if kind == 'relpath']
114 roots = filter(None, map(globprefix, pats)) + files
115 if cwd: roots = [cwdsep + r for r in roots]
107
116
108 patmatch = matchfn(pats, '$')
117 patmatch = matchfn(pats, '$') or always
109 filematch = matchfn(files, '(?:/|$)')
118 filematch = matchfn(files, '(?:/|$)') or always
110 incmatch = matchfn(inc, '(?:/|$)') or under
119 incmatch = matchfn(inc, '(?:/|$)') or always
111 excmatch = matchfn(exc, '(?:/|$)') or (lambda fn: False)
120 excmatch = matchfn(exc, '(?:/|$)') or (lambda fn: False)
112
121
113 return plain, lambda fn: (incmatch(fn) and not excmatch(fn) and
122 return roots, lambda fn: (incmatch(fn) and not excmatch(fn) and
114 (fn.endswith('/') or
123 (fn.endswith('/') or
115 (not pats and not files) or
124 (not pats and not files) or
116 (pats and patmatch(fn)) or
125 (pats and patmatch(fn)) or
@@ -9,4 +9,4 b' removing b'
9 this update spans a branch affecting the following files:
9 this update spans a branch affecting the following files:
10 b
10 b
11 aborting update spanning branches!
11 aborting update spanning branches!
12 (use update -m to perform a branch merge)
12 (use update -m to merge across branches or -C to lose changes)
General Comments 0
You need to be logged in to leave comments. Login now