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