Mercurial > evolve
changeset 2850:a0d6741d4bb8
topics: take locks and start transaction before calling _changetopics
This will help us in calling _changetopics in other transactions which already
started. Currently the _changetopics creates its own transaction and hence can't
be used it a same transaction with any other function or logic.
author | Pulkit Goyal <7895pulkit@gmail.com> |
---|---|
date | Mon, 14 Aug 2017 11:39:06 +0530 |
parents | 95470e817c00 |
children | a13acecbc850 |
files | hgext3rd/topic/__init__.py |
diffstat | 1 files changed, 71 insertions(+), 66 deletions(-) [+] |
line wrap: on
line diff
--- 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)