Show More
@@ -502,7 +502,7 b' class queue:' | |||||
502 | if opts.get('rev'): |
|
502 | if opts.get('rev'): | |
503 | if not self.applied: |
|
503 | if not self.applied: | |
504 | raise util.Abort(_('no patches applied')) |
|
504 | raise util.Abort(_('no patches applied')) | |
505 |
revs = |
|
505 | revs = cmdutil.revrange(ui, repo, opts['rev']) | |
506 | if len(revs) > 1 and revs[0] > revs[1]: |
|
506 | if len(revs) > 1 and revs[0] > revs[1]: | |
507 | revs.reverse() |
|
507 | revs.reverse() | |
508 | for rev in revs: |
|
508 | for rev in revs: | |
@@ -1015,9 +1015,9 b' class queue:' | |||||
1015 | del mm[mm.index(x)] |
|
1015 | del mm[mm.index(x)] | |
1016 | dd.append(x) |
|
1016 | dd.append(x) | |
1017 |
|
1017 | |||
1018 |
m = |
|
1018 | m = util.unique(mm) | |
1019 |
r = |
|
1019 | r = util.unique(dd) | |
1020 |
a = |
|
1020 | a = util.unique(aa) | |
1021 | filelist = filter(matchfn, util.unique(m + r + a)) |
|
1021 | filelist = filter(matchfn, util.unique(m + r + a)) | |
1022 | if opts.get('git'): |
|
1022 | if opts.get('git'): | |
1023 | self.diffopts().git = True |
|
1023 | self.diffopts().git = True | |
@@ -1276,7 +1276,7 b' class queue:' | |||||
1276 | if files: |
|
1276 | if files: | |
1277 | raise util.Abort(_('option "-r" not valid when importing ' |
|
1277 | raise util.Abort(_('option "-r" not valid when importing ' | |
1278 | 'files')) |
|
1278 | 'files')) | |
1279 |
rev = |
|
1279 | rev = cmdutil.revrange(self.ui, repo, rev) | |
1280 | rev.sort(lambda x, y: cmp(y, x)) |
|
1280 | rev.sort(lambda x, y: cmp(y, x)) | |
1281 | if (len(files) > 1 or len(rev) > 1) and patchname: |
|
1281 | if (len(files) > 1 or len(rev) > 1) and patchname: | |
1282 | raise util.Abort(_('option "-n" not valid when importing multiple ' |
|
1282 | raise util.Abort(_('option "-n" not valid when importing multiple ' |
@@ -13,43 +13,25 b" demandload(globals(), 'os sys')" | |||||
13 |
|
13 | |||
14 | revrangesep = ':' |
|
14 | revrangesep = ':' | |
15 |
|
15 | |||
16 | def revfix(repo, val, defval): |
|
|||
17 | '''turn user-level id of changeset into rev number. |
|
|||
18 | user-level id can be tag, changeset, rev number, or negative rev |
|
|||
19 | number relative to number of revs (-1 is tip, etc).''' |
|
|||
20 | if not val: |
|
|||
21 | return defval |
|
|||
22 | try: |
|
|||
23 | num = int(val) |
|
|||
24 | if str(num) != val: |
|
|||
25 | raise ValueError |
|
|||
26 | if num < 0: |
|
|||
27 | num += repo.changelog.count() |
|
|||
28 | if num < 0: |
|
|||
29 | num = 0 |
|
|||
30 | elif num >= repo.changelog.count(): |
|
|||
31 | raise ValueError |
|
|||
32 | except ValueError: |
|
|||
33 | try: |
|
|||
34 | num = repo.changelog.rev(repo.lookup(val)) |
|
|||
35 | except KeyError: |
|
|||
36 | raise util.Abort(_('invalid revision identifier %s') % val) |
|
|||
37 | return num |
|
|||
38 |
|
||||
39 | def revpair(ui, repo, revs): |
|
16 | def revpair(ui, repo, revs): | |
40 | '''return pair of nodes, given list of revisions. second item can |
|
17 | '''return pair of nodes, given list of revisions. second item can | |
41 | be None, meaning use working dir.''' |
|
18 | be None, meaning use working dir.''' | |
|
19 | ||||
|
20 | def revfix(repo, val, defval): | |||
|
21 | if not val and val != 0: | |||
|
22 | val = defval | |||
|
23 | return repo.lookup(val) | |||
|
24 | ||||
42 | if not revs: |
|
25 | if not revs: | |
43 | return repo.dirstate.parents()[0], None |
|
26 | return repo.dirstate.parents()[0], None | |
44 | end = None |
|
27 | end = None | |
45 | if len(revs) == 1: |
|
28 | if len(revs) == 1: | |
46 |
|
|
29 | if revrangesep in revs[0]: | |
47 | if revrangesep in start: |
|
30 | start, end = revs[0].split(revrangesep, 1) | |
48 | start, end = start.split(revrangesep, 1) |
|
|||
49 | start = revfix(repo, start, 0) |
|
31 | start = revfix(repo, start, 0) | |
50 | end = revfix(repo, end, repo.changelog.count() - 1) |
|
32 | end = revfix(repo, end, repo.changelog.count() - 1) | |
51 | else: |
|
33 | else: | |
52 |
start = revfix(repo, |
|
34 | start = revfix(repo, revs[0], None) | |
53 | elif len(revs) == 2: |
|
35 | elif len(revs) == 2: | |
54 | if revrangesep in revs[0] or revrangesep in revs[1]: |
|
36 | if revrangesep in revs[0] or revrangesep in revs[1]: | |
55 | raise util.Abort(_('too many revisions specified')) |
|
37 | raise util.Abort(_('too many revisions specified')) | |
@@ -57,12 +39,17 b' def revpair(ui, repo, revs):' | |||||
57 | end = revfix(repo, revs[1], None) |
|
39 | end = revfix(repo, revs[1], None) | |
58 | else: |
|
40 | else: | |
59 | raise util.Abort(_('too many revisions specified')) |
|
41 | raise util.Abort(_('too many revisions specified')) | |
60 | if end is not None: end = repo.lookup(str(end)) |
|
42 | return start, end | |
61 | return repo.lookup(str(start)), end |
|
|||
62 |
|
43 | |||
63 | def revrange(ui, repo, revs): |
|
44 | def revrange(ui, repo, revs): | |
64 | """Yield revision as strings from a list of revision specifications.""" |
|
45 | """Yield revision as strings from a list of revision specifications.""" | |
65 | seen = {} |
|
46 | ||
|
47 | def revfix(repo, val, defval): | |||
|
48 | if not val and val != 0: | |||
|
49 | return defval | |||
|
50 | return repo.changelog.rev(repo.lookup(val)) | |||
|
51 | ||||
|
52 | seen, l = {}, [] | |||
66 | for spec in revs: |
|
53 | for spec in revs: | |
67 | if revrangesep in spec: |
|
54 | if revrangesep in spec: | |
68 | start, end = spec.split(revrangesep, 1) |
|
55 | start, end = spec.split(revrangesep, 1) | |
@@ -73,13 +60,15 b' def revrange(ui, repo, revs):' | |||||
73 | if rev in seen: |
|
60 | if rev in seen: | |
74 | continue |
|
61 | continue | |
75 | seen[rev] = 1 |
|
62 | seen[rev] = 1 | |
76 |
|
|
63 | l.append(rev) | |
77 | else: |
|
64 | else: | |
78 | rev = revfix(repo, spec, None) |
|
65 | rev = revfix(repo, spec, None) | |
79 | if rev in seen: |
|
66 | if rev in seen: | |
80 | continue |
|
67 | continue | |
81 | seen[rev] = 1 |
|
68 | seen[rev] = 1 | |
82 |
|
|
69 | l.append(rev) | |
|
70 | ||||
|
71 | return l | |||
83 |
|
72 | |||
84 | def make_filename(repo, pat, node, |
|
73 | def make_filename(repo, pat, node, | |
85 | total=None, seqno=None, revwidth=None, pathname=None): |
|
74 | total=None, seqno=None, revwidth=None, pathname=None): | |
@@ -149,19 +138,12 b' def matchpats(repo, pats=[], opts={}, he' | |||||
149 | return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'), |
|
138 | return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'), | |
150 | opts.get('exclude'), head) |
|
139 | opts.get('exclude'), head) | |
151 |
|
140 | |||
152 |
def |
|
141 | def walk(repo, pats=[], opts={}, node=None, head='', badmatch=None): | |
153 | files, matchfn, anypats = matchpats(repo, pats, opts, head) |
|
142 | files, matchfn, anypats = matchpats(repo, pats, opts, head) | |
154 |
exact = dict |
|
143 | exact = dict.fromkeys(files) | |
155 | def walk(): |
|
|||
156 |
|
|
144 | for src, fn in repo.walk(node=node, files=files, match=matchfn, | |
157 |
|
|
145 | badmatch=badmatch): | |
158 |
|
|
146 | yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact | |
159 | return files, matchfn, walk() |
|
|||
160 |
|
||||
161 | def walk(repo, pats=[], opts={}, node=None, head='', badmatch=None): |
|
|||
162 | files, matchfn, results = makewalk(repo, pats, opts, node, head, badmatch) |
|
|||
163 | for r in results: |
|
|||
164 | yield r |
|
|||
165 |
|
147 | |||
166 | def findrenames(repo, added=None, removed=None, threshold=0.5): |
|
148 | def findrenames(repo, added=None, removed=None, threshold=0.5): | |
167 | if added is None or removed is None: |
|
149 | if added is None or removed is None: |
@@ -50,7 +50,7 b' def logmessage(opts):' | |||||
50 | (logfile, inst.strerror)) |
|
50 | (logfile, inst.strerror)) | |
51 | return message |
|
51 | return message | |
52 |
|
52 | |||
53 | def walkchangerevs(ui, repo, pats, opts): |
|
53 | def walkchangerevs(ui, repo, pats, change, opts): | |
54 | '''Iterate over files and the revs they changed in. |
|
54 | '''Iterate over files and the revs they changed in. | |
55 |
|
55 | |||
56 | Callers most commonly need to iterate backwards over the history |
|
56 | Callers most commonly need to iterate backwards over the history | |
@@ -61,10 +61,8 b' def walkchangerevs(ui, repo, pats, opts)' | |||||
61 | window, we first walk forwards to gather data, then in the desired |
|
61 | window, we first walk forwards to gather data, then in the desired | |
62 | order (usually backwards) to display it. |
|
62 | order (usually backwards) to display it. | |
63 |
|
63 | |||
64 |
This function returns an (iterator, |
|
64 | This function returns an (iterator, matchfn) tuple. The iterator | |
65 | getchange function returns the changelog entry for a numeric |
|
65 | yields 3-tuples. They will be of one of the following forms: | |
66 | revision. The iterator yields 3-tuples. They will be of one of |
|
|||
67 | the following forms: |
|
|||
68 |
|
66 | |||
69 | "window", incrementing, lastrev: stepping through a window, |
|
67 | "window", incrementing, lastrev: stepping through a window, | |
70 | positive if walking forwards through revs, last rev in the |
|
68 | positive if walking forwards through revs, last rev in the | |
@@ -91,32 +89,24 b' def walkchangerevs(ui, repo, pats, opts)' | |||||
91 | if windowsize < sizelimit: |
|
89 | if windowsize < sizelimit: | |
92 | windowsize *= 2 |
|
90 | windowsize *= 2 | |
93 |
|
91 | |||
94 |
|
||||
95 | files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) |
|
92 | files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) | |
96 | follow = opts.get('follow') or opts.get('follow_first') |
|
93 | follow = opts.get('follow') or opts.get('follow_first') | |
97 |
|
94 | |||
98 | if repo.changelog.count() == 0: |
|
95 | if repo.changelog.count() == 0: | |
99 |
return [], |
|
96 | return [], matchfn | |
100 |
|
97 | |||
101 | if follow: |
|
98 | if follow: | |
102 | defrange = '%s:0' % repo.changectx().rev() |
|
99 | defrange = '%s:0' % repo.changectx().rev() | |
103 | else: |
|
100 | else: | |
104 | defrange = 'tip:0' |
|
101 | defrange = 'tip:0' | |
105 |
revs = |
|
102 | revs = cmdutil.revrange(ui, repo, opts['rev'] or [defrange]) | |
106 | wanted = {} |
|
103 | wanted = {} | |
107 | slowpath = anypats |
|
104 | slowpath = anypats | |
108 | fncache = {} |
|
105 | fncache = {} | |
109 |
|
106 | |||
110 | chcache = {} |
|
|||
111 | def getchange(rev): |
|
|||
112 | ch = chcache.get(rev) |
|
|||
113 | if ch is None: |
|
|||
114 | chcache[rev] = ch = repo.changelog.read(repo.lookup(str(rev))) |
|
|||
115 | return ch |
|
|||
116 |
|
||||
117 | if not slowpath and not files: |
|
107 | if not slowpath and not files: | |
118 | # No files, no patterns. Display all revs. |
|
108 | # No files, no patterns. Display all revs. | |
119 |
wanted = dict |
|
109 | wanted = dict.fromkeys(revs) | |
120 | copies = [] |
|
110 | copies = [] | |
121 | if not slowpath: |
|
111 | if not slowpath: | |
122 | # Only files, no patterns. Check the history of each file. |
|
112 | # Only files, no patterns. Check the history of each file. | |
@@ -169,7 +159,7 b' def walkchangerevs(ui, repo, pats, opts)' | |||||
169 | def changerevgen(): |
|
159 | def changerevgen(): | |
170 | for i, window in increasing_windows(repo.changelog.count()-1, -1): |
|
160 | for i, window in increasing_windows(repo.changelog.count()-1, -1): | |
171 | for j in xrange(i - window, i + 1): |
|
161 | for j in xrange(i - window, i + 1): | |
172 |
yield j, |
|
162 | yield j, change(j)[3] | |
173 |
|
163 | |||
174 | for rev, changefiles in changerevgen(): |
|
164 | for rev, changefiles in changerevgen(): | |
175 | matches = filter(matchfn, changefiles) |
|
165 | matches = filter(matchfn, changefiles) | |
@@ -220,7 +210,7 b' def walkchangerevs(ui, repo, pats, opts)' | |||||
220 | ff = followfilter() |
|
210 | ff = followfilter() | |
221 | stop = min(revs[0], revs[-1]) |
|
211 | stop = min(revs[0], revs[-1]) | |
222 | for x in xrange(rev, stop-1, -1): |
|
212 | for x in xrange(rev, stop-1, -1): | |
223 |
if ff.match(x) and wanted |
|
213 | if ff.match(x) and x in wanted: | |
224 | del wanted[x] |
|
214 | del wanted[x] | |
225 |
|
215 | |||
226 | def iterate(): |
|
216 | def iterate(): | |
@@ -240,11 +230,11 b' def walkchangerevs(ui, repo, pats, opts)' | |||||
240 | srevs = list(nrevs) |
|
230 | srevs = list(nrevs) | |
241 | srevs.sort() |
|
231 | srevs.sort() | |
242 | for rev in srevs: |
|
232 | for rev in srevs: | |
243 |
fns = fncache.get(rev) or filter(matchfn, |
|
233 | fns = fncache.get(rev) or filter(matchfn, change(rev)[3]) | |
244 | yield 'add', rev, fns |
|
234 | yield 'add', rev, fns | |
245 | for rev in nrevs: |
|
235 | for rev in nrevs: | |
246 | yield 'iter', rev, None |
|
236 | yield 'iter', rev, None | |
247 |
return iterate(), |
|
237 | return iterate(), matchfn | |
248 |
|
238 | |||
249 | def write_bundle(cg, filename=None, compress=True): |
|
239 | def write_bundle(cg, filename=None, compress=True): | |
250 | """Write a bundle file and return its filename. |
|
240 | """Write a bundle file and return its filename. | |
@@ -298,13 +288,6 b' def write_bundle(cg, filename=None, comp' | |||||
298 | if cleanup is not None: |
|
288 | if cleanup is not None: | |
299 | os.unlink(cleanup) |
|
289 | os.unlink(cleanup) | |
300 |
|
290 | |||
301 | def trimuser(ui, name, rev, revcache): |
|
|||
302 | """trim the name of the user who committed a change""" |
|
|||
303 | user = revcache.get(rev) |
|
|||
304 | if user is None: |
|
|||
305 | user = revcache[rev] = ui.shortuser(name) |
|
|||
306 | return user |
|
|||
307 |
|
||||
308 | class changeset_printer(object): |
|
291 | class changeset_printer(object): | |
309 | '''show changeset information when templating not requested.''' |
|
292 | '''show changeset information when templating not requested.''' | |
310 |
|
293 | |||
@@ -1383,7 +1366,7 b' def export(ui, repo, *changesets, **opts' | |||||
1383 | """ |
|
1366 | """ | |
1384 | if not changesets: |
|
1367 | if not changesets: | |
1385 | raise util.Abort(_("export requires at least one changeset")) |
|
1368 | raise util.Abort(_("export requires at least one changeset")) | |
1386 |
revs = |
|
1369 | revs = cmdutil.revrange(ui, repo, changesets) | |
1387 | if len(revs) > 1: |
|
1370 | if len(revs) > 1: | |
1388 | ui.note(_('exporting patches:\n')) |
|
1371 | ui.note(_('exporting patches:\n')) | |
1389 | else: |
|
1372 | else: | |
@@ -1471,29 +1454,23 b' def grep(ui, repo, pattern, *pats, **opt' | |||||
1471 | yield ('+', b[i]) |
|
1454 | yield ('+', b[i]) | |
1472 |
|
1455 | |||
1473 | prev = {} |
|
1456 | prev = {} | |
1474 | ucache = {} |
|
|||
1475 | def display(fn, rev, states, prevstates): |
|
1457 | def display(fn, rev, states, prevstates): | |
1476 | counts = {'-': 0, '+': 0} |
|
1458 | counts = {'-': 0, '+': 0} | |
1477 | filerevmatches = {} |
|
1459 | filerevmatches = {} | |
1478 | if incrementing or not opts['all']: |
|
1460 | if incrementing or not opts['all']: | |
1479 | a, b = prevstates, states |
|
1461 | a, b, r = prevstates, states, rev | |
1480 | else: |
|
1462 | else: | |
1481 | a, b = states, prevstates |
|
1463 | a, b, r = states, prevstates, prev.get(fn, -1) | |
1482 | for change, l in difflinestates(a, b): |
|
1464 | for change, l in difflinestates(a, b): | |
1483 | if incrementing or not opts['all']: |
|
|||
1484 | r = rev |
|
|||
1485 | else: |
|
|||
1486 | r = prev[fn] |
|
|||
1487 | cols = [fn, str(r)] |
|
1465 | cols = [fn, str(r)] | |
1488 | if opts['line_number']: |
|
1466 | if opts['line_number']: | |
1489 | cols.append(str(l.linenum)) |
|
1467 | cols.append(str(l.linenum)) | |
1490 | if opts['all']: |
|
1468 | if opts['all']: | |
1491 | cols.append(change) |
|
1469 | cols.append(change) | |
1492 | if opts['user']: |
|
1470 | if opts['user']: | |
1493 |
cols.append( |
|
1471 | cols.append(ui.shortuser(getchange(r)[1])) | |
1494 | ucache)) |
|
|||
1495 | if opts['files_with_matches']: |
|
1472 | if opts['files_with_matches']: | |
1496 |
c = (fn, r |
|
1473 | c = (fn, r) | |
1497 | if c in filerevmatches: |
|
1474 | if c in filerevmatches: | |
1498 | continue |
|
1475 | continue | |
1499 | filerevmatches[c] = 1 |
|
1476 | filerevmatches[c] = 1 | |
@@ -1505,7 +1482,8 b' def grep(ui, repo, pattern, *pats, **opt' | |||||
1505 |
|
1482 | |||
1506 | fstate = {} |
|
1483 | fstate = {} | |
1507 | skip = {} |
|
1484 | skip = {} | |
1508 | changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts) |
|
1485 | getchange = util.cachefunc(lambda r:repo.changectx(r).changeset()) | |
|
1486 | changeiter, matchfn = walkchangerevs(ui, repo, pats, getchange, opts) | |||
1509 | count = 0 |
|
1487 | count = 0 | |
1510 | incrementing = False |
|
1488 | incrementing = False | |
1511 | follow = opts.get('follow') |
|
1489 | follow = opts.get('follow') | |
@@ -1514,8 +1492,7 b' def grep(ui, repo, pattern, *pats, **opt' | |||||
1514 | incrementing = rev |
|
1492 | incrementing = rev | |
1515 | matches.clear() |
|
1493 | matches.clear() | |
1516 | elif st == 'add': |
|
1494 | elif st == 'add': | |
1517 |
|
|
1495 | mf = repo.changectx(rev).manifest() | |
1518 | mf = repo.manifest.read(change[0]) |
|
|||
1519 | matches[rev] = {} |
|
1496 | matches[rev] = {} | |
1520 | for fn in fns: |
|
1497 | for fn in fns: | |
1521 | if fn in skip: |
|
1498 | if fn in skip: | |
@@ -1838,7 +1815,8 b' def log(ui, repo, *pats, **opts):' | |||||
1838 | def __getattr__(self, key): |
|
1815 | def __getattr__(self, key): | |
1839 | return getattr(self.ui, key) |
|
1816 | return getattr(self.ui, key) | |
1840 |
|
1817 | |||
1841 | changeiter, getchange, matchfn = walkchangerevs(ui, repo, pats, opts) |
|
1818 | getchange = util.cachefunc(lambda r:repo.changectx(r).changeset()) | |
|
1819 | changeiter, matchfn = walkchangerevs(ui, repo, pats, getchange, opts) | |||
1842 |
|
1820 | |||
1843 | if opts['branches']: |
|
1821 | if opts['branches']: | |
1844 | ui.warn(_("the --branches option is deprecated, " |
|
1822 | ui.warn(_("the --branches option is deprecated, " | |
@@ -1855,8 +1833,7 b' def log(ui, repo, *pats, **opts):' | |||||
1855 | count = 0 |
|
1833 | count = 0 | |
1856 |
|
1834 | |||
1857 | if opts['copies'] and opts['rev']: |
|
1835 | if opts['copies'] and opts['rev']: | |
1858 | endrev = max([int(i) |
|
1836 | endrev = max(cmdutil.revrange(ui, repo, opts['rev'])) + 1 | |
1859 | for i in cmdutil.revrange(ui, repo, opts['rev'])]) + 1 |
|
|||
1860 | else: |
|
1837 | else: | |
1861 | endrev = repo.changelog.count() |
|
1838 | endrev = repo.changelog.count() | |
1862 | rcache = {} |
|
1839 | rcache = {} |
@@ -25,7 +25,6 b' class dirstate(object):' | |||||
25 | self.dirs = None |
|
25 | self.dirs = None | |
26 | self.copymap = {} |
|
26 | self.copymap = {} | |
27 | self.ignorefunc = None |
|
27 | self.ignorefunc = None | |
28 | self.blockignore = False |
|
|||
29 |
|
28 | |||
30 | def wjoin(self, f): |
|
29 | def wjoin(self, f): | |
31 | return os.path.join(self.root, f) |
|
30 | return os.path.join(self.root, f) | |
@@ -98,8 +97,6 b' class dirstate(object):' | |||||
98 | '''default match function used by dirstate and |
|
97 | '''default match function used by dirstate and | |
99 | localrepository. this honours the repository .hgignore file |
|
98 | localrepository. this honours the repository .hgignore file | |
100 | and any other files specified in the [ui] section of .hgrc.''' |
|
99 | and any other files specified in the [ui] section of .hgrc.''' | |
101 | if self.blockignore: |
|
|||
102 | return False |
|
|||
103 | if not self.ignorefunc: |
|
100 | if not self.ignorefunc: | |
104 | ignore = self.hgignore() |
|
101 | ignore = self.hgignore() | |
105 | allpats = [] |
|
102 | allpats = [] | |
@@ -350,45 +347,42 b' class dirstate(object):' | |||||
350 | kind)) |
|
347 | kind)) | |
351 | return False |
|
348 | return False | |
352 |
|
349 | |||
353 |
def |
|
350 | def walk(self, files=None, match=util.always, badmatch=None): | |
|
351 | # filter out the stat | |||
|
352 | for src, f, st in self.statwalk(files, match, badmatch=badmatch): | |||
|
353 | yield src, f | |||
|
354 | ||||
|
355 | def statwalk(self, files=None, match=util.always, ignored=False, | |||
354 | badmatch=None): |
|
356 | badmatch=None): | |
|
357 | ''' | |||
|
358 | walk recursively through the directory tree, finding all files | |||
|
359 | matched by the match function | |||
|
360 | ||||
|
361 | results are yielded in a tuple (src, filename, st), where src | |||
|
362 | is one of: | |||
|
363 | 'f' the file was found in the directory tree | |||
|
364 | 'm' the file was only in the dirstate and not in the tree | |||
|
365 | 'b' file was not found and matched badmatch | |||
|
366 | ||||
|
367 | and st is the stat result if the file was found in the directory. | |||
|
368 | ''' | |||
355 | self.lazyread() |
|
369 | self.lazyread() | |
356 |
|
370 | |||
357 | # walk all files by default |
|
371 | # walk all files by default | |
358 | if not files: |
|
372 | if not files: | |
359 | files = [self.root] |
|
373 | files = [self.root] | |
360 | if not dc: |
|
|||
361 |
|
|
374 | dc = self.map.copy() | |
362 |
el |
|
375 | else: | |
|
376 | files = util.unique(files) | |||
363 | dc = self.filterfiles(files) |
|
377 | dc = self.filterfiles(files) | |
364 |
|
378 | |||
365 |
def |
|
379 | def imatch(file_): | |
366 |
file_ |
|
380 | if file_ not in dc and self.ignore(file_): | |
367 | if not ignored and file_ not in dc and self.ignore(file_): |
|
|||
368 | return False |
|
381 | return False | |
369 | return match(file_) |
|
382 | return match(file_) | |
370 |
|
383 | |||
371 | return self.walkhelper(files=files, statmatch=statmatch, dc=dc, |
|
384 | if ignored: imatch = match | |
372 | badmatch=badmatch) |
|
|||
373 |
|
||||
374 | def walk(self, files=None, match=util.always, dc=None, badmatch=None): |
|
|||
375 | # filter out the stat |
|
|||
376 | for src, f, st in self.statwalk(files, match, dc, badmatch=badmatch): |
|
|||
377 | yield src, f |
|
|||
378 |
|
385 | |||
379 | # walk recursively through the directory tree, finding all files |
|
|||
380 | # matched by the statmatch function |
|
|||
381 | # |
|
|||
382 | # results are yielded in a tuple (src, filename, st), where src |
|
|||
383 | # is one of: |
|
|||
384 | # 'f' the file was found in the directory tree |
|
|||
385 | # 'm' the file was only in the dirstate and not in the tree |
|
|||
386 | # and st is the stat result if the file was found in the directory. |
|
|||
387 | # |
|
|||
388 | # dc is an optional arg for the current dirstate. dc is not modified |
|
|||
389 | # directly by this function, but might be modified by your statmatch call. |
|
|||
390 | # |
|
|||
391 | def walkhelper(self, files, statmatch, dc, badmatch=None): |
|
|||
392 | # self.root may end with a path separator when self.root == '/' |
|
386 | # self.root may end with a path separator when self.root == '/' | |
393 | common_prefix_len = len(self.root) |
|
387 | common_prefix_len = len(self.root) | |
394 | if not self.root.endswith('/'): |
|
388 | if not self.root.endswith('/'): | |
@@ -420,12 +414,12 b' class dirstate(object):' | |||||
420 | # don't trip over symlinks |
|
414 | # don't trip over symlinks | |
421 | st = os.lstat(p) |
|
415 | st = os.lstat(p) | |
422 | if stat.S_ISDIR(st.st_mode): |
|
416 | if stat.S_ISDIR(st.st_mode): | |
423 | ds = os.path.join(nd, f +'/') |
|
417 | ds = util.pconvert(os.path.join(nd, f +'/')) | |
424 |
if |
|
418 | if imatch(ds): | |
425 | work.append(p) |
|
419 | work.append(p) | |
426 |
if |
|
420 | if imatch(np) and np in dc: | |
427 | yield 'm', np, st |
|
421 | yield 'm', np, st | |
428 |
elif |
|
422 | elif imatch(np): | |
429 | if self.supported_type(np, st): |
|
423 | if self.supported_type(np, st): | |
430 | yield 'f', np, st |
|
424 | yield 'f', np, st | |
431 | elif np in dc: |
|
425 | elif np in dc: | |
@@ -438,12 +432,12 b' class dirstate(object):' | |||||
438 |
|
432 | |||
439 | # step one, find all files that match our criteria |
|
433 | # step one, find all files that match our criteria | |
440 | files.sort() |
|
434 | files.sort() | |
441 |
for ff in |
|
435 | for ff in files: | |
|
436 | nf = util.normpath(ff) | |||
442 | f = self.wjoin(ff) |
|
437 | f = self.wjoin(ff) | |
443 | try: |
|
438 | try: | |
444 | st = os.lstat(f) |
|
439 | st = os.lstat(f) | |
445 | except OSError, inst: |
|
440 | except OSError, inst: | |
446 | nf = util.normpath(ff) |
|
|||
447 | found = False |
|
441 | found = False | |
448 | for fn in dc: |
|
442 | for fn in dc: | |
449 | if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'): |
|
443 | if nf == fn or (fn.startswith(nf) and fn[len(nf)] == '/'): | |
@@ -454,7 +448,7 b' class dirstate(object):' | |||||
454 | self.ui.warn('%s: %s\n' % ( |
|
448 | self.ui.warn('%s: %s\n' % ( | |
455 | util.pathto(self.getcwd(), ff), |
|
449 | util.pathto(self.getcwd(), ff), | |
456 | inst.strerror)) |
|
450 | inst.strerror)) | |
457 |
elif badmatch and badmatch(ff) and |
|
451 | elif badmatch and badmatch(ff) and imatch(nf): | |
458 | yield 'b', ff, None |
|
452 | yield 'b', ff, None | |
459 | continue |
|
453 | continue | |
460 | if stat.S_ISDIR(st.st_mode): |
|
454 | if stat.S_ISDIR(st.st_mode): | |
@@ -464,23 +458,18 b' class dirstate(object):' | |||||
464 | for e in sorted_: |
|
458 | for e in sorted_: | |
465 | yield e |
|
459 | yield e | |
466 | else: |
|
460 | else: | |
467 |
|
|
461 | if not seen(nf) and match(nf): | |
468 | if seen(ff): |
|
|||
469 | continue |
|
|||
470 | self.blockignore = True |
|
|||
471 | if statmatch(ff, st): |
|
|||
472 | if self.supported_type(ff, st, verbose=True): |
|
462 | if self.supported_type(ff, st, verbose=True): | |
473 |
yield 'f', |
|
463 | yield 'f', nf, st | |
474 | elif ff in dc: |
|
464 | elif ff in dc: | |
475 |
yield 'm', |
|
465 | yield 'm', nf, st | |
476 | self.blockignore = False |
|
|||
477 |
|
466 | |||
478 | # step two run through anything left in the dc hash and yield |
|
467 | # step two run through anything left in the dc hash and yield | |
479 | # if we haven't already seen it |
|
468 | # if we haven't already seen it | |
480 | ks = dc.keys() |
|
469 | ks = dc.keys() | |
481 | ks.sort() |
|
470 | ks.sort() | |
482 | for k in ks: |
|
471 | for k in ks: | |
483 |
if not seen(k) and |
|
472 | if not seen(k) and imatch(k): | |
484 | yield 'm', k, None |
|
473 | yield 'm', k, None | |
485 |
|
474 | |||
486 | def status(self, files=None, match=util.always, list_ignored=False, |
|
475 | def status(self, files=None, match=util.always, list_ignored=False, |
@@ -714,6 +714,18 b' class localrepository(repo.repository):' | |||||
714 | return n |
|
714 | return n | |
715 |
|
715 | |||
716 | def walk(self, node=None, files=[], match=util.always, badmatch=None): |
|
716 | def walk(self, node=None, files=[], match=util.always, badmatch=None): | |
|
717 | ''' | |||
|
718 | walk recursively through the directory tree or a given | |||
|
719 | changeset, finding all files matched by the match | |||
|
720 | function | |||
|
721 | ||||
|
722 | results are yielded in a tuple (src, filename), where src | |||
|
723 | is one of: | |||
|
724 | 'f' the file was found in the directory tree | |||
|
725 | 'm' the file was only in the dirstate and not in the tree | |||
|
726 | 'b' file was not found and matched badmatch | |||
|
727 | ''' | |||
|
728 | ||||
717 | if node: |
|
729 | if node: | |
718 | fdict = dict.fromkeys(files) |
|
730 | fdict = dict.fromkeys(files) | |
719 | for fn in self.manifest.read(self.changelog.read(node)[0]): |
|
731 | for fn in self.manifest.read(self.changelog.read(node)[0]): |
@@ -128,10 +128,12 b' def binary(s):' | |||||
128 | def unique(g): |
|
128 | def unique(g): | |
129 | """return the uniq elements of iterable g""" |
|
129 | """return the uniq elements of iterable g""" | |
130 | seen = {} |
|
130 | seen = {} | |
|
131 | l = [] | |||
131 | for f in g: |
|
132 | for f in g: | |
132 | if f not in seen: |
|
133 | if f not in seen: | |
133 | seen[f] = 1 |
|
134 | seen[f] = 1 | |
134 |
|
|
135 | l.append(f) | |
|
136 | return l | |||
135 |
|
137 | |||
136 | class Abort(Exception): |
|
138 | class Abort(Exception): | |
137 | """Raised if a command needs to print an error and exit.""" |
|
139 | """Raised if a command needs to print an error and exit.""" | |
@@ -985,6 +987,9 b' def shortuser(user):' | |||||
985 | f = user.find(' ') |
|
987 | f = user.find(' ') | |
986 | if f >= 0: |
|
988 | if f >= 0: | |
987 | user = user[:f] |
|
989 | user = user[:f] | |
|
990 | f = user.find('.') | |||
|
991 | if f >= 0: | |||
|
992 | user = user[:f] | |||
988 | return user |
|
993 | return user | |
989 |
|
994 | |||
990 | def walkrepos(path): |
|
995 | def walkrepos(path): |
@@ -9,7 +9,7 b' port:2:1:+:spam:export' | |||||
9 | port:2:2:+:spam:vaportight |
|
9 | port:2:2:+:spam:vaportight | |
10 | port:2:3:+:spam:import/export |
|
10 | port:2:3:+:spam:import/export | |
11 | port:1:2:+:eggs:export |
|
11 | port:1:2:+:eggs:export | |
12 |
port:0:1:+: |
|
12 | port:0:1:+:spam:import | |
13 | port:4:import/export |
|
13 | port:4:import/export | |
14 | % follow |
|
14 | % follow | |
15 | port:0:import |
|
15 | port:0:import | |
@@ -22,4 +22,4 b' port:2:1:+:spam:export' | |||||
22 | port:2:2:+:spam:vaportight |
|
22 | port:2:2:+:spam:vaportight | |
23 | port:2:3:+:spam:import/export |
|
23 | port:2:3:+:spam:import/export | |
24 | port:1:2:+:eggs:export |
|
24 | port:1:2:+:eggs:export | |
25 |
port:0:1:+: |
|
25 | port:0:1:+:spam:import |
General Comments 0
You need to be logged in to leave comments.
Login now