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

login
register
mail settings
Submitter Siddharth Agarwal
Date Feb. 8, 2013, 9:13 p.m.
Message ID <34715ca02ce42fa3452b.1360358006@sid0x220>
Download mbox | patch
Permalink /patch/836/
State Superseded, archived
Headers show

Comments

Siddharth Agarwal - Feb. 8, 2013, 9:13 p.m.
# HG changeset patch
# User Siddharth Agarwal <sid0@fb.com>
# Date 1360357062 0
# Node ID 34715ca02ce42fa3452b7b0d87cb0acfedb18a16
# Parent  52b65a0ec0e1c2ce3b2e9c33546a38ebcbe7946a
manifestmerge: handle abort on local unknown, remote created files

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(