Mercurial > public > mercurial-scm > hg-stable
diff mercurial/copies.py @ 24803:e89f909edffa stable 3.4-rc
merge default into stable for 3.4 freeze
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 16 Apr 2015 20:57:51 -0500 |
parents | 4906dc0e038c |
children | 708b19c18adf 0f28815ef066 |
line wrap: on
line diff
--- a/mercurial/copies.py Thu Apr 16 22:33:53 2015 +0900 +++ b/mercurial/copies.py Thu Apr 16 20:57:51 2015 -0500 @@ -8,10 +8,6 @@ import util import heapq -def _nonoverlap(d1, d2, d3): - "Return list of elements in d1 not in d2 or d3" - return sorted([d for d in d1 if d not in d3 and d not in d2]) - def _dirname(f): s = f.rfind("/") if s == -1: @@ -144,7 +140,19 @@ del c[k] return c -def _forwardcopies(a, b): +def _computeforwardmissing(a, b, match=None): + """Computes which files are in b but not a. + This is its own function so extensions can easily wrap this call to see what + files _forwardcopies is about to process. + """ + ma = a.manifest() + mb = b.manifest() + if match: + ma = ma.matches(match) + mb = mb.matches(match) + return mb.filesnotin(ma) + +def _forwardcopies(a, b, match=None): '''find {dst@b: src@a} copy mapping where a is an ancestor of b''' # check for working copy @@ -167,9 +175,7 @@ # we currently don't try to find where old files went, too expensive # this means we can miss a case like 'hg rm b; hg cp a b' cm = {} - missing = set(b.manifest().iterkeys()) - missing.difference_update(a.manifest().iterkeys()) - + missing = _computeforwardmissing(a, b, match=match) ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True) for f in missing: fctx = b[f] @@ -197,16 +203,36 @@ r[v] = k return r -def pathcopies(x, y): +def pathcopies(x, y, match=None): '''find {dst@y: src@x} copy mapping for directed compare''' if x == y or not x or not y: return {} a = y.ancestor(x) if a == x: - return _forwardcopies(x, y) + return _forwardcopies(x, y, match=match) if a == y: return _backwardrenames(x, y) - return _chain(x, y, _backwardrenames(x, a), _forwardcopies(a, y)) + return _chain(x, y, _backwardrenames(x, a), + _forwardcopies(a, y, match=match)) + +def _computenonoverlap(repo, c1, c2, addedinm1, addedinm2): + """Computes, based on addedinm1 and addedinm2, the files exclusive to c1 + and c2. This is its own function so extensions can easily wrap this call + to see what files mergecopies is about to process. + + Even though c1 and c2 are not used in this function, they are useful in + other extensions for being able to read the file nodes of the changed files. + """ + u1 = sorted(addedinm1 - addedinm2) + u2 = sorted(addedinm2 - addedinm1) + + if u1: + repo.ui.debug(" unmatched files in local:\n %s\n" + % "\n ".join(u1)) + if u2: + repo.ui.debug(" unmatched files in other:\n %s\n" + % "\n ".join(u2)) + return u1, u2 def mergecopies(repo, c1, c2, ca): """ @@ -288,15 +314,9 @@ repo.ui.debug(" searching for copies back to rev %d\n" % limit) - u1 = _nonoverlap(m1, m2, ma) - u2 = _nonoverlap(m2, m1, ma) - - if u1: - repo.ui.debug(" unmatched files in local:\n %s\n" - % "\n ".join(u1)) - if u2: - repo.ui.debug(" unmatched files in other:\n %s\n" - % "\n ".join(u2)) + addedinm1 = m1.filesnotin(ma) + addedinm2 = m2.filesnotin(ma) + u1, u2 = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2) for f in u1: ctx = setupctx(c1) @@ -320,7 +340,7 @@ else: diverge2.update(fl) # reverse map for below - bothnew = sorted([d for d in m1 if d in m2 and d not in ma]) + bothnew = sorted(addedinm1 & addedinm2) if bothnew: repo.ui.debug(" unmatched files new in both:\n %s\n" % "\n ".join(bothnew))