commands: make backout acquire locks before processing
authorFUJIWARA Katsunori <foozy@lares.dti.ne.jp>
Wed, 02 Dec 2015 03:12:07 +0900
changeset 27193 c7217f1458bf
parent 27192 a01d3d32b53a
child 27194 77995317b374
commands: make backout acquire locks before processing Before this patch, "hg backout" executes below before acquisition of wlock. - cmdutil.checkunfinished() - cmdutil.bailifchanged() - repo.dirstate.parents() It may cause unintentional result, if another command runs parallelly (see also issue4368). In addition to it, "hg backout" refers changelog for purposes below without acquisition of store lock (slock), and it may cause unintentional result, if store is updated parallelly. - show and update to the revision by 'repo.changelog.tip()' - examine for "created new head" by 'repo.branchheads()' and 'cmdutil.commitstatus()' To avoid this issue, this patch makes "hg backout" acquire wlock and slock before processing.
mercurial/commands.py
--- a/mercurial/commands.py	Wed Dec 02 03:12:07 2015 +0900
+++ b/mercurial/commands.py	Wed Dec 02 03:12:07 2015 +0900
@@ -574,6 +574,15 @@
     Returns 0 on success, 1 if nothing to backout or there are unresolved
     files.
     '''
+    wlock = lock = None
+    try:
+        wlock = repo.wlock()
+        lock = repo.lock()
+        return _dobackout(ui, repo, node, rev, commit, **opts)
+    finally:
+        release(lock, wlock)
+
+def _dobackout(ui, repo, node=None, rev=None, commit=False, **opts):
     if rev and node:
         raise error.Abort(_("please specify just one revision"))
 
@@ -612,7 +621,6 @@
         parent = p1
 
     # the backout should appear on the same branch
-    wlock = repo.wlock()
     try:
         branch = repo.dirstate.branch()
         bheads = repo.branchheads(branch)
@@ -675,7 +683,9 @@
             finally:
                 ui.setconfig('ui', 'forcemerge', '', '')
     finally:
-        wlock.release()
+        # TODO: get rid of this meaningless try/finally enclosing.
+        # this is kept only to reduce changes in a patch.
+        pass
     return 0
 
 @command('bisect',