diff -r 9a2db13b2e99 -r dc247e648f43 hgext3rd/topic/__init__.py --- a/hgext3rd/topic/__init__.py Tue Aug 28 11:24:50 2018 +0200 +++ b/hgext3rd/topic/__init__.py Mon Sep 03 22:05:12 2018 +0200 @@ -29,8 +29,10 @@ your current topic. Topic is offering you aliases reference to changeset in your current topic -stack as 't#'. For example, 't1' refers to the root of your stack, 't2' to the -second commits, etc. The 'hg stack' command show these number. +stack as 's#'. For example, 's1' refers to the root of your stack, 's2' to the +second commits, etc. The 'hg stack' command show these number. 's0' can be used +to refer to the parent of the topic root. Updating using `hg up s0` will keep +the topic active. Push behavior will change a bit with topic. When pushing to a publishing repository the changesets will turn public and the topic data on them will fade @@ -132,7 +134,6 @@ registrar, scmutil, templatefilters, - templatekw, util, ) @@ -149,13 +150,8 @@ topicmap, ) -if util.safehasattr(registrar, 'command'): - commandfunc = registrar.command -else: # compat with hg < 4.3 - commandfunc = cmdutil.command - cmdtable = {} -command = commandfunc(cmdtable) +command = registrar.command(cmdtable) colortable = {'topic.active': 'green', 'topic.list.troubledcount': 'red', 'topic.list.headcount.multiple': 'yellow', @@ -181,7 +177,7 @@ 'topic.active': 'green', } -__version__ = '0.10.1.dev' +__version__ = '0.11.0.dev' testedwith = '4.3.3 4.4.2 4.5.2 4.6.2 4.7' minimumhgversion = '4.3' @@ -231,6 +227,8 @@ default=None, ) +templatekeyword = registrar.templatekeyword() + def _contexttopic(self, force=False): if not (force or self.mutable()): return '' @@ -240,8 +238,8 @@ def _contexttopicidx(self): topic = self.topic() if not topic: - # XXX we might want to include t0 here, - # however t0 is related to 'currenttopic' which has no place here. + # XXX we might want to include s0 here, + # however s0 is related to 'currenttopic' which has no place here. return None revlist = stack.stack(self._repo, topic=topic) try: @@ -257,12 +255,23 @@ return None context.basectx.topicidx = _contexttopicidx +stackrev = re.compile(r'^s\d+$') topicrev = re.compile(r'^t\d+$') branchrev = re.compile(r'^b\d+$') def _namemap(repo, name): revs = None - if topicrev.match(name): + if stackrev.match(name): + idx = int(name[1:]) + tname = topic = repo.currenttopic + if topic: + ttype = 'topic' + revs = list(stack.stack(repo, topic=topic)) + else: + ttype = 'branch' + tname = branch = repo[None].branch() + revs = list(stack.stack(repo, branch=branch)) + elif topicrev.match(name): idx = int(name[1:]) ttype = 'topic' tname = topic = repo.currenttopic @@ -279,9 +288,12 @@ try: r = revs[idx] except IndexError: - msg = _('cannot resolve "%s": %s "%s" has only %d changesets') + if ttype == 'topic': + msg = _('cannot resolve "%s": %s "%s" has only %d changesets') + elif ttype == 'branch': + msg = _('cannot resolve "%s": %s "%s" has only %d non-public changesets') raise error.Abort(msg % (name, ttype, tname, len(revs) - 1)) - # b0 or t0 can be None + # b0 or t0 or s0 can be None if r == -1 and idx == 0: msg = _('the %s "%s" has no %s') raise error.Abort(msg % (ttype, tname, name)) @@ -323,7 +335,7 @@ extensions.wrapfunction(cmdutil, 'buildcommittext', committextwrap) extensions.wrapfunction(merge, 'update', mergeupdatewrap) - # We need to check whether t0 or b0 is passed to override the default update + # We need to check whether t0 or b0 or s0 is passed to override the default update # behaviour of changing topic and I can't find a better way # to do that as scmutil.revsingle returns the rev number and hence we can't # plug into logic for this into mergemod.update(). @@ -338,7 +350,6 @@ cmdutil.summaryhooks.add('topic', summaryhook) - templatekw.keywords['topic'] = topickw # Wrap workingctx extra to return the topic name extensions.wrapfunction(context.workingctx, '__init__', wrapinit) # Wrap changelog.add to drop empty topic @@ -510,9 +521,11 @@ 'topics', 'topic', namemap=_namemap, nodemap=_nodemap, listnames=lambda repo: repo.topics)) -def topickw(**args): +@templatekeyword('topic', requires={'ctx'}) +def topickw(context, mapping): """:topic: String. The topic of the changeset""" - return args['ctx'].topic() + ctx = context.resource(mapping, 'ctx') + return ctx.topic() def wrapinit(orig, self, repo, *args, **kwargs): orig(self, repo, *args, **kwargs) @@ -647,9 +660,9 @@ ct = repo.currenttopic if clear: - empty = stack.stack(repo, topic=ct).changesetcount == 0 - if empty: - if ct: + if ct: + empty = stack.stack(repo, topic=ct).changesetcount == 0 + if empty: ui.status(_('clearing empty topic "%s"\n') % ct) return _changecurrenttopic(repo, None) @@ -1152,7 +1165,6 @@ # rebased commit. We have explicitly stored in config if rebase is # running. ot = repo.currenttopic - empty = stack.stack(repo, topic=ot).changesetcount == 0 if repo.ui.hasconfig('experimental', 'topicrebase'): isrebase = True if repo.ui.configbool('_internal', 'keep-topic'): @@ -1166,8 +1178,10 @@ f.write(t) if t and t != ot: repo.ui.status(_("switching to topic %s\n") % t) - if ot and not t and empty: - repo.ui.status(_('clearing empty topic "%s"\n') % ot) + if ot and not t: + empty = stack.stack(repo, topic=ot).changesetcount == 0 + if empty: + repo.ui.status(_('clearing empty topic "%s"\n') % ot) elif ist0: repo.ui.status(_("preserving the current topic '%s'\n") % ot) return ret @@ -1176,7 +1190,7 @@ def checkt0(orig, ui, repo, node=None, rev=None, *args, **kwargs): - thezeros = set(['t0', 'b0']) + thezeros = set(['t0', 'b0', 's0']) backup = repo.ui.backupconfig('_internal', 'keep-topic') try: if node in thezeros or rev in thezeros: