diff -r 6863caf01daa -r 352053e6cd8e mercurial/revset.py --- a/mercurial/revset.py Sun Feb 26 17:10:57 2012 +0100 +++ b/mercurial/revset.py Sun Feb 26 17:10:57 2012 +0100 @@ -441,63 +441,45 @@ """ return limit(repo, subset, x) +def _follow(repo, subset, x, name, followfirst=False): + l = getargs(x, 0, 1, _("%s takes no arguments or a filename") % name) + c = repo['.'] + if l: + x = getstring(l[0], _("%s expected a filename") % name) + if x in c: + cx = c[x] + s = set(ctx.rev() for ctx in cx.ancestors(followfirst=followfirst)) + # include the revision responsible for the most recent version + s.add(cx.linkrev()) + else: + return [] + else: + cut = followfirst and 1 or None + cl = repo.changelog + s = set() + visit = [c.rev()] + while visit: + for prev in cl.parentrevs(visit.pop(0))[:cut]: + if prev not in s and prev != nodemod.nullrev: + visit.append(prev) + s.add(prev) + s.add(c.rev()) + + return [r for r in subset if r in s] + def follow(repo, subset, x): """``follow([file])`` An alias for ``::.`` (ancestors of the working copy's first parent). If a filename is specified, the history of the given file is followed, including copies. """ - # i18n: "follow" is a keyword - l = getargs(x, 0, 1, _("follow takes no arguments or a filename")) - c = repo['.'] - if l: - x = getstring(l[0], _("follow expected a filename")) - if x in c: - cx = c[x] - s = set(ctx.rev() for ctx in cx.ancestors()) - # include the revision responsible for the most recent version - s.add(cx.linkrev()) - else: - return [] - else: - s = set(repo.changelog.ancestors(c.rev())) - s.add(c.rev()) - - return [r for r in subset if r in s] + return _follow(repo, subset, x, 'follow') def _followfirst(repo, subset, x): # ``followfirst([file])`` # Like ``follow([file])`` but follows only the first parent of # every revision or file revision. - # i18n: "_followfirst" is a keyword - l = getargs(x, 0, 1, _("_followfirst takes no arguments or a filename")) - c = repo['.'] - if l: - x = getstring(l[0], _("_followfirst expected a filename")) - if x not in c: - return [] - cx = c[x] - visit = {} - s = set([cx.linkrev()]) - while True: - for p in cx.parents()[:1]: - visit[(p.rev(), p.node())] = p - if not visit: - break - cx = visit.pop(max(visit)) - s.add(cx.rev()) - else: - cl = repo.changelog - s = set() - visit = [c.rev()] - while visit: - for prev in cl.parentrevs(visit.pop(0))[:1]: - if prev not in s and prev != nodemod.nullrev: - visit.append(prev) - s.add(prev) - s.add(c.rev()) - - return [r for r in subset if r in s] + return _follow(repo, subset, x, '_followfirst', followfirst=True) def getall(repo, subset, x): """``all()``