Mercurial > hg > hg-git
changeset 613:bf8518b09d57
overlays: fix incoming support for hg 2.8
This was crafted mostly via a bunch of aimless flailing in the
code. I'm pretty well convinced at this point that the incoming
support needs to be rewritten slightly to behave properly in the new
world order (specifically, the overlayrepo class probably should be
subclassing localrepo, or else more directly reimplementing things
instead of trying to forward methods.)
author | Augie Fackler <raf@durin42.com> |
---|---|
date | Sat, 05 Oct 2013 17:40:50 -0400 |
parents | 60a4d55fdaa6 |
children | 5f00e72ac3df |
files | hggit/overlay.py |
diffstat | 1 files changed, 65 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/hggit/overlay.py +++ b/hggit/overlay.py @@ -4,8 +4,11 @@ # # incomplete, implemented on demand +from mercurial import ancestor +from mercurial import manifest from mercurial import context from mercurial.node import bin, hex, nullid +from mercurial import localrepo class overlaymanifest(object): def __init__(self, repo, sha): @@ -26,6 +29,9 @@ self.load() return self._map.keys() + def iterkeys(self): + return iter(self.keys()) + def flags(self, path): self.load() @@ -84,6 +90,9 @@ def ancestors(self): return [self, self] + def filenode(self): + return nullid + def rev(self): return -1 @@ -100,13 +109,17 @@ class overlaychangectx(context.changectx): def __init__(self, repo, sha): self.repo = repo + if not isinstance(sha, basestring): + sha = sha.hex() self.commit = repo.handler.git.get_object(sha) + self._overlay = getattr(repo, 'gitoverlay', repo) + self._rev = self._overlay.rev(bin(self.commit.id)) def node(self): return bin(self.commit.id) def rev(self): - return self.repo.rev(bin(self.commit.id)) + return self._rev def date(self): return self.commit.author_time, self.commit.author_timezone @@ -142,11 +155,11 @@ return [] def manifest(self): - return overlaymanifest(self.repo, self.commit.tree) + return overlaymanifest(self._overlay, self.commit.tree) def filectx(self, path, filelog=None): mf = self.manifest() - return overlayfilectx(self.repo, path, mf[path]) + return overlayfilectx(self._overlay, path, mf[path]) def flags(self, path): mf = self.manifest() @@ -189,6 +202,16 @@ return [p1, p2] + def ancestor(self, a, b): + anode = self.repo.nodemap.get(a) + bnode = self.repo.nodemap.get(b) + if anode is None and bnode is None: + return self.base.ancestor(a, b) + ancs = ancestor.ancestors(self.parentrevs, a, b) + if ancs: + return min(map(self.node, ancs)) + return nullid + def parentrevs(self, rev): return [self.rev(p) for p in self.parents(self.node(rev))] @@ -212,18 +235,32 @@ def __len__(self): return len(self.repo.handler.repo) + len(self.repo.revmap) +class overlaymanifestlog(overlayrevlog): + def read(self, sha): + if sha == nullid: + return manifest.manifestdict() + return overlaymanifest(self.repo, sha) + +class overlaychangelog(overlayrevlog): + def read(self, sha): + if isinstance(sha, int): + sha = self.node(sha) + if sha == nullid: + return (nullid, "", (0, 0), [], "", {}) + return overlaychangectx(self.repo, sha) + class overlayrepo(object): def __init__(self, handler, commits, refs): self.handler = handler - self.changelog = overlayrevlog(self, handler.repo.changelog) - self.manifest = overlayrevlog(self, handler.repo.manifest) + self.changelog = overlaychangelog(self, handler.repo.changelog) + self.manifest = overlaymanifestlog(self, handler.repo.manifest) # for incoming -p self.root = handler.repo.root self.getcwd = handler.repo.getcwd - self.status = handler.repo.status + # self.status = handler.repo.status self.ui = handler.repo.ui self.revmap = None @@ -238,6 +275,28 @@ return self.handler.repo[n] return overlaychangectx(self, n) + def _handlerhack(self, method, *args, **kwargs): + nothing = object() + r = self.handler.repo + oldhandler = getattr(r, 'handler', nothing) + oldoverlay = getattr(r, 'gitoverlay', nothing) + r.handler = self.handler + r.gitoverlay = self + try: + return getattr(r, method)(*args, **kwargs) + finally: + if oldhandler is nothing: + del r.handler + else: + r.handler = oldhandler + if oldoverlay is nothing: + del r.gitoverlay + else: + r.gitoverlay = oldoverlay + + def status(self, *args, **kwargs): + return self._handlerhack('status', *args, **kwargs) + def node(self, n): """Returns an Hg or Git hash for the specified Git hash""" if bin(n) in self.revmap: