changeset 5047:d9689c6474bd

Merge with mpm
author Brendan Cully <brendan@kublai.com>
date Wed, 01 Aug 2007 14:26:30 -0700
parents ed68c8c31c9a (current diff) bf444a9a9c23 (diff)
children 41284ad94852
files tests/test-double-merge
diffstat 6 files changed, 77 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/merge.py
+++ b/mercurial/merge.py
@@ -9,10 +9,11 @@ from node import *
 from i18n import _
 import errno, util, os, tempfile, context
 
-def filemerge(repo, fw, fo, wctx, mctx):
+def filemerge(repo, fw, fd, fo, wctx, mctx):
     """perform a 3-way merge in the working directory
 
-    fw = filename in the working directory
+    fw = original filename in the working directory
+    fd = destination filename in the working directory
     fo = filename in other parent
     wctx, mctx = working and merge changecontexts
     """
@@ -27,15 +28,16 @@ def filemerge(repo, fw, fo, wctx, mctx):
         return name
 
     fcm = wctx.filectx(fw)
+    fcmdata = wctx.filectx(fd).data()
     fco = mctx.filectx(fo)
 
-    if not fco.cmp(fcm.data()): # files identical?
+    if not fco.cmp(fcmdata): # files identical?
         return None
 
     fca = fcm.ancestor(fco)
     if not fca:
         fca = repo.filectx(fw, fileid=nullrev)
-    a = repo.wjoin(fw)
+    a = repo.wjoin(fd)
     b = temp("base", fca)
     c = temp("other", fco)
 
@@ -49,11 +51,11 @@ def filemerge(repo, fw, fo, wctx, mctx):
     cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge")
            or "hgmerge")
     r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root,
-                    environ={'HG_FILE': fw,
+                    environ={'HG_FILE': fd,
                              'HG_MY_NODE': str(wctx.parents()[0]),
                              'HG_OTHER_NODE': str(mctx)})
     if r:
-        repo.ui.warn(_("merging %s failed!\n") % fw)
+        repo.ui.warn(_("merging %s failed!\n") % fd)
 
     os.unlink(b)
     os.unlink(c)
@@ -380,6 +382,15 @@ def applyupdates(repo, action, wctx, mct
 
     updated, merged, removed, unresolved = 0, 0, 0, 0
     action.sort()
+    # prescan for copy/renames
+    for a in action:
+        f, m = a[:2]
+        if m == 'm': # merge
+            f2, fd, flags, move = a[2:]
+            if f != fd:
+                repo.ui.debug(_("copying %s to %s\n") % (f, fd))
+                repo.wwrite(fd, repo.wread(f), flags)
+
     for a in action:
         f, m = a[:2]
         if f and f[0] == "/":
@@ -396,7 +407,7 @@ def applyupdates(repo, action, wctx, mct
             removed += 1
         elif m == "m": # merge
             f2, fd, flags, move = a[2:]
-            r = filemerge(repo, f, f2, wctx, mctx)
+            r = filemerge(repo, f, fd, f2, wctx, mctx)
             if r > 0:
                 unresolved += 1
             else:
@@ -404,12 +415,9 @@ def applyupdates(repo, action, wctx, mct
                     updated += 1
                 else:
                     merged += 1
-            if f != fd:
-                repo.ui.debug(_("copying %s to %s\n") % (f, fd))
-                repo.wwrite(fd, repo.wread(f), flags)
-                if move:
-                    repo.ui.debug(_("removing %s\n") % f)
-                    os.unlink(repo.wjoin(f))
+            if f != fd and move:
+                repo.ui.debug(_("removing %s\n") % f)
+                os.unlink(repo.wjoin(f))
             util.set_exec(repo.wjoin(fd), "x" in flags)
         elif m == "g": # get
             flags = a[2]
new file mode 100755
--- /dev/null
+++ b/tests/test-double-merge
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+hg init repo
+cd repo
+
+echo line 1 > foo
+hg ci -qAm 'add foo' -d "1000000 0"
+
+# copy foo to bar and change both files
+hg cp foo bar
+echo line 2-1 >> foo
+echo line 2-2 >> bar
+hg ci -m 'cp foo bar; change both' -d "1000000 0"
+
+# in another branch, change foo in a way that doesn't conflict with
+# the other changes
+hg up -qC 0
+echo line 0 >| foo
+hg cat foo >> foo
+hg ci -m 'change foo' -d "1000000 0"
+
+# we get conflicts that shouldn't be there
+hg merge --debug
+
+echo "-- foo --"
+cat foo
+
+echo "-- bar --"
+cat bar
+
new file mode 100644
--- /dev/null
+++ b/tests/test-double-merge.out
@@ -0,0 +1,20 @@
+resolving manifests
+ overwrite None partial False
+ ancestor 310fd17130da local 2092631ce82b+ remote 7731dad1c2b9
+ foo: versions differ -> m
+ foo: remote copied to bar -> m
+copying foo to bar
+merging foo and bar
+my foo@2092631ce82b+ other bar@7731dad1c2b9 ancestor foo@310fd17130da
+merging foo
+my foo@2092631ce82b+ other foo@7731dad1c2b9 ancestor foo@310fd17130da
+0 files updated, 2 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+-- foo --
+line 0
+line 1
+line 2-1
+-- bar --
+line 0
+line 1
+line 2-2
--- a/tests/test-merge9.out
+++ b/tests/test-merge9.out
@@ -5,7 +5,7 @@ adding quux2
 merging bar
 merging bar failed!
 merging foo and baz
-merging foo failed!
+merging baz failed!
 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
 There are unresolved merges, you can redo the full merge using:
   hg update -C 2
--- a/tests/test-rename-merge1.out
+++ b/tests/test-rename-merge1.out
@@ -7,9 +7,9 @@ resolving manifests
  a2: divergent renames -> dr
  a: remote moved to b -> m
  b2: remote created -> g
+copying a to b
 merging a and b
 my a@f26ec4fc3fa3+ other b@8e765a822af2 ancestor a@af1939970a1c
-copying a to b
 removing a
 warning: detected divergent renames of a2 to:
  c2
--- a/tests/test-rename-merge2.out
+++ b/tests/test-rename-merge2.out
@@ -6,17 +6,17 @@ resolving manifests
  ancestor 924404dff337 local e300d1c794ec+ remote 735846fee2d7
  rev: versions differ -> m
  a: remote copied to b -> m
+copying a to b
 merging a and b
 my a@e300d1c794ec+ other b@735846fee2d7 ancestor a@924404dff337
-copying a to b
 merging rev
 my rev@e300d1c794ec+ other rev@735846fee2d7 ancestor rev@924404dff337
 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
 (branch merge, don't forget to commit)
 --------------
-M a
 M b
   a
+C a
 --------------
 
 --------------
@@ -49,9 +49,9 @@ resolving manifests
  ancestor 924404dff337 local e300d1c794ec+ remote e03727d2d66b
  rev: versions differ -> m
  a: remote moved to b -> m
+copying a to b
 merging a and b
 my a@e300d1c794ec+ other b@e03727d2d66b ancestor a@924404dff337
-copying a to b
 removing a
 merging rev
 my rev@e300d1c794ec+ other rev@e03727d2d66b ancestor rev@924404dff337
@@ -357,9 +357,9 @@ resolving manifests
  ancestor 924404dff337 local e300d1c794ec+ remote 79cc6877a3b7
  rev: versions differ -> m
  a: remote moved to b -> m
+copying a to b
 merging a and b
 my a@e300d1c794ec+ other b@79cc6877a3b7 ancestor a@924404dff337
-copying a to b
 removing a
 merging rev
 my rev@e300d1c794ec+ other rev@79cc6877a3b7 ancestor rev@924404dff337