changeset 26029:563ea14c62d4 stable

rebase: lock the repo during the full rebase operation Running `hg pull --rebase` would move bookmarks without any repository locking. So we now lock the repository. For good measure and avoiding sneaky race conditions, we lock the repository for the whole operation. There is no code change besides the indentation.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Tue, 11 Aug 2015 16:45:11 -0700
parents 6fbe35588433
children 5243890224ff 97208371715a
files hgext/rebase.py
diffstat 1 files changed, 38 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/rebase.py	Tue Aug 11 16:26:12 2015 -0700
+++ b/hgext/rebase.py	Tue Aug 11 16:45:11 2015 -0700
@@ -1026,40 +1026,46 @@
 def pullrebase(orig, ui, repo, *args, **opts):
     'Call rebase after pull if the latter has been invoked with --rebase'
     if opts.get('rebase'):
-        if opts.get('update'):
-            del opts['update']
-            ui.debug('--update and --rebase are not compatible, ignoring '
-                     'the update flag\n')
+        wlock = lock = None
+        try:
+            wlock = repo.wlock()
+            lock = repo.lock()
+            if opts.get('update'):
+                del opts['update']
+                ui.debug('--update and --rebase are not compatible, ignoring '
+                         'the update flag\n')
 
-        movemarkfrom = repo['.'].node()
-        revsprepull = len(repo)
-        origpostincoming = commands.postincoming
-        def _dummy(*args, **kwargs):
-            pass
-        commands.postincoming = _dummy
-        try:
-            orig(ui, repo, *args, **opts)
+            movemarkfrom = repo['.'].node()
+            revsprepull = len(repo)
+            origpostincoming = commands.postincoming
+            def _dummy(*args, **kwargs):
+                pass
+            commands.postincoming = _dummy
+            try:
+                orig(ui, repo, *args, **opts)
+            finally:
+                commands.postincoming = origpostincoming
+            revspostpull = len(repo)
+            if revspostpull > revsprepull:
+                # --rev option from pull conflict with rebase own --rev
+                # dropping it
+                if 'rev' in opts:
+                    del opts['rev']
+                # positional argument from pull conflicts with rebase's own
+                # --source.
+                if 'source' in opts:
+                    del opts['source']
+                rebase(ui, repo, **opts)
+                branch = repo[None].branch()
+                dest = repo[branch].rev()
+                if dest != repo['.'].rev():
+                    # there was nothing to rebase we force an update
+                    hg.update(repo, dest)
+                    if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
+                        ui.status(_("updating bookmark %s\n")
+                                  % repo._activebookmark)
         finally:
-            commands.postincoming = origpostincoming
-        revspostpull = len(repo)
-        if revspostpull > revsprepull:
-            # --rev option from pull conflict with rebase own --rev
-            # dropping it
-            if 'rev' in opts:
-                del opts['rev']
-            # positional argument from pull conflicts with rebase's own
-            # --source.
-            if 'source' in opts:
-                del opts['source']
-            rebase(ui, repo, **opts)
-            branch = repo[None].branch()
-            dest = repo[branch].rev()
-            if dest != repo['.'].rev():
-                # there was nothing to rebase we force an update
-                hg.update(repo, dest)
-                if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
-                    ui.status(_("updating bookmark %s\n")
-                              % repo._activebookmark)
+            release(lock, wlock)
     else:
         if opts.get('tool'):
             raise util.Abort(_('--tool can only be used with --rebase'))