changeset 3105:7c7469d41ade

merge: pull manifest comparison out into separate function
author Matt Mackall <mpm@selenic.com>
date Sun, 17 Sep 2006 16:13:03 -0500
parents ef4e5d05bac4
children 4ec28446fca8
files mercurial/merge.py
diffstat 1 files changed, 94 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/merge.py	Sun Sep 17 16:02:09 2006 -0500
+++ b/mercurial/merge.py	Sun Sep 17 16:13:03 2006 -0500
@@ -52,6 +52,99 @@
     os.unlink(c)
     return r
 
+def manifestmerge(ui, m1, m2, ma, overwrite, backwards):
+    """
+    Merge manifest m1 with m2 using ancestor ma and generate merge action list
+    """
+
+    action = []
+
+    # Compare manifests
+    for f, n in m1.iteritems():
+        if f in m2:
+            queued = 0
+
+            # are files different?
+            if n != m2[f]:
+                a = ma.get(f, nullid)
+                # are both different from the ancestor?
+                if not overwrite and n != a and m2[f] != a:
+                    ui.debug(_(" %s versions differ, resolve\n") % f)
+                    action.append((f, "m", fmerge(f, m1, m2, ma), n[:20], m2[f]))
+                    queued = 1
+                # are we clobbering?
+                # is remote's version newer?
+                # or are we going back in time and clean?
+                elif overwrite or m2[f] != a or (backwards and not n[20:]):
+                    ui.debug(_(" remote %s is newer, get\n") % f)
+                    action.append((f, "g", m2.execf(f), m2[f]))
+                    queued = 1
+            elif n[20:] in ("u","a"):
+                # this unknown file is the same as the checkout
+                # we need to reset the dirstate if the file was added
+                action.append((f, "g", m2.execf(f), m2[f]))
+
+            # do we still need to look at mode bits?
+            if not queued and m1.execf(f) != m2.execf(f):
+                if overwrite:
+                    ui.debug(_(" updating permissions for %s\n") % f)
+                    action.append((f, "e", m2.execf(f)))
+                else:
+                    mode = fmerge(f, m1, m2, ma)
+                    if mode != m1.execf(f):
+                        ui.debug(_(" updating permissions for %s\n")
+                                      % f)
+                        action.append((f, "e", m2.execf(f)))
+            del m2[f]
+        elif f in ma:
+            if n != ma[f]:
+                r = _("d")
+                if not overwrite:
+                    r = ui.prompt(
+                        (_(" local changed %s which remote deleted\n") % f) +
+                         _("(k)eep or (d)elete?"), _("[kd]"), _("k"))
+                if r == _("d"):
+                    action.append((f, "r"))
+            else:
+                ui.debug(_("other deleted %s\n") % f)
+                action.append((f, "r"))
+        else:
+            # file is created on branch or in working directory
+            if overwrite and n[20:] != "u":
+                ui.debug(_("remote deleted %s, clobbering\n") % f)
+                action.append((f, "r"))
+            elif not n[20:]: # same as parent
+                if backwards:
+                    ui.debug(_("remote deleted %s\n") % f)
+                    action.append((f, "r"))
+                else:
+                    ui.debug(_("local modified %s, keeping\n") % f)
+            else:
+                ui.debug(_("working dir created %s, keeping\n") % f)
+
+    for f, n in m2.iteritems():
+        if f[0] == "/":
+            continue
+        if f in ma and n != ma[f]:
+            r = _("k")
+            if not overwrite:
+                r = ui.prompt(
+                    (_("remote changed %s which local deleted\n") % f) +
+                     _("(k)eep or (d)elete?"), _("[kd]"), _("k"))
+            if r == _("k"):
+                action.append((f, "g", m2.execf(f), n))
+        elif f not in ma:
+            ui.debug(_("remote created %s\n") % f)
+            action.append((f, "g", m2.execf(f), n))
+        else:
+            if overwrite or backwards:
+                ui.debug(_("local deleted %s, recreating\n") % f)
+                action.append((f, "g", m2.execf(f), n))
+            else:
+                ui.debug(_("local deleted %s\n") % f)
+
+    return action
+
 def update(repo, node, branchmerge=False, force=False, partial=None,
            wlock=None, show_stats=True, remind=True):
 
@@ -134,90 +227,7 @@
         for f in m2.keys():
             if not partial(f): del m2[f]
 
-    # Compare manifests
-    for f, n in m1.iteritems():
-        if f in m2:
-            queued = 0
-
-            # are files different?
-            if n != m2[f]:
-                a = ma.get(f, nullid)
-                # are both different from the ancestor?
-                if not overwrite and n != a and m2[f] != a:
-                    repo.ui.debug(_(" %s versions differ, resolve\n") % f)
-                    action.append((f, "m", fmerge(f, m1, m2, ma), n[:20], m2[f]))
-                    queued = 1
-                # are we clobbering?
-                # is remote's version newer?
-                # or are we going back in time and clean?
-                elif overwrite or m2[f] != a or (backwards and not n[20:]):
-                    repo.ui.debug(_(" remote %s is newer, get\n") % f)
-                    action.append((f, "g", m2.execf(f), m2[f]))
-                    queued = 1
-            elif n[20:] in ("u","a"):
-                # this unknown file is the same as the checkout
-                # we need to reset the dirstate if the file was added
-                action.append((f, "g", m2.execf(f), m2[f]))
-
-            # do we still need to look at mode bits?
-            if not queued and m1.execf(f) != m2.execf(f):
-                if overwrite:
-                    repo.ui.debug(_(" updating permissions for %s\n") % f)
-                    action.append((f, "e", m2.execf(f)))
-                else:
-                    mode = fmerge(f, m1, m2, ma)
-                    if mode != m1.execf(f):
-                        repo.ui.debug(_(" updating permissions for %s\n")
-                                      % f)
-                        action.append((f, "e", m2.execf(f)))
-            del m2[f]
-        elif f in ma:
-            if n != ma[f]:
-                r = _("d")
-                if not overwrite:
-                    r = repo.ui.prompt(
-                        (_(" local changed %s which remote deleted\n") % f) +
-                         _("(k)eep or (d)elete?"), _("[kd]"), _("k"))
-                if r == _("d"):
-                    action.append((f, "r"))
-            else:
-                repo.ui.debug(_("other deleted %s\n") % f)
-                action.append((f, "r"))
-        else:
-            # file is created on branch or in working directory
-            if overwrite and n[20:] != "u":
-                repo.ui.debug(_("remote deleted %s, clobbering\n") % f)
-                action.append((f, "r"))
-            elif not n[20:]: # same as parent
-                if backwards:
-                    repo.ui.debug(_("remote deleted %s\n") % f)
-                    action.append((f, "r"))
-                else:
-                    repo.ui.debug(_("local modified %s, keeping\n") % f)
-            else:
-                repo.ui.debug(_("working dir created %s, keeping\n") % f)
-
-    for f, n in m2.iteritems():
-        if f[0] == "/":
-            continue
-        if f in ma and n != ma[f]:
-            r = _("k")
-            if not overwrite:
-                r = repo.ui.prompt(
-                    (_("remote changed %s which local deleted\n") % f) +
-                     _("(k)eep or (d)elete?"), _("[kd]"), _("k"))
-            if r == _("k"):
-                action.append((f, "g", m2.execf(f), n))
-        elif f not in ma:
-            repo.ui.debug(_("remote created %s\n") % f)
-            action.append((f, "g", m2.execf(f), n))
-        else:
-            if overwrite or backwards:
-                repo.ui.debug(_("local deleted %s, recreating\n") % f)
-                action.append((f, "g", m2.execf(f), n))
-            else:
-                repo.ui.debug(_("local deleted %s\n") % f)
-
+    action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards)
     del m1, m2, ma
 
     ### apply phase