diff mercurial/exchange.py @ 24752:5640efd1b160

unbundle: acquire 'wlock' when processing bundle2 (BC) (issue4596) A bundle2 may contain bookmark updates (or other extension content) that requires the 'wlock' to be written. As 'wlock' must be acquired before 'lock', we must stay on the side of caution and use both in all case to ensure their ordering.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Wed, 15 Apr 2015 01:16:40 -0400
parents 457e26da029b
children 5dc5cd7abbf5
line wrap: on
line diff
--- a/mercurial/exchange.py	Sun Apr 12 09:46:03 2015 -0400
+++ b/mercurial/exchange.py	Wed Apr 15 01:16:40 2015 -0400
@@ -10,6 +10,7 @@
 import errno, urllib
 import util, scmutil, changegroup, base85, error
 import discovery, phases, obsolete, bookmarks as bookmod, bundle2, pushkey
+import lock as lockmod
 
 def readbundle(ui, fh, fname, vfs=None):
     header = changegroup.readexactly(fh, 4)
@@ -1275,13 +1276,14 @@
     If the push was raced as PushRaced exception is raised."""
     r = 0
     # need a transaction when processing a bundle2 stream
-    tr = None
-    lock = repo.lock()
+    wlock = lock = tr = None
     try:
         check_heads(repo, heads, 'uploading changes')
         # push can proceed
         if util.safehasattr(cg, 'params'):
             try:
+                wlock = repo.wlock()
+                lock = repo.lock()
                 tr = repo.transaction(source)
                 tr.hookargs['source'] = source
                 tr.hookargs['url'] = url
@@ -1292,9 +1294,8 @@
                 exc.duringunbundle2 = True
                 raise
         else:
+            lock = repo.lock()
             r = changegroup.addchangegroup(repo, cg, source, url)
     finally:
-        if tr is not None:
-            tr.release()
-        lock.release()
+        lockmod.release(tr, lock, wlock)
     return r