--- a/hgext3rd/topic/__init__.py Mon Aug 21 19:44:23 2017 +0200
+++ b/hgext3rd/topic/__init__.py Mon Aug 14 11:39:06 2017 +0530
@@ -356,7 +356,18 @@
raise error.Abort('changing topic requires a topic name or --clear')
if any(not c.mutable() for c in repo.set('%r and public()', rev)):
raise error.Abort("can't change topic of a public change")
- return _changetopics(ui, repo, rev, topic)
+ wl = l = txn = None
+ try:
+ wl = repo.wlock()
+ l = repo.lock()
+ txn = repo.transaction('rewrite-topics')
+ rewrote = _changetopics(ui, repo, rev, topic)
+ txn.close()
+ finally:
+ lock.release(txn, l, wl)
+ repo.invalidate()
+ ui.status('changed topic on %d changes\n' % rewrote)
+ return
if clear:
return _changecurrenttopic(repo, None)
@@ -397,72 +408,66 @@
repo.vfs.unlink('topic')
def _changetopics(ui, repo, revset, newtopic):
+ """ Changes topic to newtopic of all the revisions in the revset and return
+ the count of revisions whose topic has been changed.
+ """
rewrote = 0
- wl = l = txn = None
- try:
- wl = repo.wlock()
- l = repo.lock()
- txn = repo.transaction('rewrite-topics')
- p1 = None
- p2 = None
- successors = {}
- for c in repo.set('%r', revset):
- def filectxfn(repo, ctx, path):
- try:
- return c[path]
- except error.ManifestLookupError:
- return None
- fixedextra = dict(c.extra())
- ui.debug('old node id is %s\n' % node.hex(c.node()))
- ui.debug('origextra: %r\n' % fixedextra)
- oldtopic = fixedextra.get(constants.extrakey, None)
- if oldtopic == newtopic:
- continue
- if newtopic is None:
- del fixedextra[constants.extrakey]
- else:
- fixedextra[constants.extrakey] = newtopic
- fixedextra[constants.changekey] = c.hex()
- if 'amend_source' in fixedextra:
- # TODO: right now the commitctx wrapper in
- # topicrepo overwrites the topic in extra if
- # amend_source is set to support 'hg commit
- # --amend'. Support for amend should be adjusted
- # to not be so invasive.
- del fixedextra['amend_source']
- ui.debug('changing topic of %s from %s to %s\n' % (
- c, oldtopic, newtopic))
- ui.debug('fixedextra: %r\n' % fixedextra)
- # While changing topic of set of linear commits, make sure that
- # we base our commits on new parent rather than old parent which
- # was obsoleted while changing the topic
- p1 = c.p1().node()
- p2 = c.p2().node()
- if p1 in successors:
- p1 = successors[p1]
- if p2 in successors:
- p2 = successors[p2]
- mc = context.memctx(
- repo, (p1, p2), c.description(),
- c.files(), filectxfn,
- user=c.user(), date=c.date(), extra=fixedextra)
- newnode = repo.commitctx(mc)
- successors[c.node()] = newnode
- ui.debug('new node id is %s\n' % node.hex(newnode))
- obsolete.createmarkers(repo, [(c, (repo[newnode],))])
- rewrote += 1
- # move the working copy too
- wctx = repo[None]
- # in-progress merge is a bit too complex for now.
- if len(wctx.parents()) == 1:
- newid = successors.get(wctx.p1().node())
- if newid is not None:
- hg.update(repo, newid, quietempty=True)
- txn.close()
- finally:
- lock.release(txn, l, wl)
- repo.invalidate()
- ui.status('changed topic on %d changes\n' % rewrote)
+ p1 = None
+ p2 = None
+ successors = {}
+ for c in repo.set('%r', revset):
+ def filectxfn(repo, ctx, path):
+ try:
+ return c[path]
+ except error.ManifestLookupError:
+ return None
+ fixedextra = dict(c.extra())
+ ui.debug('old node id is %s\n' % node.hex(c.node()))
+ ui.debug('origextra: %r\n' % fixedextra)
+ oldtopic = fixedextra.get(constants.extrakey, None)
+ if oldtopic == newtopic:
+ continue
+ if newtopic is None:
+ del fixedextra[constants.extrakey]
+ else:
+ fixedextra[constants.extrakey] = newtopic
+ fixedextra[constants.changekey] = c.hex()
+ if 'amend_source' in fixedextra:
+ # TODO: right now the commitctx wrapper in
+ # topicrepo overwrites the topic in extra if
+ # amend_source is set to support 'hg commit
+ # --amend'. Support for amend should be adjusted
+ # to not be so invasive.
+ del fixedextra['amend_source']
+ ui.debug('changing topic of %s from %s to %s\n' % (
+ c, oldtopic, newtopic))
+ ui.debug('fixedextra: %r\n' % fixedextra)
+ # While changing topic of set of linear commits, make sure that
+ # we base our commits on new parent rather than old parent which
+ # was obsoleted while changing the topic
+ p1 = c.p1().node()
+ p2 = c.p2().node()
+ if p1 in successors:
+ p1 = successors[p1]
+ if p2 in successors:
+ p2 = successors[p2]
+ mc = context.memctx(
+ repo, (p1, p2), c.description(),
+ c.files(), filectxfn,
+ user=c.user(), date=c.date(), extra=fixedextra)
+ newnode = repo.commitctx(mc)
+ successors[c.node()] = newnode
+ ui.debug('new node id is %s\n' % node.hex(newnode))
+ obsolete.createmarkers(repo, [(c, (repo[newnode],))])
+ rewrote += 1
+ # move the working copy too
+ wctx = repo[None]
+ # in-progress merge is a bit too complex for now.
+ if len(wctx.parents()) == 1:
+ newid = successors.get(wctx.p1().node())
+ if newid is not None:
+ hg.update(repo, newid, quietempty=True)
+ return rewrote
def _listtopics(ui, repo, opts):
fm = ui.formatter('topics', opts)