##// END OF EJS Templates
color: labeled text should be passed to ui.write() as ui.labeled...
color: labeled text should be passed to ui.write() as ui.labeled Some implementations of ui.label() (HTML versions in particular) must escape the provided text and then markup the text with their tags. When this marked up text is then passed to ui.write(), we must label the text as 'ui.labeled' so the implementation knows not to escape it a second time (exposing the initial markup). This required the addition of a 'ui.plain' label for text that is purposefully not marked up. I was a little pedantic here, passing even ' ' strings to ui.label() when it would be included with other labeled text in a ui.write() call. But it seemed appropriate to lean to the side of caution.

File last commit:

r11154:17031fea stable
r11302:e1dde736 default
Show More
bundlerepo.py
305 lines | 10.8 KiB | text/x-python | PythonLexer
Martin Geisler
put license and copyright info into comment blocks
r8226 # bundlerepo.py - repository class for viewing uncompressed bundles
#
# Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com>
#
# This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942
Martin Geisler
turn some comments back into module docstrings
r8227 """Repository class for viewing uncompressed bundles.
This provides a read-only repository interface to bundles as if they
were part of the actual repository.
"""
Peter Arrenbrecht
cleanup: drop unused imports
r7873 from node import nullid
Matt Mackall
Simplify i18n imports
r3891 from i18n import _
Simon Heimberg
separate import lines from mercurial and general python modules
r8312 import os, struct, bz2, zlib, tempfile, shutil
import changegroup, util, mdiff
Peter Arrenbrecht
cleanup: drop unused imports
r7873 import localrepo, changelog, manifest, filelog, revlog, error
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):
Matt Mackall
revlog: don't pass datafile as an argument
r4257 def __init__(self, opener, indexfile, bundlefile,
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 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)
#
Matt Mackall
revlog: don't pass datafile as an argument
r4257 revlog.revlog.__init__(self, opener, indexfile)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 self.bundlefile = bundlefile
mason@suse.com
Fix bundle repos to use an index tuple consistent with revlogng...
r2074 self.basemap = {}
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)
Matt Mackall
add __len__ and __iter__ methods to repo and revlog
r6750 n = len(self)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 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:
Martin Geisler
i18n: mark strings for translation in Mercurial
r6953 raise util.Abort(_("invalid changegroup"))
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 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:
Sune Foldager
bundlerepo: fix small bug in exception raising
r9650 raise error.LookupError(p, self.indexfile,
Matt Mackall
errors: move revlog errors...
r7633 _("unknown parent"))
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 if linkmapper is None:
link = n
else:
link = linkmapper(cs)
if not prev:
prev = p1
Benoit Boissinot
fix bundlerepo broken by 4205f626dc05...
r5167 # start, size, full unc. size, base (unused), link, p1, p2, node
e = (revlog.offset_type(start, 0), size, -1, -1, link,
Matt Mackall
revlog: add a magic null revision to our index...
r4979 self.rev(p1), self.rev(p2), node)
mason@suse.com
Fix bundle repos to use an index tuple consistent with revlogng...
r2074 self.basemap[n] = prev
Matt Mackall
revlog: add a magic null revision to our index...
r4979 self.index.insert(-1, e)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 self.nodemap[node] = n
prev = node
n += 1
def bundle(self, rev):
"""is rev from the bundle"""
if rev < 0:
return False
mason@suse.com
Fix bundle repos to use an index tuple consistent with revlogng...
r2074 return rev in self.basemap
Matt Mackall
many, many trivial check-code fixups
r10282 def bundlebase(self, rev):
return self.basemap[rev]
Benoit Boissinot
bundlerepo: keep the bundlerevlog interface in sync with revlog
r9676 def _chunk(self, rev):
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 # 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: keep the bundlerevlog interface in sync with revlog
r9676 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:
Benoit Boissinot
bundlerepo: keep the bundlerevlog interface in sync with revlog
r9676 return self._chunk(rev2)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 elif not self.bundle(rev1) and not self.bundle(rev2):
Benoit Boissinot
bundlerepo: it was meant to be revdiff() instead of chunk()
r4028 return revlog.revlog.revdiff(self, rev1, rev2)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942
Matt Mackall
revlog: eliminate diff and patches functions...
r4989 return mdiff.textdiff(self.revision(self.node(rev1)),
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 self.revision(self.node(rev2)))
def revision(self, node):
"""return an uncompressed revision of a given"""
Matt Mackall
many, many trivial check-code fixups
r10282 if node == nullid:
return ""
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942
text = None
chain = []
iter_node = node
rev = self.rev(iter_node)
# reconstruct the revision if it is from a changegroup
while self.bundle(rev):
Matt Mackall
revlog: mark cache private
r4984 if self._cache and self._cache[0] == iter_node:
text = self._cache[2]
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 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:
Benoit Boissinot
bundlerepo: keep the bundlerevlog interface in sync with revlog
r9676 delta = self._chunk(chain.pop())
Matt Mackall
revlog: eliminate diff and patches functions...
r4989 text = mdiff.patches(text, [delta])
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942
p1, p2 = self.parents(node)
Benoit Boissinot
bundlerepo: remove relative import, fix a comment
r1946 if node != revlog.hash(text, p1, p2):
Matt Mackall
errors: move revlog errors...
r7633 raise error.RevlogError(_("integrity check failed on %s:%d")
Benoit Boissinot
indent: fix alignment
r2257 % (self.datafile, self.rev(node)))
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942
Matt Mackall
revlog: mark cache private
r4984 self._cache = (node, self.rev(node), text)
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 return text
def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
raise NotImplementedError
Peter Arrenbrecht
drop superfluous param from revlog.addgroup()
r6647 def addgroup(self, revs, linkmapper, transaction):
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 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)
Matt Mackall
revlog: don't pass datafile as an argument
r4257 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile)
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 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)
Matt Mackall
revlog: don't pass datafile as an argument
r4257 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile,
linkmapper)
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 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)
Matt Mackall
revlog: don't pass datafile as an argument
r4257 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile,
linkmapper)
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 bundlerepository(localrepo.localrepository):
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 def __init__(self, ui, path, bundlename):
John Mulligan
Add ability to directly clone from all-history bundles...
r6314 self._tempparent = None
try:
localrepo.localrepository.__init__(self, ui, path)
Matt Mackall
error: move repo errors...
r7637 except error.RepoError:
John Mulligan
Add ability to directly clone from all-history bundles...
r6314 self._tempparent = tempfile.mkdtemp()
Martin Geisler
coding style: use a space after comma...
r9198 localrepo.instance(ui, self._tempparent, 1)
John Mulligan
Add ability to directly clone from all-history bundles...
r6314 localrepo.localrepository.__init__(self, ui, self._tempparent)
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673
Peter Arrenbrecht
bundlerepo: fix inconsistency of parsed and internal name (issue #821)
r6129 if path:
Alexander Solovyov
expand paths to local repository or bundle in appropriate classes...
r11154 self._url = 'bundle:' + util.expandpath(path) + '+' + bundlename
Peter Arrenbrecht
bundlerepo: fix inconsistency of parsed and internal name (issue #821)
r6129 else:
self._url = 'bundle:' + bundlename
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673
Benoit Boissinot
add support for compressed bundle repositories...
r2273 self.tempfile = None
self.bundlefile = open(bundlename, "rb")
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)
Benoit Allard
add support for HG10GZ bundles to bundlerepo.bundlerevlog()
r6569 elif (header == "HG10BZ") or (header == "HG10GZ"):
Benoit Boissinot
add support for compressed bundle repositories...
r2273 fdtemp, temp = tempfile.mkstemp(prefix="hg-bundle-",
suffix=".hg10un", dir=self.path)
self.tempfile = temp
fptemp = os.fdopen(fdtemp, 'wb')
def generator(f):
Benoit Allard
add support for HG10GZ bundles to bundlerepo.bundlerevlog()
r6569 if header == "HG10BZ":
zd = bz2.BZ2Decompressor()
zd.decompress("BZ")
elif header == "HG10GZ":
zd = zlib.decompressobj()
Benoit Boissinot
add support for compressed bundle repositories...
r2273 for chunk in f:
yield zd.decompress(chunk)
gen = generator(util.filechunkiter(self.bundlefile, 4096))
try:
fptemp.write("HG10UN")
for chunk in gen:
fptemp.write(chunk)
finally:
fptemp.close()
self.bundlefile.close()
self.bundlefile = open(self.tempfile, "rb")
# seek right after the header
self.bundlefile.seek(6)
Benoit Boissinot
use HG10UN header for uncompressed bundle...
r1980 elif header == "HG10UN":
Benoit Boissinot
add support for compressed bundle repositories...
r2273 # nothing to do
Benoit Boissinot
use HG10UN header for uncompressed bundle...
r1980 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 # dict with the mapping 'filename' -> position in the bundle
self.bundlefilespos = {}
Brendan Cully
Make bundlerepo lazier...
r5262
Matt Mackall
localrepo: use propertycache
r8260 @util.propertycache
def changelog(self):
c = bundlechangelog(self.sopener, self.bundlefile)
self.manstart = self.bundlefile.tell()
return c
@util.propertycache
def manifest(self):
self.bundlefile.seek(self.manstart)
m = bundlemanifest(self.sopener, self.bundlefile, self.changelog.rev)
self.filestart = self.bundlefile.tell()
return m
@util.propertycache
def manstart(self):
self.changelog
return self.manstart
@util.propertycache
def filestart(self):
self.manifest
return self.filestart
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 def url(self):
return self._url
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 def file(self, f):
Brendan Cully
Make bundlerepo lazier...
r5262 if not self.bundlefilespos:
self.bundlefile.seek(self.filestart)
while 1:
chunk = changegroup.getchunk(self.bundlefile)
if not chunk:
break
self.bundlefilespos[chunk] = 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 if f[0] == '/':
f = f[1:]
if f in self.bundlefilespos:
self.bundlefile.seek(self.bundlefilespos[f])
Benoit Boissinot
introduce localrepo.spath for the store path, sopener fixes
r3791 return bundlefilelog(self.sopener, f, self.bundlefile,
Benoit Boissinot
add bundlerepo.py: a read-only repo that can use uncompressed bundles...
r1942 self.changelog.rev)
else:
Benoit Boissinot
introduce localrepo.spath for the store path, sopener fixes
r3791 return filelog.filelog(self.sopener, 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()
Benoit Boissinot
add support for compressed bundle repositories...
r2273
def __del__(self):
Alexis S. L. Carvalho
bundlerepo: avoid exception in __del__ when the bundle doesn't exist...
r3429 bundlefile = getattr(self, 'bundlefile', None)
if bundlefile and not bundlefile.closed:
bundlefile.close()
tempfile = getattr(self, 'tempfile', None)
if tempfile is not None:
os.unlink(tempfile)
John Mulligan
Add ability to directly clone from all-history bundles...
r6314 if self._tempparent:
shutil.rmtree(self._tempparent, True)
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740
Matt Mackall
clone: use cancopy
r6315 def cancopy(self):
return False
Dirkjan Ochtman
bundlerepo doesn't really have a dirstate, throw AttributeError if requested
r7435 def getcwd(self):
return os.getcwd() # always outside the repo
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740 def instance(ui, path, create):
if create:
raise util.Abort(_('cannot create new bundle repository'))
Peter Arrenbrecht
Fix income/pull with bundle and -R (issue 820)....
r5664 parentpath = ui.config("bundle", "mainreporoot", "")
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):]
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740 path = util.drop_scheme('file', path)
if path.startswith('bundle:'):
path = util.drop_scheme('bundle', path)
s = path.split("+", 1)
if len(s) == 1:
Peter Arrenbrecht
Fix income/pull with bundle and -R (issue 820)....
r5664 repopath, bundlename = parentpath, s[0]
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740 else:
repopath, bundlename = s
else:
Peter Arrenbrecht
Fix income/pull with bundle and -R (issue 820)....
r5664 repopath, bundlename = parentpath, path
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740 return bundlerepository(ui, repopath, bundlename)