# HG changeset patch # User Dirkjan Ochtman # Date 1256892819 -3600 # Node ID 8743f2e1bc54c7f5ca334bcfc75c107aa2949ebb # Parent 71e081b88f3e0811b5a0b4eaea309d91ad0384e3# Parent 1de5ebfa5585cf8b6b47d0fadb7f2f114821ed63 merge changes from mpm diff -r 71e081b88f3e -r 8743f2e1bc54 hgext/churn.py --- a/hgext/churn.py Wed Oct 28 22:47:46 2009 -0500 +++ b/hgext/churn.py Fri Oct 30 09:53:39 2009 +0100 @@ -54,13 +54,10 @@ df = util.matchdate(opts['date']) m = cmdutil.match(repo, pats, opts) - for st, ctx, fns in cmdutil.walkchangerevs(ui, repo, m, opts): - if not st == 'add': - continue - + def prep(ctx, fns): rev = ctx.rev() if df and not df(ctx.date()[0]): # doesn't match date format - continue + return key = getkey(ctx) key = amap.get(key, key) # alias remap @@ -70,7 +67,7 @@ parents = ctx.parents() if len(parents) > 1: ui.note(_('Revision %d is a merge, ignoring...\n') % (rev,)) - continue + return ctx1 = parents[0] lines = changedlines(ui, repo, ctx1, ctx, fns) @@ -84,6 +81,9 @@ ui.write("\r" + _("generating stats: %d%%") % pct) sys.stdout.flush() + for ctx in cmdutil.walkchangerevs(repo, m, opts, prep): + continue + if opts.get('progress'): ui.write("\r") sys.stdout.flush() diff -r 71e081b88f3e -r 8743f2e1bc54 mercurial/cmdutil.py --- a/mercurial/cmdutil.py Wed Oct 28 22:47:46 2009 -0500 +++ b/mercurial/cmdutil.py Fri Oct 30 09:53:39 2009 +0100 @@ -1022,24 +1022,26 @@ def finddate(ui, repo, date): """Find the tipmost changeset that matches the given date spec""" + df = util.matchdate(date) m = matchall(repo) results = {} - for st, ctx, fns in walkchangerevs(ui, repo, m, {'rev': None}): + + def prep(ctx, fns): + d = ctx.date() + if df(d[0]): + results[rev] = d + + for ctx in walkchangerevs(repo, m, {'rev': None}, prep): rev = ctx.rev() - if st == 'add': - d = ctx.date() - if df(d[0]): - results[rev] = d - elif st == 'iter': - if rev in results: - ui.status(_("Found revision %s from %s\n") % - (rev, util.datestr(results[rev]))) - return str(rev) + if rev in results: + ui.status(_("Found revision %s from %s\n") % + (rev, util.datestr(results[rev]))) + return str(rev) raise util.Abort(_("revision matching date not found")) -def walkchangerevs(ui, repo, match, opts): +def walkchangerevs(repo, match, opts, prepare): '''Iterate over files and the revs in which they changed. Callers most commonly need to iterate backwards over the history @@ -1050,15 +1052,9 @@ window, we first walk forwards to gather data, then in the desired order (usually backwards) to display it. - This function returns an iterator. The iterator yields 3-tuples. - They will be of one of the following forms: - - "add", rev, fns: out-of-order traversal of the given filenames - fns, which changed during revision rev - use to gather data for - possible display - - "iter", rev, None: in-order traversal of the revs earlier iterated - over with "add" - use to display data''' + This function returns an iterator yielding contexts. Before + yielding each context, the iterator will first call the prepare + function on each context in the window in forward order.''' def increasing_windows(start, end, windowsize=8, sizelimit=512): if start < end: @@ -1093,6 +1089,7 @@ # No files, no patterns. Display all revs. wanted = set(revs) copies = [] + if not slowpath: # Only files, no patterns. Check the history of each file. def filerevgen(filelog, node): @@ -1129,8 +1126,6 @@ slowpath = True break else: - ui.warn(_('%s:%s copy source revision cannot be found!\n') - % (file_, short(node))) continue for rev, copied in filerevgen(filelog, node): if rev <= maxrev: @@ -1215,6 +1210,7 @@ return rev in wanted for i, window in increasing_windows(0, len(revs)): + change = util.cachefunc(repo.changectx) nrevs = [rev for rev in revs[i:i+window] if want(rev)] for rev in sorted(nrevs): fns = fncache.get(rev) @@ -1225,9 +1221,9 @@ if match(f): yield f fns = fns_generator() - yield 'add', ctx, fns + prepare(ctx, fns) for rev in nrevs: - yield 'iter', change(rev), None + yield change(rev) return iterate() def commit(ui, repo, commitfunc, pats, opts): diff -r 71e081b88f3e -r 8743f2e1bc54 mercurial/commands.py --- a/mercurial/commands.py Wed Oct 28 22:47:46 2009 -0500 +++ b/mercurial/commands.py Fri Oct 30 09:53:39 2009 +0100 @@ -1302,61 +1302,62 @@ matchfn = cmdutil.match(repo, pats, opts) found = False follow = opts.get('follow') - for st, ctx, fns in cmdutil.walkchangerevs(ui, repo, matchfn, opts): - if st == 'add': - rev = ctx.rev() - pctx = ctx.parents()[0] - parent = pctx.rev() - matches.setdefault(rev, {}) - matches.setdefault(parent, {}) - files = revfiles.setdefault(rev, []) - for fn in fns: - flog = getfile(fn) + + def prep(ctx, fns): + rev = ctx.rev() + pctx = ctx.parents()[0] + parent = pctx.rev() + matches.setdefault(rev, {}) + matches.setdefault(parent, {}) + files = revfiles.setdefault(rev, []) + for fn in fns: + flog = getfile(fn) + try: + fnode = ctx.filenode(fn) + except error.LookupError: + continue + + copied = flog.renamed(fnode) + copy = follow and copied and copied[0] + if copy: + copies.setdefault(rev, {})[fn] = copy + if fn in skip: + if copy: + skip[copy] = True + continue + files.append(fn) + + if fn not in matches[rev]: + grepbody(fn, rev, flog.read(fnode)) + + pfn = copy or fn + if pfn not in matches[parent]: try: - fnode = ctx.filenode(fn) + fnode = pctx.filenode(pfn) + grepbody(pfn, parent, flog.read(fnode)) except error.LookupError: - continue - - copied = flog.renamed(fnode) - copy = follow and copied and copied[0] + pass + + for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep): + rev = ctx.rev() + parent = ctx.parents()[0].rev() + for fn in sorted(revfiles.get(rev, [])): + states = matches[rev][fn] + copy = copies.get(rev, {}).get(fn) + if fn in skip: if copy: - copies.setdefault(rev, {})[fn] = copy - if fn in skip: + skip[copy] = True + continue + pstates = matches.get(parent, {}).get(copy or fn, []) + if pstates or states: + r = display(fn, ctx, pstates, states) + found = found or r + if r and not opts.get('all'): + skip[fn] = True if copy: skip[copy] = True - continue - files.append(fn) - - if fn not in matches[rev]: - grepbody(fn, rev, flog.read(fnode)) - - pfn = copy or fn - if pfn not in matches[parent]: - try: - fnode = pctx.filenode(pfn) - grepbody(pfn, parent, flog.read(fnode)) - except error.LookupError: - pass - elif st == 'iter': - rev = ctx.rev() - parent = ctx.parents()[0].rev() - for fn in sorted(revfiles.get(rev, [])): - states = matches[rev][fn] - copy = copies.get(rev, {}).get(fn) - if fn in skip: - if copy: - skip[copy] = True - continue - pstates = matches.get(parent, {}).get(copy or fn, []) - if pstates or states: - r = display(fn, ctx, pstates, states) - found = found or r - if r and not opts.get('all'): - skip[fn] = True - if copy: - skip[copy] = True - del matches[rev] - del revfiles[rev] + del matches[rev] + del revfiles[rev] def heads(ui, repo, *branchrevs, **opts): """show current repository heads or show branch heads @@ -2034,53 +2035,42 @@ if opts["date"]: df = util.matchdate(opts["date"]) - only_branches = opts.get('only_branch') - displayer = cmdutil.show_changeset(ui, repo, opts, True, matchfn) - for st, ctx, fns in cmdutil.walkchangerevs(ui, repo, matchfn, opts): + def prep(ctx, fns): rev = ctx.rev() - if st == 'add': - parents = [p for p in repo.changelog.parentrevs(rev) - if p != nullrev] - if opts.get('no_merges') and len(parents) == 2: - continue - if opts.get('only_merges') and len(parents) != 2: - continue - - if only_branches and ctx.branch() not in only_branches: - continue - - if df and not df(ctx.date()[0]): - continue - - if opts.get('keyword'): - miss = 0 - for k in [kw.lower() for kw in opts['keyword']]: - if not (k in ctx.user().lower() or - k in ctx.description().lower() or - k in " ".join(ctx.files()).lower()): - miss = 1 - break - if miss: - continue - - if opts['user']: - if not [k for k in opts['user'] if k in ctx.user()]: - continue - - copies = [] - if opts.get('copies') and rev: - for fn in ctx.files(): - rename = getrenamed(fn, rev) - if rename: - copies.append((fn, rename[0])) - - displayer.show(ctx, copies=copies) - - elif st == 'iter': - if count == limit: break - - if displayer.flush(rev): + parents = [p for p in repo.changelog.parentrevs(rev) + if p != nullrev] + if opts.get('no_merges') and len(parents) == 2: + return + if opts.get('only_merges') and len(parents) != 2: + return + if opts.get('only_branch') and ctx.branch() not in opts['only_branch']: + return + if df and not df(ctx.date()[0]): + return + if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]: + return + if opts.get('keyword'): + for k in [kw.lower() for kw in opts['keyword']]: + if (k in ctx.user().lower() or + k in ctx.description().lower() or + k in " ".join(ctx.files()).lower()): + break + else: + return + + copies = [] + if opts.get('copies') and rev: + for fn in ctx.files(): + rename = getrenamed(fn, rev) + if rename: + copies.append((fn, rename[0])) + + displayer.show(ctx, copies=copies) + + for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep): + if count != limit: + if displayer.flush(ctx.rev()): count += 1 def manifest(ui, repo, node=None, rev=None):