Mercurial > public > mercurial-scm > hg
diff hgext/show.py @ 31944:99bc93147d87
show: implement underway view
This is the beginning of a wip/smartlog view. It is basically a manually
constructed (read: fast) revset function to collect "relevant"
changesets combined with a custom template and a graph displayer.
It obviously needs a lot of work.
I'd like to get *something* usable in 4.2 so `hg show` has some value
to end-users.
Let the bikeshedding begin.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 12 Apr 2017 20:31:15 -0700 |
parents | 3e9f118cc834 |
children | 02c3b1f396de |
line wrap: on
line diff
--- a/hgext/show.py Wed Apr 12 20:28:44 2017 -0700 +++ b/hgext/show.py Wed Apr 12 20:31:15 2017 -0700 @@ -15,13 +15,17 @@ from __future__ import absolute_import from mercurial.i18n import _ +from mercurial.node import nullrev from mercurial import ( cmdutil, commands, error, formatter, + graphmod, pycompat, registrar, + revset, + revsetlang, ) # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for @@ -32,6 +36,7 @@ cmdtable = {} command = cmdutil.command(cmdtable) +revsetpredicate = registrar.revsetpredicate() class showcmdfunc(registrar._funcregistrarbase): """Register a function to be invoked for an `hg show <thing>`.""" @@ -128,6 +133,70 @@ fm.data(active=bm == active, longestbookmarklen=longestname) +@revsetpredicate('_underway([commitage[, headage]])') +def underwayrevset(repo, subset, x): + args = revset.getargsdict(x, 'underway', 'commitage headage') + if 'commitage' not in args: + args['commitage'] = None + if 'headage' not in args: + args['headage'] = None + + # We assume callers of this revset add a topographical sort on the + # result. This means there is no benefit to making the revset lazy + # since the topographical sort needs to consume all revs. + # + # With this in mind, we build up the set manually instead of constructing + # a complex revset. This enables faster execution. + + # Mutable changesets (non-public) are the most important changesets + # to return. ``not public()`` will also pull in obsolete changesets if + # there is a non-obsolete changeset with obsolete ancestors. This is + # why we exclude obsolete changesets from this query. + rs = 'not public() and not obsolete()' + rsargs = [] + if args['commitage']: + rs += ' and date(%s)' + rsargs.append(revsetlang.getstring(args['commitage'], + _('commitage requires a string'))) + + mutable = repo.revs(rs, *rsargs) + relevant = revset.baseset(mutable) + + # Add parents of mutable changesets to provide context. + relevant += repo.revs('parents(%ld)', mutable) + + # We also pull in (public) heads if they a) aren't closing a branch + # b) are recent. + rs = 'head() and not closed()' + rsargs = [] + if args['headage']: + rs += ' and date(%s)' + rsargs.append(revsetlang.getstring(args['headage'], + _('headage requires a string'))) + + relevant += repo.revs(rs, *rsargs) + + # Add working directory parent. + wdirrev = repo['.'].rev() + if wdirrev != nullrev: + relevant += revset.baseset(set([wdirrev])) + + return subset & relevant + +@showview('underway', fmtopic='underway') +def showunderway(ui, repo, fm): + """changesets that aren't finished""" + # TODO support date-based limiting when calling revset. + revs = repo.revs('sort(_underway(), topo)') + + revdag = graphmod.dagwalker(repo, revs) + displayer = cmdutil.changeset_templater(ui, repo, None, None, + tmpl=fm._t.load(fm._topic), + mapfile=None, buffered=True) + + ui.setconfig('experimental', 'graphshorten', True) + cmdutil.displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges) + # Adjust the docstring of the show command so it shows all registered views. # This is a bit hacky because it runs at the end of module load. When moved # into core or when another extension wants to provide a view, we'll need