diff -r 0ba067a97d06 -r 862cabc132fd src/topic/__init__.py --- a/src/topic/__init__.py Wed Jun 10 15:26:50 2015 -0400 +++ b/src/topic/__init__.py Wed Jun 10 15:03:39 2015 -0400 @@ -12,6 +12,7 @@ from mercurial import cmdutil from mercurial import commands +from mercurial import context from mercurial import extensions from mercurial import namespaces from mercurial import obsolete @@ -62,12 +63,47 @@ @command('topics', [ ('', 'clear', False, 'clear active topic if any'), + ('', 'change', '', 'revset of existing revisions to change topic'), ]) -def topics(ui, repo, topic=None, clear=False): +def topics(ui, repo, topic=None, clear=False, change=None): """View current topic, set current topic, or see all topics.""" if not obsolete.isenabled(repo, obsolete.createmarkersopt): raise util.Abort('current reality means you should only ' 'use topic with obsolete enabled') + if change: + if topic is None and not clear: + raise util.Abort('changing topic requires a topic name or --clear') + if any(not c.mutable() for c in repo.set('%r and public()', change)): + raise util.Abort("can't change topic of a public change") + rewrote = 0 + needevolve = False + for c in repo.set('%r', change): + def filectxfn(repo, ctx, path): + try: + return c[path] + except error.ManifestLookupError: + return None + fixedextra = dict(c.extra()) + newtopic = None if clear else topic + if fixedextra.get('topic', None) == topic: + continue + if clear and 'topic' in fixedextra: + del fixedextra['topic'] + else: + fixedextra['topic'] = topic + c.parents() + mc = context.memctx( + repo, (c.p1().node(), c.p2().node()), c.description(), + c.files(), filectxfn, + user=c.user(), date=c.date(), extra=fixedextra) + newnode = repo.commitctx(mc) + needevolve = needevolve or (len(c.children()) > 0) + obsolete.createmarkers(repo, [(c, (repo[newnode],))]) + rewrote += 1 + ui.status('changed topic on %d changes\n' % rewrote) + if needevolve: + evolvetarget = 'topic(%s)' % topic if topic else 'not topic()' + ui.status('please run hg evolve --rev "%s" now\n' % evolvetarget) if clear: if repo.vfs.exists('topic'): repo.vfs.unlink('topic')