Mercurial > evolve
changeset 2731:d39942773163
topics: add a new flag --age which will show last touched time for topics
This adds a new flag `--age` to `hg topic` command which will show topics
sorted by their last touched time and will also show the last touched time for
them.
This patch also adds a simple test to make sure the flag does not breaks by
future changes. Adding more tests showing output like "3 hours ago", "2 minutes
ago" etc will change as the code takes time.time() into account which will
increase with time, and hence the output will change, so we need some static
output like a date.
author | Pulkit Goyal <7895pulkit@gmail.com> |
---|---|
date | Tue, 11 Jul 2017 21:39:39 +0530 |
parents | 7fbb7a5d359f |
children | 4b5caa509df8 |
files | hgext3rd/topic/__init__.py tests/test-topic.t |
diffstat | 2 files changed, 89 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext3rd/topic/__init__.py Tue Jul 11 11:24:43 2017 +0200 +++ b/hgext3rd/topic/__init__.py Tue Jul 11 21:39:39 2017 +0530 @@ -53,6 +53,7 @@ from __future__ import absolute_import import re +import time from mercurial.i18n import _ from mercurial import ( @@ -68,9 +69,11 @@ namespaces, node, obsolete, + obsutil, patch, phases, registrar, + templatefilters, util, ) @@ -297,6 +300,7 @@ ('', 'clear', False, 'clear active topic if any'), ('r', 'rev', '', 'revset of existing revisions', _('REV')), ('l', 'list', False, 'show the stack of changeset in the topic'), + ('', 'age', False, 'show when you last touched the topics') ] + commands.formatteropts) def topics(ui, repo, topic='', clear=False, rev=None, list=False, **opts): """View current topic, set current topic, change topic for a set of revisions, or see all topics. @@ -316,6 +320,9 @@ List of topics: `hg topics` + List of topics with their last touched time sorted according to it: + `hg topic --age` + The active topic (if any) will be prepended with a "*". The --verbose version of this command display various information on the state of each topic.""" @@ -442,6 +449,11 @@ def _listtopics(ui, repo, opts): fm = ui.formatter('topics', opts) + showlast = opts.get('age') + if showlast: + # we have a new function as plugging logic into existing function is + # pretty much difficult + return _showlasttouched(repo, fm, opts) activetopic = repo.currenttopic namemask = '%s' if repo.topics and ui.verbose: @@ -494,6 +506,76 @@ fm.plain('\n') fm.end() +def _showlasttouched(repo, fm, opts): + topics = repo.topics + timedict = _getlasttouched(repo, topics) + times = timedict.keys() + times.sort() + if topics: + maxwidth = max(len(t) for t in topics) + namemask = '%%-%is' % maxwidth + activetopic = repo.currenttopic + for timevalue in times: + curtopics = timedict[timevalue][1] + for topic in curtopics: + fm.startitem() + marker = ' ' + label = 'topic' + active = (topic == activetopic) + if active: + marker = '*' + label = 'topic.active' + fm.plain(' %s ' % marker, label=label) + fm.write('topic', namemask, topic, label=label) + fm.data(active=active) + fm.plain(' (') + if timevalue == -1: + timestr = 'not yet touched' + else: + timestr = templatefilters.age(timedict[timevalue][0]) + fm.write('lasttouched', '%s', timestr, label='topic.list.time') + fm.plain(')') + fm.plain('\n') + fm.end() + +def _getlasttouched(repo, topics): + """ + Calculates the last time a topic was used. Returns a dictionary of seconds + passed from current time for a topic as keys and topic name as values. + """ + topicstime = {} + curtime = time.time() + for t in topics: + maxtime = (0, 0) + trevs = repo.revs("topic(%s)", t) + # Need to check for the time of all changesets in the topic, whether + # they are obsolete of non-heads + # XXX: can we just rely on the max rev number for this + for revs in trevs: + rt = repo[revs].date() + if rt[0] > maxtime[0]: + # Can store the rev to gather more info + # latesthead = revs + maxtime = rt + # looking on the markers also to get more information and accurate + # last touch time. + obsmarkers = obsutil.getmarkers(repo, [repo[revs].node()]) + for marker in obsmarkers: + rt = marker.date() + if rt[0] > maxtime[0]: + maxtime = rt + # is the topic still yet untouched + if not trevs: + secspassed = -1 + else: + secspassed = (curtime - maxtime[0]) + try: + topicstime[secspassed][1].append(t) + except KeyError: + topicstime[secspassed] = (maxtime, [t]) + + return topicstime + def panicforuntopicedcommit(): msg = _("no active topic") hint = _("set a current topic or use '--config " +
--- a/tests/test-topic.t Tue Jul 11 11:24:43 2017 +0200 +++ b/tests/test-topic.t Tue Jul 11 21:39:39 2017 +0530 @@ -33,6 +33,9 @@ List of topics: 'hg topics' + List of topics with their last touched time sorted according to it: + 'hg topic --age' + The active topic (if any) will be prepended with a "*". The --verbose version of this command display various information on the @@ -43,6 +46,7 @@ --clear clear active topic if any -r --rev REV revset of existing revisions -l --list show the stack of changeset in the topic + --age show when you last touched the topics (some details hidden, use --verbose to show complete help) $ hg topics @@ -821,6 +825,9 @@ t1: start on fran t0^ Add file delta (base) + $ hg topics --age + * changewut (1970-01-01) + $ cd .. Testing the new config knob to forbid untopiced commit