##// END OF EJS Templates
add checking for invalid entries in tag files...
add checking for invalid entries in tag files safely parse the differents tag files, output warning when parsing an invalid entry.

File last commit:

r1981:736b6c96 default
r1986:719cf07b default
Show More
bundlerepo.py
201 lines | 7.5 KiB | text/x-python | PythonLexer
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 """
bundlerepo.py - repository class for viewing uncompressed bundles
This provides a read-only repository interface to bundles as if
they were part of the actual repository.
Copyright 2006 Benoit Boissinot <benoit.boissinot@ens-lyon.org>
This software may be used and distributed according to the terms
of the GNU General Public License, incorporated herein by reference.
"""
from node import *
from i18n import gettext as _
from demandload import demandload
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981 demandload(globals(), "changegroup util os struct")
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 import localrepo, changelog, manifest, filelog, revlog
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 class bundlerevlog(revlog.revlog):
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 def __init__(self, opener, indexfile, datafile, bundlefile,
linkmapper=None):
# How it works:
# to retrieve a revision, we need to know the offset of
# the revision in the bundlefile (an opened file).
#
# We store this offset in the index (start), to differentiate a
# rev in the bundle and from a rev in the revlog, we check
# len(index[r]). If the tuple is bigger than 7, it is a bundle
# (it is bigger since we store the node to which the delta is)
#
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 revlog.revlog.__init__(self, opener, indexfile, datafile)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 self.bundlefile = bundlefile
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981 def chunkpositer():
for chunk in changegroup.chunkiter(bundlefile):
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 pos = bundlefile.tell()
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981 yield chunk, pos - len(chunk)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 n = self.count()
prev = None
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981 for chunk, start in chunkpositer():
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 size = len(chunk)
if size < 80:
raise util.Abort("invalid changegroup")
start += 80
size -= 80
node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80])
if node in self.nodemap:
prev = node
continue
for p in (p1, p2):
if not p in self.nodemap:
raise RevlogError(_("unknown parent %s") % short(p1))
if linkmapper is None:
link = n
else:
link = linkmapper(cs)
if not prev:
prev = p1
# start, size, base is not used, link, p1, p2, delta ref
e = (start, size, None, link, p1, p2, node, prev)
self.index.append(e)
self.nodemap[node] = n
prev = node
n += 1
def bundle(self, rev):
"""is rev from the bundle"""
if rev < 0:
return False
return len(self.index[rev]) > 7
def bundlebase(self, rev): return self.index[rev][7]
def chunk(self, rev):
# Warning: in case of bundle, the diff is against bundlebase,
# not against rev - 1
# XXX: could use some caching
if not self.bundle(rev):
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 return revlog.revlog.chunk(self, rev)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 self.bundlefile.seek(self.start(rev))
return self.bundlefile.read(self.length(rev))
def revdiff(self, rev1, rev2):
"""return or calculate a delta between two revisions"""
if self.bundle(rev1) and self.bundle(rev2):
# hot path for bundle
revb = self.rev(self.bundlebase(rev2))
if revb == rev1:
return self.chunk(rev2)
elif not self.bundle(rev1) and not self.bundle(rev2):
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 return revlog.revlog.chunk(self, rev1, rev2)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942
return self.diff(self.revision(self.node(rev1)),
self.revision(self.node(rev2)))
def revision(self, node):
"""return an uncompressed revision of a given"""
if node == nullid: return ""
text = None
chain = []
iter_node = node
rev = self.rev(iter_node)
# reconstruct the revision if it is from a changegroup
while self.bundle(rev):
if self.cache and self.cache[0] == iter_node:
text = self.cache[2]
break
chain.append(rev)
iter_node = self.bundlebase(rev)
rev = self.rev(iter_node)
if text is None:
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 text = revlog.revlog.revision(self, iter_node)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942
while chain:
delta = self.chunk(chain.pop())
text = self.patches(text, [delta])
p1, p2 = self.parents(node)
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 if node != revlog.hash(text, p1, p2):
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 raise RevlogError(_("integrity check failed on %s:%d")
% (self.datafile, self.rev(node)))
self.cache = (node, rev, text)
return text
def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
raise NotImplementedError
def addgroup(self, revs, linkmapper, transaction, unique=0):
raise NotImplementedError
def strip(self, rev, minlink):
raise NotImplementedError
def checksize(self):
raise NotImplementedError
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 class bundlechangelog(bundlerevlog, changelog.changelog):
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 def __init__(self, opener, bundlefile):
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 changelog.changelog.__init__(self, opener)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 bundlerevlog.__init__(self, opener, "00changelog.i", "00changelog.d",
bundlefile)
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 class bundlemanifest(bundlerevlog, manifest.manifest):
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 def __init__(self, opener, bundlefile, linkmapper):
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 manifest.manifest.__init__(self, opener)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 bundlerevlog.__init__(self, opener, self.indexfile, self.datafile,
bundlefile, linkmapper)
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 class bundlefilelog(bundlerevlog, filelog.filelog):
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 def __init__(self, opener, path, bundlefile, linkmapper):
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 filelog.filelog.__init__(self, opener, path)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 bundlerevlog.__init__(self, opener, self.indexfile, self.datafile,
bundlefile, linkmapper)
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 class bundlerepository(localrepo.localrepository):
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 def __init__(self, ui, path, bundlename):
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 localrepo.localrepository.__init__(self, ui, path)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 f = open(bundlename, "rb")
s = os.fstat(f.fileno())
self.bundlefile = f
Benoit Boissinot
use HG10UN header for uncompressed bundle...
r1980 header = self.bundlefile.read(6)
if not header.startswith("HG"):
raise util.Abort(_("%s: not a Mercurial bundle file") % bundlename)
elif not header.startswith("HG10"):
raise util.Abort(_("%s: unknown bundle version") % bundlename)
elif header == "HG10BZ":
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 raise util.Abort(_("%s: compressed bundle not supported")
% bundlename)
Benoit Boissinot
use HG10UN header for uncompressed bundle...
r1980 elif header == "HG10UN":
# uncompressed bundle supported
pass
else:
raise util.Abort(_("%s: unknown bundle compression type")
% bundlename)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 self.changelog = bundlechangelog(self.opener, self.bundlefile)
self.manifest = bundlemanifest(self.opener, self.bundlefile,
self.changelog.rev)
# dict with the mapping 'filename' -> position in the bundle
self.bundlefilespos = {}
while 1:
Thomas Arendsen Hein
make incoming work via ssh (issue139); move chunk code into separate module....
r1981 f = changegroup.getchunk(self.bundlefile)
if not f:
break
self.bundlefilespos[f] = self.bundlefile.tell()
for c in changegroup.chunkiter(self.bundlefile):
pass
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942
def dev(self):
return -1
def file(self, f):
if f[0] == '/':
f = f[1:]
if f in self.bundlefilespos:
self.bundlefile.seek(self.bundlefilespos[f])
return bundlefilelog(self.opener, f, self.bundlefile,
self.changelog.rev)
else:
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 return filelog.filelog(self.opener, f)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942
Thomas Arendsen Hein
imported patch /home/thomas/fix-incoming-abortion4.patch
r1971 def close(self):
"""Close assigned bundle file immediately."""
self.bundlefile.close()