Mercurial > public > mercurial-scm > hg
diff mercurial/copies.py @ 18134:6c35b53cd28b
copies: separate moves via directory renames from explicit copies
Currently the "copy" dict contains both explicit copies/moves made by a
context and pending moves that need to happen because the other context moved
the directory the file was in. For explicit copies, the dict stores a
destination to source map, while for pending moves via directory renames, it
stores a source to destination map. The merge code uses this fact in a non-
obvious way to differentiate between these two cases.
We make this explicit by storing these pending moves in a separate dict. The
dict still has a source to destination map, but that is called out in the
docstring.
author | Siddharth Agarwal <sid0@fb.com> |
---|---|
date | Wed, 26 Dec 2012 14:50:17 -0800 |
parents | 8b7cd9a998f0 |
children | a6fe1b9cc68f |
line wrap: on
line diff
--- a/mercurial/copies.py Wed Dec 26 11:16:18 2012 -0600 +++ b/mercurial/copies.py Wed Dec 26 14:50:17 2012 -0800 @@ -170,11 +170,17 @@ Find moves and copies between context c1 and c2 that are relevant for merging. - Returns two dicts, "copy" and "diverge". + Returns four dicts: "copy", "movewithdir", "diverge", and + "renamedelete". "copy" is a mapping from destination name -> source name, where source is in c1 and destination is in c2 or vice-versa. + "movewithdir" is a mapping from source name -> destination name, + where the file at source present in one context but not the other + needs to be moved to destination by the merge process, because the + other context moved the directory it is in. + "diverge" is a mapping of source name -> list of destination names for divergent renames. @@ -183,16 +189,16 @@ """ # avoid silly behavior for update from empty dir if not c1 or not c2 or c1 == c2: - return {}, {}, {} + return {}, {}, {}, {} # avoid silly behavior for parent -> working dir if c2.node() is None and c1.node() == repo.dirstate.p1(): - return repo.dirstate.copies(), {}, {} + return repo.dirstate.copies(), {}, {}, {} limit = _findlimit(repo, c1.rev(), c2.rev()) if limit is None: # no common ancestor, no copies - return {}, {}, {} + return {}, {}, {}, {} m1 = c1.manifest() m2 = c2.manifest() ma = ca.manifest() @@ -206,6 +212,7 @@ ctx = util.lrucachefunc(makectx) copy = {} + movewithdir = {} fullcopy = {} diverge = {} @@ -315,7 +322,7 @@ del diverge2 if not fullcopy: - return copy, diverge, renamedelete + return copy, movewithdir, diverge, renamedelete repo.ui.debug(" checking for directory renames\n") @@ -352,7 +359,7 @@ del d1, d2, invalid if not dirmove: - return copy, diverge, renamedelete + return copy, movewithdir, diverge, renamedelete for d in dirmove: repo.ui.debug(" dir %s -> %s\n" % (d, dirmove[d])) @@ -365,8 +372,8 @@ # new file added in a directory that was moved, move it df = dirmove[d] + f[len(d):] if df not in copy: - copy[f] = df - repo.ui.debug(" file %s -> %s\n" % (f, copy[f])) + movewithdir[f] = df + repo.ui.debug(" file %s -> %s\n" % (f, df)) break - return copy, diverge, renamedelete + return copy, movewithdir, diverge, renamedelete