hgext3rd/topic/__init__.py
changeset 2642 92e882a82aaf
parent 2625 8f2901f4749e
child 2643 a9ca94defc29
equal deleted inserted replaced
2641:c90c70d8b6de 2642:92e882a82aaf
   276             raise error.Abort(_('must have obsolete enabled to use --change'))
   276             raise error.Abort(_('must have obsolete enabled to use --change'))
   277         if not topic and not clear:
   277         if not topic and not clear:
   278             raise error.Abort('changing topic requires a topic name or --clear')
   278             raise error.Abort('changing topic requires a topic name or --clear')
   279         if any(not c.mutable() for c in repo.set('%r and public()', change)):
   279         if any(not c.mutable() for c in repo.set('%r and public()', change)):
   280             raise error.Abort("can't change topic of a public change")
   280             raise error.Abort("can't change topic of a public change")
   281         rewrote = 0
   281         _changetopics(ui, repo, change, topic, clear)
   282         needevolve = False
       
   283         l = repo.lock()
       
   284         txn = repo.transaction('rewrite-topics')
       
   285         try:
       
   286             newp = None
       
   287             oldp = None
       
   288             p1 = None
       
   289             p2 = None
       
   290             for c in repo.set('%r', change):
       
   291                 def filectxfn(repo, ctx, path):
       
   292                     try:
       
   293                         return c[path]
       
   294                     except error.ManifestLookupError:
       
   295                         return None
       
   296                 fixedextra = dict(c.extra())
       
   297                 ui.debug('old node id is %s\n' % node.hex(c.node()))
       
   298                 ui.debug('origextra: %r\n' % fixedextra)
       
   299                 newtopic = None if clear else topic
       
   300                 oldtopic = fixedextra.get(constants.extrakey, None)
       
   301                 if oldtopic == newtopic:
       
   302                     continue
       
   303                 if clear:
       
   304                     del fixedextra[constants.extrakey]
       
   305                 else:
       
   306                     fixedextra[constants.extrakey] = topic
       
   307                 if 'amend_source' in fixedextra:
       
   308                     # TODO: right now the commitctx wrapper in
       
   309                     # topicrepo overwrites the topic in extra if
       
   310                     # amend_source is set to support 'hg commit
       
   311                     # --amend'. Support for amend should be adjusted
       
   312                     # to not be so invasive.
       
   313                     del fixedextra['amend_source']
       
   314                 ui.debug('changing topic of %s from %s to %s\n' % (
       
   315                     c, oldtopic, newtopic))
       
   316                 ui.debug('fixedextra: %r\n' % fixedextra)
       
   317                 # While changing topic of set of linear commits, make sure that
       
   318                 # we base our commits on new parent rather than old parent which
       
   319                 # was obsoleted while changing the topic
       
   320                 if newp and c.p1().node() == oldp:
       
   321                     p1 = newp
       
   322                     p2 = c.p2().node()
       
   323                 elif newp and c.p2().node() == oldp:
       
   324                     p1 = c.p1().node()
       
   325                     p2 = newp
       
   326                 else:
       
   327                     p1 = c.p1().node()
       
   328                     p2 = c.p2().node()
       
   329                 mc = context.memctx(
       
   330                     repo, (p1, p2), c.description(),
       
   331                     c.files(), filectxfn,
       
   332                     user=c.user(), date=c.date(), extra=fixedextra)
       
   333                 newnode = repo.commitctx(mc)
       
   334                 oldp = c.node()
       
   335                 newp = newnode
       
   336                 ui.debug('new node id is %s\n' % node.hex(newnode))
       
   337                 needevolve = needevolve or (len(c.children()) > 0)
       
   338                 obsolete.createmarkers(repo, [(c, (repo[newnode],))])
       
   339                 rewrote += 1
       
   340             txn.close()
       
   341         except:
       
   342             try:
       
   343                 txn.abort()
       
   344             finally:
       
   345                 repo.invalidate()
       
   346             raise
       
   347         finally:
       
   348             lock.release(txn, l)
       
   349         ui.status('changed topic on %d changes\n' % rewrote)
       
   350         if needevolve:
       
   351             evolvetarget = 'topic(%s)' % topic if topic else 'not topic()'
       
   352             ui.status('please run hg evolve --rev "%s" now\n' % evolvetarget)
       
   353     if clear:
   282     if clear:
   354         if repo.vfs.exists('topic'):
   283         if repo.vfs.exists('topic'):
   355             repo.vfs.unlink('topic')
   284             repo.vfs.unlink('topic')
   356         return
   285         return
   357     if topic:
   286     if topic:
   369     if not topic:
   298     if not topic:
   370         topic = repo.currenttopic
   299         topic = repo.currenttopic
   371     if not topic:
   300     if not topic:
   372         raise error.Abort(_('no active topic to list'))
   301         raise error.Abort(_('no active topic to list'))
   373     return stack.showstack(ui, repo, topic, opts)
   302     return stack.showstack(ui, repo, topic, opts)
       
   303 
       
   304 def _changetopics(ui, repo, revset, topic, clear):
       
   305     rewrote = 0
       
   306     needevolve = False
       
   307     l = repo.lock()
       
   308     txn = repo.transaction('rewrite-topics')
       
   309     try:
       
   310         newp = None
       
   311         oldp = None
       
   312         p1 = None
       
   313         p2 = None
       
   314         for c in repo.set('%r', revset):
       
   315             def filectxfn(repo, ctx, path):
       
   316                 try:
       
   317                     return c[path]
       
   318                 except error.ManifestLookupError:
       
   319                     return None
       
   320             fixedextra = dict(c.extra())
       
   321             ui.debug('old node id is %s\n' % node.hex(c.node()))
       
   322             ui.debug('origextra: %r\n' % fixedextra)
       
   323             newtopic = None if clear else topic
       
   324             oldtopic = fixedextra.get(constants.extrakey, None)
       
   325             if oldtopic == newtopic:
       
   326                 continue
       
   327             if clear:
       
   328                 del fixedextra[constants.extrakey]
       
   329             else:
       
   330                 fixedextra[constants.extrakey] = topic
       
   331             if 'amend_source' in fixedextra:
       
   332                 # TODO: right now the commitctx wrapper in
       
   333                 # topicrepo overwrites the topic in extra if
       
   334                 # amend_source is set to support 'hg commit
       
   335                 # --amend'. Support for amend should be adjusted
       
   336                 # to not be so invasive.
       
   337                 del fixedextra['amend_source']
       
   338             ui.debug('changing topic of %s from %s to %s\n' % (
       
   339                 c, oldtopic, newtopic))
       
   340             ui.debug('fixedextra: %r\n' % fixedextra)
       
   341             # While changing topic of set of linear commits, make sure that
       
   342             # we base our commits on new parent rather than old parent which
       
   343             # was obsoleted while changing the topic
       
   344             if newp and c.p1().node() == oldp:
       
   345                 p1 = newp
       
   346                 p2 = c.p2().node()
       
   347             elif newp and c.p2().node() == oldp:
       
   348                 p1 = c.p1().node()
       
   349                 p2 = newp
       
   350             else:
       
   351                 p1 = c.p1().node()
       
   352                 p2 = c.p2().node()
       
   353             mc = context.memctx(
       
   354                 repo, (p1, p2), c.description(),
       
   355                 c.files(), filectxfn,
       
   356                 user=c.user(), date=c.date(), extra=fixedextra)
       
   357             newnode = repo.commitctx(mc)
       
   358             oldp = c.node()
       
   359             newp = newnode
       
   360             ui.debug('new node id is %s\n' % node.hex(newnode))
       
   361             needevolve = needevolve or (len(c.children()) > 0)
       
   362             obsolete.createmarkers(repo, [(c, (repo[newnode],))])
       
   363             rewrote += 1
       
   364         txn.close()
       
   365     except:
       
   366         try:
       
   367             txn.abort()
       
   368         finally:
       
   369             repo.invalidate()
       
   370         raise
       
   371     finally:
       
   372         lock.release(txn, l)
       
   373     ui.status('changed topic on %d changes\n' % rewrote)
       
   374     if needevolve:
       
   375         evolvetarget = 'topic(%s)' % topic if topic else 'not topic()'
       
   376         ui.status('please run hg evolve --rev "%s" now\n' % evolvetarget)
   374 
   377 
   375 def _listtopics(ui, repo, opts):
   378 def _listtopics(ui, repo, opts):
   376     fm = ui.formatter('bookmarks', opts)
   379     fm = ui.formatter('bookmarks', opts)
   377     activetopic = repo.currenttopic
   380     activetopic = repo.currenttopic
   378     namemask = '%s'
   381     namemask = '%s'