changeset 119:22f2b700bd59

evolution: proper locking scheme (maybe a bit zelous with wlock and lock)
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
date Sat, 07 Jan 2012 11:19:12 +0100
parents 06fe05256a79
children ba45bb2d35cb
files hgext/evolution.py
diffstat 1 files changed, 47 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/evolution.py
+++ b/hgext/evolution.py
@@ -269,45 +269,48 @@
     if branch:
         opts.setdefault('extra', {})['branch'] = branch
 
-    wlock = repo.wlock()
+    lock = repo.lock()
     try:
-        if not old.phase():
-            raise util.Abort(_("can not rewrite immutable changeset %s") % old)
+        wlock = repo.wlock()
+        try:
+            if not old.phase():
+                raise util.Abort(_("can not rewrite immutable changeset %s") % old)
 
-        # commit current changes as update
-        # code copied from commands.commit to avoid noisy messages
-        ciopts = dict(opts)
-        ciopts.pop('message', None)
-        ciopts.pop('logfile', None)
-        ciopts['message'] = opts.get('note') or ('amends %s' % old.hex())
-        e = cmdutil.commiteditor
-        def commitfunc(ui, repo, message, match, opts):
-            return repo.commit(message, opts.get('user'), opts.get('date'), match,
-                               editor=e)
-        cmdutil.commit(ui, repo, commitfunc, pats, ciopts)
+            # commit current changes as update
+            # code copied from commands.commit to avoid noisy messages
+            ciopts = dict(opts)
+            ciopts.pop('message', None)
+            ciopts.pop('logfile', None)
+            ciopts['message'] = opts.get('note') or ('amends %s' % old.hex())
+            e = cmdutil.commiteditor
+            def commitfunc(ui, repo, message, match, opts):
+                return repo.commit(message, opts.get('user'), opts.get('date'), match,
+                                   editor=e)
+            cmdutil.commit(ui, repo, commitfunc, pats, ciopts)
 
-        # find all changesets to be considered updates
-        cl = repo.changelog
-        head = repo['.']
-        updatenodes = set(cl.nodesbetween(roots=[old.node()],
-                                          heads=[head.node()])[0])
-        updatenodes.remove(old.node())
-        if not updatenodes and not (opts.get('message') or opts.get('logfile') or opts.get('edit')):
-            raise error.Abort(_('no updates found'))
-        updates = [repo[n] for n in updatenodes]
+            # find all changesets to be considered updates
+            cl = repo.changelog
+            head = repo['.']
+            updatenodes = set(cl.nodesbetween(roots=[old.node()],
+                                              heads=[head.node()])[0])
+            updatenodes.remove(old.node())
+            if not updatenodes and not (opts.get('message') or opts.get('logfile') or opts.get('edit')):
+                raise error.Abort(_('no updates found'))
+            updates = [repo[n] for n in updatenodes]
 
-        # perform amend
-        if opts.get('edit'):
-            opts['force_editor'] = True
-        newid = rewrite(repo, old, updates, head,
-                        [old.p1().node(), old.p2().node()], opts)
+            # perform amend
+            if opts.get('edit'):
+                opts['force_editor'] = True
+            newid = rewrite(repo, old, updates, head,
+                            [old.p1().node(), old.p2().node()], opts)
 
-        # reroute the working copy parent to the new changeset
-        phases.retractboundary(repo, old.phase(), [newid])
-        repo.dirstate.setparents(newid, node.nullid)
-
+            # reroute the working copy parent to the new changeset
+            phases.retractboundary(repo, old.phase(), [newid])
+            repo.dirstate.setparents(newid, node.nullid)
+        finally:
+            wlock.release()
     finally:
-        wlock.release()
+        lock.release()
 
 def commitwrapper(orig, ui, repo, *arg, **kwargs):
     obsoleted = kwargs.get('obsolete', [])
@@ -321,13 +324,17 @@
     return result
 
 def graftwrapper(orig, ui, repo, *revs, **kwargs):
-    if kwargs.get('old_obsolete'):
-        obsoleted = kwargs.setdefault('obsolete', [])
-        if kwargs['continue']:
-            obsoleted.extend(repo.opener.read('graftstate').splitlines())
-        else:
-            obsoleted.extend(revs)
-    return commitwrapper(orig, ui, repo,*revs, **kwargs)
+    lock = repo.lock()
+    try:
+        if kwargs.get('old_obsolete'):
+            obsoleted = kwargs.setdefault('obsolete', [])
+            if kwargs['continue']:
+                obsoleted.extend(repo.opener.read('graftstate').splitlines())
+            else:
+                obsoleted.extend(revs)
+        return commitwrapper(orig, ui, repo,*revs, **kwargs)
+    finally:
+        lock.release()
 
 def extsetup(ui):
     entry = extensions.wrapcommand(commands.table, 'commit', commitwrapper)
@@ -335,4 +342,3 @@
     entry = extensions.wrapcommand(commands.table, 'graft', graftwrapper)
     entry[1].append(('o', 'obsolete', [], _("this graft obsolet this revision")))
     entry[1].append(('O', 'old-obsolete', False, _("graft result obsolete graft source")))
-