[PATCH stable] resolve: keep wlock while resolving

Mads Kiilerich mads at kiilerich.com
Mon May 26 19:03:07 CDT 2014


# HG changeset patch
# User Mads Kiilerich <madski at unity3d.com>
# Date 1401123731 -7200
#      Mon May 26 19:02:11 2014 +0200
# Branch stable
# Node ID 3b9f1b3f473c5f93bdc0afce94d89f7652cf52cf
# Parent  565d45919db8ef3d814cd055829c1814f6040904
resolve: keep wlock while resolving

This will make resolve use correct locking and thus make it more safe.

Resolve is usually a long running command spending a lot of time waiting for
user input on hard problems. It is thus a real world scenario to start multiple
resolves at once or run other commands (such as up -C and merge) while resolve
is running. Proper locking prevents that.

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -4926,44 +4926,49 @@ def resolve(ui, repo, *pats, **opts):
         raise util.Abort(_('no files or directories specified; '
                            'use --all to remerge all files'))
 
-    ms = mergemod.mergestate(repo)
-    m = scmutil.match(repo[None], pats, opts)
-    ret = 0
-
-    for f in ms:
-        if m(f):
-            if show:
-                if nostatus:
-                    ui.write("%s\n" % f)
+    wlock = repo.wlock()
+    try:
+        ms = mergemod.mergestate(repo)
+        m = scmutil.match(repo[None], pats, opts)
+        ret = 0
+
+        for f in ms:
+            if m(f):
+                if show:
+                    if nostatus:
+                        ui.write("%s\n" % f)
+                    else:
+                        ui.write("%s %s\n" % (ms[f].upper(), f),
+                                 label='resolve.' +
+                                 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
+                elif mark:
+                    ms.mark(f, "r")
+                elif unmark:
+                    ms.mark(f, "u")
                 else:
-                    ui.write("%s %s\n" % (ms[f].upper(), f),
-                             label='resolve.' +
-                             {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
-            elif mark:
-                ms.mark(f, "r")
-            elif unmark:
-                ms.mark(f, "u")
-            else:
-                wctx = repo[None]
-
-                # backup pre-resolve (merge uses .orig for its own purposes)
-                a = repo.wjoin(f)
-                util.copyfile(a, a + ".resolve")
-
-                try:
-                    # resolve file
-                    ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
-                                 'resolve')
-                    if ms.resolve(f, wctx):
-                        ret = 1
-                finally:
-                    ui.setconfig('ui', 'forcemerge', '', 'resolve')
-                    ms.commit()
-
-                # replace filemerge's .orig file with our resolve file
-                util.rename(a + ".resolve", a + ".orig")
-
-    ms.commit()
+                    wctx = repo[None]
+
+                    # backup pre-resolve (merge uses .orig for its own purposes)
+                    a = repo.wjoin(f)
+                    util.copyfile(a, a + ".resolve")
+
+                    try:
+                        # resolve file
+                        ui.setconfig('ui', 'forcemerge', opts.get('tool', ''),
+                                     'resolve')
+                        if ms.resolve(f, wctx):
+                            ret = 1
+                    finally:
+                        ui.setconfig('ui', 'forcemerge', '', 'resolve')
+                        ms.commit()
+
+                    # replace filemerge's .orig file with our resolve file
+                    util.rename(a + ".resolve", a + ".orig")
+
+        ms.commit()
+    finally:
+        wlock.release()
+
     return ret
 
 @command('revert',


More information about the Mercurial-devel mailing list