Patchwork [4,of,4,V3] manifestmerge: handle abort on local unknown, remote created files

login
register
mail settings
Submitter Siddharth Agarwal
Date Feb. 9, 2013, 3:48 p.m.
Message ID <a8047ff53c9e754629ba.1360424936@sid0x220>
Download mbox | patch
Permalink /patch/888/
State Superseded
Commit d9ff580fcaa26199ab8d76f35f81169431ce84b3
Headers show

Comments

Siddharth Agarwal - Feb. 9, 2013, 3:48 p.m.
# HG changeset patch
# User Siddharth Agarwal <sid0@fb.com>
# Date 1360424160 0
# Node ID a8047ff53c9e754629baf8347008ef456b713447
# Parent  0e6b206adfdd78e87dfb4f81c37a6b79f521ea18
manifestmerge: handle abort on local unknown, remote created files

This replaces the _checkunknown call in calculateupdates with a more
performant version. On a repository with over 150,000 files, this speeds up an
update by 0.6-0.8 seconds, which is up to 25%.

This does not introduce any UI changes. There is existing test coverage for
every case, mostly in test-merge*.t.
Bryan O'Sullivan - Feb. 9, 2013, 4 p.m.
On Sat, Feb 9, 2013 at 7:48 AM, Siddharth Agarwal <sid0@fb.com> wrote:

> manifestmerge: handle abort on local unknown, remote created files
>

Series crewed, thanks.

Patch

diff --git a/mercurial/merge.py b/mercurial/merge.py
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -224,7 +224,7 @@  def manifestmerge(repo, p1, p2, pa, bran
                 m1['.hgsubstate'] += "+"
                 break
 
-    prompts = []
+    aborts, prompts = [], []
     # Compare manifests
     for f, n in m1.iteritems():
         if partial and not partial(f):
@@ -285,15 +285,40 @@  def manifestmerge(repo, p1, p2, pa, bran
                 actions.append((f2, "m", (f, f, True),
                                 "remote moved to " + f))
         elif f not in ma:
-            if (not overwrite
-                and _checkunknownfile(repo, p1, p2, f)):
-                actions.append((f, "m", (f, f, False),
-                                "remote differs from untracked local"))
+            # local unknown, remote created: the logic is described by the
+            # following table:
+            #
+            # force  branchmerge  different  |  action
+            #   n         *           n      |    get
+            #   n         *           y      |   abort
+            #   y         n           *      |    get
+            #   y         y           n      |    get
+            #   y         y           y      |   merge
+            #
+            # Checking whether the files are different is expensive, so we
+            # don't do that when we can avoid it.
+            if force and not branchmerge:
+                actions.append((f, "g", (m2.flags(f),), "remote created"))
             else:
-                actions.append((f, "g", (m2.flags(f),), "remote created"))
+                different = _checkunknownfile(repo, p1, p2, f)
+                if force and branchmerge and different:
+                    actions.append((f, "m", (f, f, False),
+                                    "remote differs from untracked local"))
+                elif not force and different:
+                    aborts.append((f, "ud"))
+                else:
+                    actions.append((f, "g", (m2.flags(f),), "remote created"))
         elif n != ma[f]:
             prompts.append((f, "dc")) # prompt deleted/changed
 
+    for f, m in sorted(aborts):
+        if m == "ud":
+            repo.ui.warn(_("%s: untracked file differs\n") % f)
+        else: assert False, m
+    if aborts:
+        raise util.Abort(_("untracked files in working directory differ "
+                           "from files in requested revision"))
+
     for f, m in sorted(prompts):
         if m == "cd":
             if repo.ui.promptchoice(
@@ -447,8 +472,6 @@  def calculateupdates(repo, tctx, mctx, a
             _checkcollision(mctx, None)
         else:
             _checkcollision(mctx, (tctx, ancestor))
-    if not force:
-        _checkunknown(repo, tctx, mctx)
     if tctx.rev() is None:
         actions += _forgetremoved(tctx, mctx, branchmerge)
     actions += manifestmerge(repo, tctx, mctx,