##// END OF EJS Templates
whitespace cleanup
whitespace cleanup

File last commit:

r3407:63545567 beta
r3413:d79f3505 beta
Show More
unionrepo.py
208 lines | 7.3 KiB | text/x-python | PythonLexer
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 # unionrepo.py - repository class for viewing union of repository changesets
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 #
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 # Derived from bundlerepo.py
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 # Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com>
# Copyright 2013 Unity Technologies, Mads Kiilerich <madski@unity3d.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 """Repository class for "in-memory pull" of one local repository to another,
allowing operations like diff and log with revsets.
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 """
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 import os
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 from mercurial.node import nullid
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 from mercurial.i18n import _
from mercurial import util, mdiff, cmdutil, scmutil
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 from mercurial import localrepo, changelog, manifest, filelog, revlog
class unionrevlog(revlog.revlog):
def __init__(self, opener, indexfile, revlog2, linkmapper):
# How it works:
# To retrieve a revision, we just need to know the node id so we can
# look it up in revlog2.
#
# To differentiate a rev in the second revlog from a rev in the revlog,
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 # we check revision against repotiprev.
opener = scmutil.readonlyvfs(opener)
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 revlog.revlog.__init__(self, opener, indexfile)
self.revlog2 = revlog2
n = len(self)
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 self.repotiprev = n - 1
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 self.bundlerevs = set() # used by 'bundle()' revset expression
for rev2 in self.revlog2:
rev = self.revlog2.index[rev2]
# rev numbers - in revlog2, very different from self.rev
_start, _csize, _rsize, _base, linkrev, p1rev, p2rev, node = rev
if linkmapper is None: # link is to same revlog
assert linkrev == rev2 # we never link back
link = n
else: # rev must be mapped from repo2 cl to unified cl by linkmapper
link = linkmapper(linkrev)
if node in self.nodemap:
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 # this happens for the common revlog revisions
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 self.bundlerevs.add(self.nodemap[node])
continue
p1node = self.revlog2.node(p1rev)
p2node = self.revlog2.node(p2rev)
e = (None, None, None, None,
link, self.rev(p1node), self.rev(p2node), node)
self.index.insert(-1, e)
self.nodemap[node] = n
self.bundlerevs.add(n)
n += 1
def _chunk(self, rev):
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 if rev <= self.repotiprev:
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 return revlog.revlog._chunk(self, rev)
return self.revlog2._chunk(self.node(rev))
def revdiff(self, rev1, rev2):
"""return or calculate a delta between two revisions"""
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 if rev1 > self.repotiprev and rev2 > self.repotiprev:
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 return self.revlog2.revdiff(
self.revlog2.rev(self.node(rev1)),
self.revlog2.rev(self.node(rev2)))
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 elif rev1 <= self.repotiprev and rev2 <= self.repotiprev:
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 return revlog.revlog.revdiff(self, rev1, rev2)
return mdiff.textdiff(self.revision(self.node(rev1)),
self.revision(self.node(rev2)))
def revision(self, nodeorrev):
"""return an uncompressed revision of a given node or revision
number.
"""
if isinstance(nodeorrev, int):
rev = nodeorrev
node = self.node(rev)
else:
node = nodeorrev
rev = self.rev(node)
if node == nullid:
return ""
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 if rev > self.repotiprev:
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 text = self.revlog2.revision(node)
self._cache = (node, rev, text)
else:
text = revlog.revlog.revision(self, rev)
# already cached
return text
def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
raise NotImplementedError
def addgroup(self, revs, linkmapper, transaction):
raise NotImplementedError
def strip(self, rev, minlink):
raise NotImplementedError
def checksize(self):
raise NotImplementedError
class unionchangelog(unionrevlog, changelog.changelog):
def __init__(self, opener, opener2):
changelog.changelog.__init__(self, opener)
linkmapper = None
changelog2 = changelog.changelog(opener2)
unionrevlog.__init__(self, opener, self.indexfile, changelog2,
linkmapper)
class unionmanifest(unionrevlog, manifest.manifest):
def __init__(self, opener, opener2, linkmapper):
manifest.manifest.__init__(self, opener)
manifest2 = manifest.manifest(opener2)
unionrevlog.__init__(self, opener, self.indexfile, manifest2,
linkmapper)
class unionfilelog(unionrevlog, filelog.filelog):
def __init__(self, opener, path, opener2, linkmapper, repo):
filelog.filelog.__init__(self, opener, path)
filelog2 = filelog.filelog(opener2, path)
unionrevlog.__init__(self, opener, self.indexfile, filelog2,
linkmapper)
self._repo = repo
def _file(self, f):
self._repo.file(f)
class unionpeer(localrepo.localpeer):
def canpush(self):
return False
class unionrepository(localrepo.localrepository):
def __init__(self, ui, path, path2):
localrepo.localrepository.__init__(self, ui, path)
self.ui.setconfig('phases', 'publish', False)
self._url = 'union:%s+%s' % (util.expandpath(path),
util.expandpath(path2))
self.repo2 = localrepo.localrepository(ui, path2)
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 @localrepo.unfilteredpropertycache
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 def changelog(self):
return unionchangelog(self.sopener, self.repo2.sopener)
def _clrev(self, rev2):
"""map from repo2 changelog rev to temporary rev in self.changelog"""
node = self.repo2.changelog.node(rev2)
return self.changelog.rev(node)
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 @localrepo.unfilteredpropertycache
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 def manifest(self):
return unionmanifest(self.sopener, self.repo2.sopener,
self._clrev)
def url(self):
return self._url
def file(self, f):
return unionfilelog(self.sopener, f, self.repo2.sopener,
self._clrev, self)
def close(self):
self.repo2.close()
def cancopy(self):
return False
def peer(self):
return unionpeer(self)
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 def getcwd(self):
return os.getcwd() # always outside the repo
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 def instance(ui, path, create):
Mads Kiilerich
update unionrepo for Mercurial 2.5.1
r3407 if create:
raise util.Abort(_('cannot create new union repository'))
parentpath = ui.config("bundle", "mainreporoot", "")
if not parentpath:
# try to find the correct path to the working directory repo
parentpath = cmdutil.findrepo(os.getcwd())
if parentpath is None:
parentpath = ''
if parentpath:
# Try to make the full path relative so we get a nice, short URL.
# In particular, we don't want temp dir names in test outputs.
cwd = os.getcwd()
if parentpath == cwd:
parentpath = ''
else:
cwd = os.path.join(cwd,'')
if parentpath.startswith(cwd):
parentpath = parentpath[len(cwd):]
if path.startswith('union:'):
s = path.split(":", 1)[1].split("+", 1)
if len(s) == 1:
repopath, repopath2 = parentpath, s[0]
else:
repopath, repopath2 = s
else:
repopath, repopath2 = parentpath, path
Mads Kiilerich
introduce unionrepo repository class for viewing union of repositories
r3302 return unionrepository(ui, repopath, repopath2)