# HG changeset patch # User Thomas Arendsen Hein # Date 1186052605 -7200 # Node ID a3d6de2838de489c8ac5214a808a304f799861d1 # Parent 8db8e1100f3f1c36fdd3dd952d7b1f1a0580b710# Parent f191bc3916f7e5f6e178e814190b46f4edb3c2c6 merge with hg-stable diff --git a/mercurial/merge.py b/mercurial/merge.py --- 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] diff --git a/tests/test-double-merge b/tests/test-double-merge 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 + diff --git a/tests/test-double-merge.out b/tests/test-double-merge.out 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 diff --git a/tests/test-merge9.out b/tests/test-merge9.out --- 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 diff --git a/tests/test-rename-merge1.out b/tests/test-rename-merge1.out --- 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 diff --git a/tests/test-rename-merge2.out b/tests/test-rename-merge2.out --- 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