--- a/mercurial/merge.py Thu Jun 21 22:19:41 2007 +0200
+++ b/mercurial/merge.py Thu Jun 21 18:02:03 2007 -0500
@@ -155,11 +155,15 @@
copy = {}
fullcopy = {}
+ diverge = {}
def checkcopies(c, man):
'''check possible copies for filectx c'''
for of in findold(c):
+ fullcopy[c.path()] = of # remember for dir rename detection
if of not in man: # original file not in other manifest?
+ if of in ma:
+ diverge.setdefault(of, []).append(c.path())
continue
c2 = ctx(of, man[of])
ca = c.ancestor(c2)
@@ -167,17 +171,16 @@
continue
# 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 == ca or c2 == ca: # no merge needed, ignore copy
continue
copy[c.path()] = of
if not repo.ui.configbool("merge", "followcopies", True):
- return {}
+ return {}, {}
# avoid silly behavior for update from empty dir
if not m1 or not m2 or not ma:
- return {}
+ return {}, {}
u1 = nonoverlap(m1, m2, ma)
u2 = nonoverlap(m2, m1, ma)
@@ -188,8 +191,16 @@
for f in u2:
checkcopies(ctx(f, m2[f]), m1)
+ d2 = {}
+ for of, fl in diverge.items():
+ for f in fl:
+ fo = list(fl)
+ fo.remove(f)
+ d2[f] = (of, fo)
+ #diverge = d2
+
if not fullcopy or not repo.ui.configbool("merge", "followdirs", True):
- return copy
+ return copy, diverge
# generate a directory move map
d1, d2 = dirs(m1), dirs(m2)
@@ -223,7 +234,7 @@
del d1, d2, invalid
if not dirmove:
- return copy
+ return copy, diverge
# check unaccounted nonoverlapping files against directory moves
for f in u1 + u2:
@@ -234,7 +245,7 @@
copy[f] = dirmove[d] + f[len(d):]
break
- return copy
+ return copy, diverge
def manifestmerge(repo, p1, p2, pa, overwrite, partial):
"""
@@ -254,6 +265,7 @@
backwards = (pa == p2)
action = []
copy = {}
+ diverge = {}
def fmerge(f, f2=None, fa=None):
"""merge flags"""
@@ -273,7 +285,11 @@
action.append((f, m) + args)
if not (backwards or overwrite):
- copy = findcopies(repo, m1, m2, ma, pa.rev())
+ copy, diverge = findcopies(repo, m1, m2, ma, pa.rev())
+
+ for of, fl in diverge.items():
+ act("divergent renames", "dr", of, fl)
+
copied = dict.fromkeys(copy.values())
# Compare manifests
@@ -410,6 +426,11 @@
t = mctx.filectx(f2).data()
repo.wwrite(fd, t, flags)
updated += 1
+ elif m == "dr": # divergent renames
+ fl = a[2]
+ repo.ui.warn("warning: detected divergent renames of %s to:\n" % f)
+ for nf in fl:
+ repo.ui.warn(" %s\n" % nf)
elif m == "e": # exec
flags = a[2]
util.set_exec(repo.wjoin(f), flags)
--- a/tests/test-bundle-r.out Thu Jun 21 22:19:41 2007 +0200
+++ b/tests/test-bundle-r.out Thu Jun 21 18:02:03 2007 -0500
@@ -197,6 +197,9 @@
crosschecking files in changesets and manifests
checking files
3 files, 7 changesets, 6 total revisions
+warning: detected divergent renames of afile to:
+ anotherfile
+ adifferentfile
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
--- a/tests/test-rename-merge1.out Thu Jun 21 22:19:41 2007 +0200
+++ b/tests/test-rename-merge1.out Thu Jun 21 18:02:03 2007 -0500
@@ -4,12 +4,16 @@
resolving manifests
overwrite None partial False
ancestor af1939970a1c local f26ec4fc3fa3+ remote 8e765a822af2
+ a2: divergent renames -> dr
a: remote moved to b -> m
b2: remote created -> g
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
+ b2
getting b2
1 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
--- a/tests/test-rename-merge2.out Thu Jun 21 22:19:41 2007 +0200
+++ b/tests/test-rename-merge2.out Thu Jun 21 18:02:03 2007 -0500
@@ -173,8 +173,12 @@
resolving manifests
overwrite None partial False
ancestor 924404dff337 local ecf3cb2a4219+ remote e6abcc1a30c2
+ a: divergent renames -> dr
rev: versions differ -> m
c: remote created -> g
+warning: detected divergent renames of a to:
+ b
+ c
getting c
merging rev
my rev@ecf3cb2a4219+ other rev@e6abcc1a30c2 ancestor rev@924404dff337