Mercurial > public > mercurial-scm > hg
diff mercurial/revset.py @ 29348:2188f170f5b6
revset: add new topographical sort
Sort revisions in reverse revision order but grouped by topographical branches.
Visualised as a graph, instead of:
o 4
|
| o 3
| |
| o 2
| |
o | 1
|/
o 0
revisions on a 'main' branch are emitted before 'side' branches:
o 4
|
o 1
|
| o 3
| |
| o 2
|/
o 0
where what constitutes a 'main' branch is configurable, so the sort could also
result in:
o 3
|
o 2
|
| o 4
| |
| o 1
|/
o 0
This sort was already available as an experimental option in the graphmod
module, from which it is now removed.
This sort is best used with hg log -G:
$ hg log -G "sort(all(), topo)"
author | Martijn Pieters <mjpieters@fb.com> |
---|---|
date | Mon, 13 Jun 2016 18:20:00 +0100 |
parents | 98535ad46fc0 |
children | ec75d77df9d7 |
line wrap: on
line diff
--- a/mercurial/revset.py Mon Jun 13 18:20:00 2016 +0100 +++ b/mercurial/revset.py Mon Jun 13 18:20:00 2016 +0100 @@ -1843,7 +1843,7 @@ 'date': lambda c: c.date()[0], } -@predicate('sort(set[, [-]key...])', safe=True) +@predicate('sort(set[, [-]key... [, ...]])', safe=True) def sort(repo, subset, x): """Sort set by keys. The default sort order is ascending, specify a key as ``-key`` to sort in descending order. @@ -1855,8 +1855,14 @@ - ``desc`` for the commit message (description), - ``user`` for user name (``author`` can be used as an alias), - ``date`` for the commit date + - ``topo`` for a reverse topographical sort + + The ``topo`` sort order cannot be combined with other sort keys. This sort + takes one optional argument, ``topo.firstbranch``, which takes a revset that + specifies what topographical branches to prioritize in the sort. + """ - args = getargsdict(x, 'sort', 'set keys') + args = getargsdict(x, 'sort', 'set keys topo.firstbranch') if 'set' not in args: # i18n: "sort" is a keyword raise error.ParseError(_('sort requires one or two arguments')) @@ -1868,12 +1874,35 @@ s = args['set'] keys = keys.split() revs = getset(repo, subset, s) + + if len(keys) > 1 and any(k.lstrip('-') == 'topo' for k in keys): + # i18n: "topo" is a keyword + raise error.ParseError(_( + 'topo sort order cannot be combined with other sort keys')) + + firstbranch = () + if 'topo.firstbranch' in args: + if any(k.lstrip('-') == 'topo' for k in keys): + firstbranch = getset(repo, subset, args['topo.firstbranch']) + else: + # i18n: "topo" and "topo.firstbranch" are keywords + raise error.ParseError(_( + 'topo.firstbranch can only be used when using the topo sort ' + 'key')) + if keys == ["rev"]: revs.sort() return revs elif keys == ["-rev"]: revs.sort(reverse=True) return revs + elif keys[0] in ("topo", "-topo"): + revs = baseset(_toposort(revs, repo.changelog.parentrevs, firstbranch), + istopo=True) + if keys[0][0] == '-': + revs.reverse() + return revs + # sort() is guaranteed to be stable ctxs = [repo[r] for r in revs] for k in reversed(keys): @@ -1887,7 +1916,7 @@ raise error.ParseError(_("unknown sort key %r") % fk) return baseset([c.rev() for c in ctxs]) -def groupbranchiter(revs, parentsfunc, firstbranch=()): +def _toposort(revs, parentsfunc, firstbranch=()): """Yield revisions from heads to roots one (topo) branch at a time. This function aims to be used by a graph generator that wishes to minimize