[PATCH] merge: take wlock only when we actually need to start updating

Kevin Bullock kbullock+mercurial at ringworld.org
Sat Feb 9 18:23:42 CST 2013


# HG changeset patch
# User Kevin Bullock <kbullock at ringworld.org>
# Date 1360455052 0
# Node ID 1a54947f6b32cf6aa0ab4703b7c75d042257d8f1
# Parent  0027a5cec9d00873ca14129b4589975083e5e71d
merge: take wlock only when we actually need to start updating

Right now we have a big huge blob of code that's just deciding where to
update to and whether we should actually do it based on the options the
user specified (--check, --clean, --force, and friends). None of this
modifies the working directory.

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -587,65 +587,65 @@ def update(repo, node, branchmerge, forc
     """
 
     onode = node
+    wc = repo[None]
+    if node is None:
+        # tip of current branch
+        try:
+            node = repo.branchtip(wc.branch())
+        except error.RepoLookupError:
+            if wc.branch() == "default": # no default branch!
+                node = repo.lookup("tip") # update to tip
+            else:
+                raise util.Abort(_("branch %s not found") % wc.branch())
+    overwrite = force and not branchmerge
+    pl = wc.parents()
+    p1, p2 = pl[0], repo[node]
+    if ancestor:
+        pa = repo[ancestor]
+    else:
+        pa = p1.ancestor(p2)
+
+    fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
+
+    ### check phase
+    if not overwrite and len(pl) > 1:
+        raise util.Abort(_("outstanding uncommitted merges"))
+    if branchmerge:
+        if pa == p2:
+            raise util.Abort(_("merging with a working directory ancestor"
+                               " has no effect"))
+        elif pa == p1:
+            if not mergeancestor and p1.branch() == p2.branch():
+                raise util.Abort(_("nothing to merge"),
+                                 hint=_("use 'hg update' "
+                                        "or check 'hg heads'"))
+        if not force and (wc.files() or wc.deleted()):
+            raise util.Abort(_("outstanding uncommitted changes"),
+                             hint=_("use 'hg status' to list changes"))
+        for s in sorted(wc.substate):
+            if wc.sub(s).dirty():
+                raise util.Abort(_("outstanding uncommitted changes in "
+                                   "subrepository '%s'") % s)
+
+    elif not overwrite:
+        if pa == p1 or pa == p2: # linear
+            pass # all good
+        elif wc.dirty(missing=True):
+            raise util.Abort(_("crosses branches (merge branches or use"
+                               " --clean to discard changes)"))
+        elif onode is None:
+            raise util.Abort(_("crosses branches (merge branches or update"
+                               " --check to force update)"))
+        else:
+            # Allow jumping branches if clean and specific rev given
+            pa = p1
+
+    ### calculate phase
+    actions = calculateupdates(repo, wc, p2, pa,
+                               branchmerge, force, partial)
+
     wlock = repo.wlock()
     try:
-        wc = repo[None]
-        if node is None:
-            # tip of current branch
-            try:
-                node = repo.branchtip(wc.branch())
-            except error.RepoLookupError:
-                if wc.branch() == "default": # no default branch!
-                    node = repo.lookup("tip") # update to tip
-                else:
-                    raise util.Abort(_("branch %s not found") % wc.branch())
-        overwrite = force and not branchmerge
-        pl = wc.parents()
-        p1, p2 = pl[0], repo[node]
-        if ancestor:
-            pa = repo[ancestor]
-        else:
-            pa = p1.ancestor(p2)
-
-        fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
-
-        ### check phase
-        if not overwrite and len(pl) > 1:
-            raise util.Abort(_("outstanding uncommitted merges"))
-        if branchmerge:
-            if pa == p2:
-                raise util.Abort(_("merging with a working directory ancestor"
-                                   " has no effect"))
-            elif pa == p1:
-                if not mergeancestor and p1.branch() == p2.branch():
-                    raise util.Abort(_("nothing to merge"),
-                                     hint=_("use 'hg update' "
-                                            "or check 'hg heads'"))
-            if not force and (wc.files() or wc.deleted()):
-                raise util.Abort(_("outstanding uncommitted changes"),
-                                 hint=_("use 'hg status' to list changes"))
-            for s in sorted(wc.substate):
-                if wc.sub(s).dirty():
-                    raise util.Abort(_("outstanding uncommitted changes in "
-                                       "subrepository '%s'") % s)
-
-        elif not overwrite:
-            if pa == p1 or pa == p2: # linear
-                pass # all good
-            elif wc.dirty(missing=True):
-                raise util.Abort(_("crosses branches (merge branches or use"
-                                   " --clean to discard changes)"))
-            elif onode is None:
-                raise util.Abort(_("crosses branches (merge branches or update"
-                                   " --check to force update)"))
-            else:
-                # Allow jumping branches if clean and specific rev given
-                pa = p1
-
-        ### calculate phase
-        actions = calculateupdates(repo, wc, p2, pa,
-                                   branchmerge, force, partial)
-
         ### apply phase
         if not branchmerge: # just jump to the new rev
             fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''


More information about the Mercurial-devel mailing list