hgext3rd/topic/__init__.py
changeset 2898 3dfc88c06378
parent 2897 bd04a614b866
child 2899 32306ee32806
equal deleted inserted replaced
2897:bd04a614b866 2898:3dfc88c06378
   308             'topics', 'topic', namemap=_namemap, nodemap=_nodemap,
   308             'topics', 'topic', namemap=_namemap, nodemap=_nodemap,
   309             listnames=lambda repo: repo.topics))
   309             listnames=lambda repo: repo.topics))
   310 
   310 
   311 @command('topics', [
   311 @command('topics', [
   312         ('', 'clear', False, 'clear active topic if any'),
   312         ('', 'clear', False, 'clear active topic if any'),
   313         ('r', 'rev', '', 'revset of existing revisions', _('REV')),
   313         ('r', 'rev', [], 'revset of existing revisions', _('REV')),
   314         ('l', 'list', False, 'show the stack of changeset in the topic'),
   314         ('l', 'list', False, 'show the stack of changeset in the topic'),
   315         ('', 'age', False, 'show when you last touched the topics'),
   315         ('', 'age', False, 'show when you last touched the topics'),
   316         ('', 'current', None, 'display the current topic only'),
   316         ('', 'current', None, 'display the current topic only'),
   317     ] + commands.formatteropts,
   317     ] + commands.formatteropts,
   318     _('hg topics [TOPIC]'))
   318     _('hg topics [TOPIC]'))
   351         raise error.Abort(_("cannot use --current when setting a topic"))
   351         raise error.Abort(_("cannot use --current when setting a topic"))
   352     if current and clear:
   352     if current and clear:
   353         raise error.Abort(_("cannot use --current and --clear"))
   353         raise error.Abort(_("cannot use --current and --clear"))
   354     if clear and topic:
   354     if clear and topic:
   355         raise error.Abort(_("cannot use --clear when setting a topic"))
   355         raise error.Abort(_("cannot use --clear when setting a topic"))
       
   356 
       
   357     touchedrevs = set()
       
   358     if rev:
       
   359         touchedrevs = scmutil.revrange(repo, rev)
   356 
   360 
   357     if topic:
   361     if topic:
   358         topic = topic.strip()
   362         topic = topic.strip()
   359         if not topic:
   363         if not topic:
   360             raise error.Abort(_("topic name cannot consist entirely of whitespaces"))
   364             raise error.Abort(_("topic name cannot consist entirely of whitespaces"))
   368             topic = repo.currenttopic
   372             topic = repo.currenttopic
   369         if not topic:
   373         if not topic:
   370             raise error.Abort(_('no active topic to list'))
   374             raise error.Abort(_('no active topic to list'))
   371         return stack.showstack(ui, repo, topic=topic, opts=opts)
   375         return stack.showstack(ui, repo, topic=topic, opts=opts)
   372 
   376 
   373     if rev:
   377     if touchedrevs:
   374         if not obsolete.isenabled(repo, obsolete.createmarkersopt):
   378         if not obsolete.isenabled(repo, obsolete.createmarkersopt):
   375             raise error.Abort(_('must have obsolete enabled to change topics'))
   379             raise error.Abort(_('must have obsolete enabled to change topics'))
   376         if clear:
   380         if clear:
   377             topic = None
   381             topic = None
   378         elif opts.get('current'):
   382         elif opts.get('current'):
   379             topic = repo.currenttopic
   383             topic = repo.currenttopic
   380         elif not topic:
   384         elif not topic:
   381             raise error.Abort('changing topic requires a topic name or --clear')
   385             raise error.Abort('changing topic requires a topic name or --clear')
   382         if any(not c.mutable() for c in repo.set('%r and public()', rev)):
   386         if repo.revs('%ld and public()', touchedrevs):
   383             raise error.Abort("can't change topic of a public change")
   387             raise error.Abort("can't change topic of a public change")
   384         wl = l = txn = None
   388         wl = l = txn = None
   385         try:
   389         try:
   386             wl = repo.wlock()
   390             wl = repo.wlock()
   387             l = repo.lock()
   391             l = repo.lock()
   388             txn = repo.transaction('rewrite-topics')
   392             txn = repo.transaction('rewrite-topics')
   389             rewrote = _changetopics(ui, repo, rev, topic)
   393             rewrote = _changetopics(ui, repo, touchedrevs, topic)
   390             txn.close()
   394             txn.close()
   391             ui.status('changed topic on %d changes\n' % rewrote)
   395             ui.status('changed topic on %d changes\n' % rewrote)
   392         finally:
   396         finally:
   393             lockmod.release(txn, l, wl)
   397             lockmod.release(txn, l, wl)
   394             repo.invalidate()
   398             repo.invalidate()
   444                 f.write(newtopic)
   448                 f.write(newtopic)
   445     else:
   449     else:
   446         if repo.vfs.exists('topic'):
   450         if repo.vfs.exists('topic'):
   447             repo.vfs.unlink('topic')
   451             repo.vfs.unlink('topic')
   448 
   452 
   449 def _changetopics(ui, repo, revset, newtopic):
   453 def _changetopics(ui, repo, revs, newtopic):
   450     """ Changes topic to newtopic of all the revisions in the revset and return
   454     """ Changes topic to newtopic of all the revisions in the revset and return
   451     the count of revisions whose topic has been changed.
   455     the count of revisions whose topic has been changed.
   452     """
   456     """
   453     rewrote = 0
   457     rewrote = 0
   454     p1 = None
   458     p1 = None
   455     p2 = None
   459     p2 = None
   456     successors = {}
   460     successors = {}
   457     for c in repo.set('%r', revset):
   461     for r in revs:
       
   462         c = repo[r]
       
   463 
   458         def filectxfn(repo, ctx, path):
   464         def filectxfn(repo, ctx, path):
   459             try:
   465             try:
   460                 return c[path]
   466                 return c[path]
   461             except error.ManifestLookupError:
   467             except error.ManifestLookupError:
   462                 return None
   468                 return None