# HG changeset patch # User Sean Farley # Date 2013-08-12 04:05:08 # Node ID 4e72ffec8c2d3d55a480c116d7263e2a8c464fae # Parent 896193a9cab4e06fd7754a20a5bb63a0e3fb2b0d basefilectx: move ancestor from filectx diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -661,6 +661,55 @@ class basefilectx(object): return zip(hist[base][0], hist[base][1].splitlines(True)) + def ancestor(self, fc2, actx): + """ + find the common ancestor file context, if any, of self, and fc2 + + actx must be the changectx of the common ancestor + of self's and fc2's respective changesets. + """ + + # the easy case: no (relevant) renames + if fc2.path() == self.path() and self.path() in actx: + return actx[self.path()] + + # the next easiest cases: unambiguous predecessor (name trumps + # history) + if self.path() in actx and fc2.path() not in actx: + return actx[self.path()] + if fc2.path() in actx and self.path() not in actx: + return actx[fc2.path()] + + # prime the ancestor cache for the working directory + acache = {} + for c in (self, fc2): + if c.filenode() is None: + pl = [(n.path(), n.filenode()) for n in c.parents()] + acache[(c._path, None)] = pl + + flcache = {self._repopath:self._filelog, fc2._repopath:fc2._filelog} + def parents(vertex): + if vertex in acache: + return acache[vertex] + f, n = vertex + if f not in flcache: + flcache[f] = self._repo.file(f) + fl = flcache[f] + pl = [(f, p) for p in fl.parents(n) if p != nullid] + re = fl.renamed(n) + if re: + pl.append(re) + acache[vertex] = pl + return pl + + a, b = (self._path, self._filenode), (fc2._path, fc2._filenode) + v = ancestor.genericancestor(a, b, parents) + if v: + f, n = v + return filectx(self._repo, f, fileid=n, filelog=flcache[f]) + + return None + class filectx(basefilectx): """A filecontext object makes access to data related to a particular filerevision convenient.""" @@ -752,55 +801,6 @@ class filectx(basefilectx): return [filectx(self._repo, self._path, fileid=x, filelog=self._filelog) for x in c] - def ancestor(self, fc2, actx): - """ - find the common ancestor file context, if any, of self, and fc2 - - actx must be the changectx of the common ancestor - of self's and fc2's respective changesets. - """ - - # the easy case: no (relevant) renames - if fc2.path() == self.path() and self.path() in actx: - return actx[self.path()] - - # the next easiest cases: unambiguous predecessor (name trumps - # history) - if self.path() in actx and fc2.path() not in actx: - return actx[self.path()] - if fc2.path() in actx and self.path() not in actx: - return actx[fc2.path()] - - # prime the ancestor cache for the working directory - acache = {} - for c in (self, fc2): - if c.filenode() is None: - pl = [(n.path(), n.filenode()) for n in c.parents()] - acache[(c._path, None)] = pl - - flcache = {self._repopath:self._filelog, fc2._repopath:fc2._filelog} - def parents(vertex): - if vertex in acache: - return acache[vertex] - f, n = vertex - if f not in flcache: - flcache[f] = self._repo.file(f) - fl = flcache[f] - pl = [(f, p) for p in fl.parents(n) if p != nullid] - re = fl.renamed(n) - if re: - pl.append(re) - acache[vertex] = pl - return pl - - a, b = (self._path, self._filenode), (fc2._path, fc2._filenode) - v = ancestor.genericancestor(a, b, parents) - if v: - f, n = v - return filectx(self._repo, f, fileid=n, filelog=flcache[f]) - - return None - def ancestors(self, followfirst=False): visit = {} c = self