# HG changeset patch # User Matt Mackall # Date 1178611153 18000 # Node ID bb1800a7d7e194b0f52177f9e7d7cd33ea204490 # Parent 1a63b44f90c9cdcb41f61cfc7e1ec5c83f8a6111 merge: fix spurious merges for copies in linear updates We make better use of contexts to accurately identify copies that don't need merges. Add a simple test and update other tests. diff -r 1a63b44f90c9 -r bb1800a7d7e1 mercurial/merge.py --- a/mercurial/merge.py Tue May 08 02:57:05 2007 -0500 +++ b/mercurial/merge.py Tue May 08 02:59:13 2007 -0500 @@ -8,7 +8,7 @@ from node import * from i18n import gettext as _ from demandload import * -demandload(globals(), "errno util os tempfile") +demandload(globals(), "errno util os tempfile context") def filemerge(repo, fw, fo, wctx, mctx): """perform a 3-way merge in the working directory @@ -123,6 +123,14 @@ f = dirname(f) return d + wctx = repo.workingctx() + + def makectx(f, n): + if len(n) == 20: + return repo.filectx(f, fileid=n) + return wctx.filectx(f) + ctx = util.cachefunc(makectx) + def findold(fctx): "find files that path was copied from, back to linkrev limit" old = {} @@ -160,7 +168,7 @@ # named changed on only one side? if ca.path() == c.path() or ca.path() == c2.path(): fullcopy[c.path()] = of # remember for dir rename detection - if c == c2: # no merge needed, ignore copy + if c == ca or c2 == ca: # no merge needed, ignore copy continue copy[c.path()] = of @@ -171,13 +179,11 @@ if not m1 or not m2 or not ma: return {} - dcopies = repo.dirstate.copies() u1 = nonoverlap(m1, m2, ma) u2 = nonoverlap(m2, m1, ma) - ctx = util.cachefunc(lambda f, n: repo.filectx(f, fileid=n[:20])) for f in u1: - checkcopies(ctx(dcopies.get(f, f), m1[f]), m2) + checkcopies(ctx(f, m1[f]), m2) for f in u2: checkcopies(ctx(f, m2[f]), m1) diff -r 1a63b44f90c9 -r bb1800a7d7e1 tests/test-merge-local.out --- a/tests/test-merge-local.out Tue May 08 02:57:05 2007 -0500 +++ b/tests/test-merge-local.out Tue May 08 02:59:13 2007 -0500 @@ -21,7 +21,7 @@ merging zzz1_merge_ok failed! merging zzz2_merge_bad merging zzz2_merge_bad failed! -3 files updated, 0 files merged, 1 files removed, 2 files unresolved +3 files updated, 0 files merged, 2 files removed, 2 files unresolved There are unresolved merges with locally modified files. You can redo the full merge using: hg update 0 @@ -40,7 +40,7 @@ merging zzz1_merge_ok merging zzz2_merge_bad merging zzz2_merge_bad failed! -3 files updated, 1 files merged, 1 files removed, 1 files unresolved +3 files updated, 1 files merged, 2 files removed, 1 files unresolved There are unresolved merges with locally modified files. You can finish the partial merge using: hg update 0 @@ -59,7 +59,7 @@ M zzz2_merge_bad # local merge without conflicts merging zzz1_merge_ok -4 files updated, 1 files merged, 1 files removed, 0 files unresolved +4 files updated, 1 files merged, 2 files removed, 0 files unresolved --- a/zzz1_merge_ok +++ b/zzz1_merge_ok +new last line diff -r 1a63b44f90c9 -r bb1800a7d7e1 tests/test-merge8.out --- a/tests/test-merge8.out Tue May 08 02:57:05 2007 -0500 +++ b/tests/test-merge8.out Tue May 08 02:59:13 2007 -0500 @@ -6,5 +6,4 @@ adding file changes added 2 changesets with 2 changes to 1 files (run 'hg update' to get a working copy) -merging a and b -0 files updated, 1 files merged, 0 files removed, 0 files unresolved +1 files updated, 0 files merged, 1 files removed, 0 files unresolved diff -r 1a63b44f90c9 -r bb1800a7d7e1 tests/test-rename-dir-merge.out --- a/tests/test-rename-dir-merge.out Tue May 08 02:57:05 2007 -0500 +++ b/tests/test-rename-dir-merge.out Tue May 08 02:59:13 2007 -0500 @@ -10,39 +10,33 @@ overwrite None partial False ancestor f9b20c0d4c51 local ce36d17b18fb+ remote 55119e611c80 a/c: remote renamed directory to b/c -> d - a/a: remote moved to b/a -> m - a/b: remote moved to b/b -> m -copying a/a to b/a + a/b: other deleted -> r + a/a: other deleted -> r + b/a: remote created -> g + b/b: remote created -> g removing a/a -copying a/b to b/b removing a/b moving a/c to b/c -3 files updated, 0 files merged, 0 files removed, 0 files unresolved +getting b/a +getting b/b +3 files updated, 0 files merged, 2 files removed, 0 files unresolved (branch merge, don't forget to commit) a/* b/a b/b b/c M b/a - a/a M b/b - a/b A b/c a/c R a/a R a/b R a/c -2 files updated, 0 files merged, 1 files removed, 0 files unresolved +0 files updated, 0 files merged, 1 files removed, 0 files unresolved resolving manifests overwrite None partial False ancestor f9b20c0d4c51 local 55119e611c80+ remote ce36d17b18fb - b/a: local moved to a/a -> m - b/b: local moved to a/b -> m None: local renamed directory to b/c -> d getting a/c to b/c -3 files updated, 0 files merged, 0 files removed, 0 files unresolved +1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) a/* b/a b/b b/c -M b/a - a/a -M b/b - a/b A b/c a/c diff -r 1a63b44f90c9 -r bb1800a7d7e1 tests/test-rename-dir-merge2.out --- a/tests/test-rename-dir-merge2.out Tue May 08 02:57:05 2007 -0500 +++ b/tests/test-rename-dir-merge2.out Tue May 08 02:59:13 2007 -0500 @@ -10,11 +10,9 @@ adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge) -merging a/f and b/f -1 files updated, 1 files merged, 0 files removed, 0 files unresolved +2 files updated, 0 files merged, 1 files removed, 0 files unresolved (branch merge, don't forget to commit) M b/f - a/f A b/aa/g a/aa/g R a/aa/g diff -r 1a63b44f90c9 -r bb1800a7d7e1 tests/test-rename-merge2.out --- a/tests/test-rename-merge2.out Tue May 08 02:57:05 2007 -0500 +++ b/tests/test-rename-merge2.out Tue May 08 02:59:13 2007 -0500 @@ -88,15 +88,14 @@ overwrite None partial False ancestor 924404dff337 local 94b33a1b7f2d+ remote 735846fee2d7 rev: versions differ -> m - a: remote copied to b -> m -copying a to b + b: remote created -> g +getting b merging rev my rev@94b33a1b7f2d+ other rev@735846fee2d7 ancestor rev@924404dff337 1 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) -------------- M b - a C a -------------- @@ -106,16 +105,14 @@ resolving manifests overwrite None partial False ancestor 924404dff337 local ac809aeed39a+ remote 97c705ade336 - b: local copied to a -> m rev: versions differ -> m merging rev my rev@ac809aeed39a+ other rev@97c705ade336 ancestor rev@924404dff337 -1 files updated, 1 files merged, 0 files removed, 0 files unresolved +0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) -------------- -M b - a C a +C b -------------- -------------- @@ -124,17 +121,17 @@ resolving manifests overwrite None partial False ancestor 924404dff337 local 94b33a1b7f2d+ remote e03727d2d66b + a: other deleted -> r rev: versions differ -> m - a: remote moved to b -> m -copying a to b + b: remote created -> g removing a +getting b merging rev my rev@94b33a1b7f2d+ other rev@e03727d2d66b ancestor rev@924404dff337 -1 files updated, 1 files merged, 0 files removed, 0 files unresolved +1 files updated, 1 files merged, 1 files removed, 0 files unresolved (branch merge, don't forget to commit) -------------- M b - a -------------- -------------- @@ -143,15 +140,13 @@ resolving manifests overwrite None partial False ancestor 924404dff337 local ecf3cb2a4219+ remote 97c705ade336 - b: local moved to a -> m rev: versions differ -> m merging rev my rev@ecf3cb2a4219+ other rev@97c705ade336 ancestor rev@924404dff337 -1 files updated, 1 files merged, 0 files removed, 0 files unresolved +0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) -------------- -M b - a +C b -------------- --------------