# HG changeset patch # User Matt Mackall # Date 1159994607 18000 # Node ID f05c182430a0128589aea34c5f5fa4106693234c # Parent 751840e739a1beb86c16a1136b4b586aea383eeb merge: add rename following Currently disabled by default, enable with [merge] followcopies = 1 diff -r 751840e739a1 -r f05c182430a0 mercurial/merge.py --- a/mercurial/merge.py Wed Oct 04 14:33:22 2006 -0500 +++ b/mercurial/merge.py Wed Oct 04 15:43:27 2006 -0500 @@ -54,6 +54,13 @@ 'HG_OTHER_NODE': p2}) if r: repo.ui.warn(_("merging %s failed!\n") % fw) + else: + if fd != fw: + repo.ui.debug(_("copying %s to %s\n") % (fw, fd)) + repo.wwrite(fd, repo.wread(fw)) + if move: + repo.ui.debug(_("removing %s\n") % fw) + os.unlink(a) os.unlink(b) os.unlink(c) @@ -126,6 +133,9 @@ Find moves and copies between m1 and m2 back to limit linkrev """ + if not repo.ui.config("merge", "followcopies"): + return {} + # avoid silly behavior for update from empty dir if not m1: return {} @@ -164,14 +174,17 @@ return copy -def manifestmerge(ui, m1, m2, ma, overwrite, backwards, partial): +def manifestmerge(ui, m1, m2, ma, copy, overwrite, backwards, partial): """ Merge manifest m1 with m2 using ancestor ma and generate merge action list """ - def fmerge(f): + def fmerge(f, f2=None, fa=None): """merge executable flags""" - a, b, c = ma.execf(f), m1.execf(f), m2.execf(f) + if not f2: + f2 = f + fa = f + a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2) return ((a^b) | (a^c)) ^ a action = [] @@ -203,6 +216,18 @@ elif m1.execf(f) != m2.execf(f): if overwrite or fmerge(f) != m1.execf(f): act("update permissions", f, "e", m2.execf(f)) + elif f in copy: + f2 = copy[f] + if f in ma: # case 3,20 A/B/A + act("remote moved", + f, "c", f2, f2, m1[f], m2[f2], fmerge(f, f2, f), True) + else: + if f2 in m1: # case 2 A,B/B/B + act("local copied", + f, "c", f2, f, m1[f], m2[f2], fmerge(f, f2, f2), False) + else: # case 4,21 A/B/B + act("local moved", + f, "c", f2, f, m1[f], m2[f2], fmerge(f, f2, f2), False) elif f in ma: if n != ma[f] and not overwrite: if ui.prompt( @@ -221,7 +246,14 @@ continue if f in m1: continue - if f in ma: + if f in copy: + f2 = copy[f] + if f2 in ma or f2 in m1: # already seen + continue + # rename case 1, A/A,B/A + act("remote copied", + f, "c", f2, f, m1[f2], m2[f], fmerge(f2, f, f2), False) + elif f in ma: if overwrite or backwards: act("recreating", f, "g", m2.execf(f), n) elif n != ma[f]: @@ -251,6 +283,12 @@ repo.ui.warn(_("update failed to remove %s: %s!\n") % (f, inst.strerror)) removed +=1 + elif m == "c": # copy + f2, fd, my, other, flag, remove = a[2:] + if filemerge(repo, f, f2, fd, my, other, xp1, xp2, remove): + unresolved += 1 + util.set_exec(repo.wjoin(fd), flag) + merged += 1 elif m == "m": # merge flag, my, other = a[2:] repo.ui.status(_("merging %s\n") % f) @@ -358,7 +396,8 @@ if not (backwards or overwrite): copy = findcopies(repo, m1, m2, pa.rev()) - action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards, partial) + action += manifestmerge(repo.ui, m1, m2, ma, copy, + overwrite, backwards, partial) ### apply phase