##// END OF EJS Templates
changegroup: port to emitrevisions() (issue5976)...
changegroup: port to emitrevisions() (issue5976) We now have a unified API for emitting revision data from a storage backend. It handles sorting nodes and the complicated delta versus revision decisions for us. This commit ports changegroup to that API. There should be no behavior changes for changegroups not using ellipsis. And lack of test changes seems to confirm that. There are some changes for ellipsis mode, however. Before, when sending an ellipsis revision, we would always send a fulltext revision (as opposed to a delta). There was a TODO tracking this open item. One of the things the emitrevisions() API does for us is figure out whether we can safely emit a delta. So, it is now possible for ellipsis revisions to be sent as deltas! (It does this by not assuming parent/ancestor revisions are available and tracking which revisions have been sent out.) Because we eliminated the list of revision delta request objects, performance has improved substantially: $ hg perfchangegroupchangelog before: ! wall 24.348077 comb 24.330000 user 24.140000 sys 0.190000 (best of 3) after: ! wall 18.245911 comb 18.240000 user 18.100000 sys 0.140000 (best of 3) That's a lot of overhead for creating a few hundred thousand Python objects! This is still a little slower than 4.7. Probably due to 23d582ca introducing a type for the revision/delta results. There is potentially room to optimize. But at some point we need to abstract storage in order to support alternate storage backends. Unfortunately that means using a Python data structure to represent results. And unfortunately there is overhead with every new Python object created. Differential Revision: https://phab.mercurial-scm.org/D4725

File last commit:

r39896:d9b3cc3d default
r39901:31b7e8e7 default
Show More
simplestorerepo.py
735 lines | 20.8 KiB | text/x-python | PythonLexer
/ tests / simplestorerepo.py
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 # simplestorerepo.py - Extension that swaps in alternate repository storage.
#
# Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Gregory Szorc
tests: conditionalize tests based on presence of revlogs for files...
r37356 # To use this with the test suite:
#
# $ HGREPOFEATURES="simplestore" ./run-tests.py \
# --extra-config-opt extensions.simplestore=`pwd`/simplestorerepo.py
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 from __future__ import absolute_import
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 import stat
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 from mercurial.i18n import _
from mercurial.node import (
bin,
hex,
nullid,
nullrev,
)
from mercurial.thirdparty import (
Gregory Szorc
repository: establish API for emitting revision deltas...
r39267 attr,
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 cbor,
)
from mercurial import (
ancestor,
Gregory Szorc
tests: disallow using simple store repo with bundlerepo...
r37364 bundlerepo,
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 error,
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 extensions,
localrepo,
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 mdiff,
pycompat,
Gregory Szorc
filelog: declare that filelog implements a storage interface...
r37459 repository,
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 revlog,
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 store,
Gregory Szorc
verify: allow suppressing warnings about extra files...
r37435 verify,
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 )
Gregory Szorc
tests: use interfaceutil in simplestorerepo...
r38565 from mercurial.utils import (
interfaceutil,
)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
# be specifying the version(s) of Mercurial they are tested with, or
# leave the attribute unspecified.
testedwith = 'ships-with-hg-core'
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 REQUIREMENT = 'testonly-simplestore'
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 def validatenode(node):
if isinstance(node, int):
raise ValueError('expected node; got int')
if len(node) != 20:
raise ValueError('expected 20 byte node')
def validaterev(rev):
if not isinstance(rev, int):
raise ValueError('expected int')
Gregory Szorc
global: replace most uses of RevlogError with StorageError (API)...
r39813 class simplestoreerror(error.StorageError):
pass
Gregory Szorc
repository: establish API for emitting revision deltas...
r39267 @interfaceutil.implementer(repository.irevisiondelta)
@attr.s(slots=True, frozen=True)
class simplestorerevisiondelta(object):
node = attr.ib()
p1node = attr.ib()
p2node = attr.ib()
basenode = attr.ib()
linknode = attr.ib()
flags = attr.ib()
baserevisionsize = attr.ib()
revision = attr.ib()
delta = attr.ib()
Gregory Szorc
tests: use interfaceutil in simplestorerepo...
r38565 @interfaceutil.implementer(repository.ifilestorage)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 class filestorage(object):
"""Implements storage for a tracked path.
Data is stored in the VFS in a directory corresponding to the tracked
path.
Index data is stored in an ``index`` file using CBOR.
Fulltext data is stored in files having names of the node.
"""
def __init__(self, svfs, path):
self._svfs = svfs
self._path = path
self._storepath = b'/'.join([b'data', path])
self._indexpath = b'/'.join([self._storepath, b'index'])
indexdata = self._svfs.tryread(self._indexpath)
if indexdata:
indexdata = cbor.loads(indexdata)
self._indexdata = indexdata or []
self._indexbynode = {}
self._indexbyrev = {}
Gregory Szorc
filelog: drop index attribute (API)...
r39896 self._index = []
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 self._refreshindex()
# This is used by changegroup code :/
self._generaldelta = True
def _refreshindex(self):
self._indexbynode.clear()
self._indexbyrev.clear()
Gregory Szorc
filelog: drop index attribute (API)...
r39896 self._index = []
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
for i, entry in enumerate(self._indexdata):
self._indexbynode[entry[b'node']] = entry
self._indexbyrev[i] = entry
self._indexbynode[nullid] = {
b'node': nullid,
b'p1': nullid,
b'p2': nullid,
b'linkrev': nullrev,
b'flags': 0,
}
self._indexbyrev[nullrev] = {
b'node': nullid,
b'p1': nullid,
b'p2': nullid,
b'linkrev': nullrev,
b'flags': 0,
}
for i, entry in enumerate(self._indexdata):
p1rev, p2rev = self.parentrevs(self.rev(entry[b'node']))
# start, length, rawsize, chainbase, linkrev, p1, p2, node
Gregory Szorc
filelog: drop index attribute (API)...
r39896 self._index.append((0, 0, 0, -1, entry[b'linkrev'], p1rev, p2rev,
entry[b'node']))
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
Gregory Szorc
filelog: drop index attribute (API)...
r39896 self._index.append((0, 0, 0, -1, -1, -1, -1, nullid))
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
def __len__(self):
return len(self._indexdata)
def __iter__(self):
return iter(range(len(self)))
def revs(self, start=0, stop=None):
step = 1
if stop is not None:
if start > stop:
step = -1
stop += step
else:
stop = len(self)
return range(start, stop, step)
def parents(self, node):
validatenode(node)
if node not in self._indexbynode:
raise KeyError('unknown node')
entry = self._indexbynode[node]
return entry[b'p1'], entry[b'p2']
def parentrevs(self, rev):
p1, p2 = self.parents(self._indexbyrev[rev][b'node'])
return self.rev(p1), self.rev(p2)
def rev(self, node):
validatenode(node)
Gregory Szorc
simplestore: shore up lookup errors...
r37426 try:
self._indexbynode[node]
except KeyError:
raise error.LookupError(node, self._indexpath, _('no node'))
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
for rev, entry in self._indexbyrev.items():
if entry[b'node'] == node:
return rev
raise error.ProgrammingError('this should not occur')
def node(self, rev):
validaterev(rev)
return self._indexbyrev[rev][b'node']
def lookup(self, node):
if isinstance(node, int):
return self.node(node)
if len(node) == 20:
Gregory Szorc
simplestore: shore up lookup errors...
r37426 self.rev(node)
return node
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
try:
rev = int(node)
if '%d' % rev != node:
raise ValueError
if rev < 0:
rev = len(self) + rev
if rev < 0 or rev >= len(self):
raise ValueError
return self.node(rev)
except (ValueError, OverflowError):
pass
if len(node) == 40:
try:
rawnode = bin(node)
self.rev(rawnode)
return rawnode
Gregory Szorc
simplestore: shore up lookup errors...
r37426 except TypeError:
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 pass
Gregory Szorc
simplestore: shore up lookup errors...
r37426 raise error.LookupError(node, self._path, _('invalid lookup input'))
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
def linkrev(self, rev):
validaterev(rev)
return self._indexbyrev[rev][b'linkrev']
def flags(self, rev):
validaterev(rev)
return self._indexbyrev[rev][b'flags']
def deltaparent(self, rev):
validaterev(rev)
p1node = self.parents(self.node(rev))[0]
return self.rev(p1node)
Gregory Szorc
repository: remove candelta() from ifileindex...
r39270 def _candelta(self, baserev, rev):
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 validaterev(baserev)
validaterev(rev)
if ((self.flags(baserev) & revlog.REVIDX_RAWTEXT_CHANGING_FLAGS)
or (self.flags(rev) & revlog.REVIDX_RAWTEXT_CHANGING_FLAGS)):
return False
return True
def rawsize(self, rev):
validaterev(rev)
node = self.node(rev)
return len(self.revision(node, raw=True))
def _processflags(self, text, flags, operation, raw=False):
if flags == 0:
return text, True
Gregory Szorc
simplestore: correctly implement flag processors...
r37454 if flags & ~revlog.REVIDX_KNOWN_FLAGS:
Gregory Szorc
global: replace most uses of RevlogError with StorageError (API)...
r39813 raise simplestoreerror(_("incompatible revision flag '%#x'") %
(flags & ~revlog.REVIDX_KNOWN_FLAGS))
Gregory Szorc
simplestore: correctly implement flag processors...
r37454
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 validatehash = True
# Depending on the operation (read or write), the order might be
# reversed due to non-commutative transforms.
orderedflags = revlog.REVIDX_FLAGS_ORDER
if operation == 'write':
orderedflags = reversed(orderedflags)
for flag in orderedflags:
# If a flagprocessor has been registered for a known flag, apply the
# related operation transform and update result tuple.
if flag & flags:
vhash = True
if flag not in revlog._flagprocessors:
message = _("missing processor for flag '%#x'") % (flag)
Gregory Szorc
global: replace most uses of RevlogError with StorageError (API)...
r39813 raise simplestoreerror(message)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
processor = revlog._flagprocessors[flag]
if processor is not None:
readtransform, writetransform, rawtransform = processor
if raw:
vhash = rawtransform(self, text)
elif operation == 'read':
text, vhash = readtransform(self, text)
else: # write operation
text, vhash = writetransform(self, text)
validatehash = validatehash and vhash
return text, validatehash
def checkhash(self, text, node, p1=None, p2=None, rev=None):
if p1 is None and p2 is None:
p1, p2 = self.parents(node)
if node != revlog.hash(text, p1, p2):
Gregory Szorc
global: replace most uses of RevlogError with StorageError (API)...
r39813 raise simplestoreerror(_("integrity check failed on %s") %
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 self._path)
def revision(self, node, raw=False):
validatenode(node)
if node == nullid:
return b''
rev = self.rev(node)
flags = self.flags(rev)
path = b'/'.join([self._storepath, hex(node)])
rawtext = self._svfs.read(path)
text, validatehash = self._processflags(rawtext, flags, 'read', raw=raw)
if validatehash:
self.checkhash(text, node, rev=rev)
return text
def read(self, node):
validatenode(node)
revision = self.revision(node)
if not revision.startswith(b'\1\n'):
return revision
start = revision.index(b'\1\n', 2)
return revision[start + 2:]
def renamed(self, node):
validatenode(node)
if self.parents(node)[0] != nullid:
return False
fulltext = self.revision(node)
Gregory Szorc
revlog: move parsemeta() and packmeta() from filelog (API)...
r37460 m = revlog.parsemeta(fulltext)[0]
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
if m and 'copy' in m:
return m['copy'], bin(m['copyrev'])
return False
def cmp(self, node, text):
validatenode(node)
t = text
if text.startswith(b'\1\n'):
t = b'\1\n\1\n' + text
p1, p2 = self.parents(node)
if revlog.hash(t, p1, p2) == node:
return False
if self.iscensored(self.rev(node)):
return text != b''
if self.renamed(node):
t2 = self.read(node)
return t2 != text
return True
def size(self, rev):
validaterev(rev)
node = self._indexbyrev[rev][b'node']
if self.renamed(node):
return len(self.read(node))
if self.iscensored(rev):
return 0
return len(self.revision(node))
def iscensored(self, rev):
validaterev(rev)
return self.flags(rev) & revlog.REVIDX_ISCENSORED
def commonancestorsheads(self, a, b):
validatenode(a)
validatenode(b)
a = self.rev(a)
b = self.rev(b)
ancestors = ancestor.commonancestorsheads(self.parentrevs, a, b)
return pycompat.maplist(self.node, ancestors)
def descendants(self, revs):
# This is a copy of revlog.descendants()
first = min(revs)
if first == nullrev:
for i in self:
yield i
return
seen = set(revs)
for i in self.revs(start=first + 1):
for x in self.parentrevs(i):
if x != nullrev and x in seen:
seen.add(i)
yield i
break
# Required by verify.
def files(self):
entries = self._svfs.listdir(self._storepath)
# Strip out undo.backup.* files created as part of transaction
# recording.
entries = [f for f in entries if not f.startswith('undo.backup.')]
return [b'/'.join((self._storepath, f)) for f in entries]
def add(self, text, meta, transaction, linkrev, p1, p2):
if meta or text.startswith(b'\1\n'):
Gregory Szorc
revlog: move parsemeta() and packmeta() from filelog (API)...
r37460 text = revlog.packmeta(meta, text)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
return self.addrevision(text, transaction, linkrev, p1, p2)
def addrevision(self, text, transaction, linkrev, p1, p2, node=None,
Gregory Szorc
simplestore: correctly implement flag processors...
r37454 flags=revlog.REVIDX_DEFAULT_FLAGS, cachedelta=None):
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 validatenode(p1)
validatenode(p2)
if flags:
node = node or revlog.hash(text, p1, p2)
rawtext, validatehash = self._processflags(text, flags, 'write')
node = node or revlog.hash(text, p1, p2)
if node in self._indexbynode:
return node
if validatehash:
self.checkhash(rawtext, node, p1=p1, p2=p2)
Gregory Szorc
simplestore: correctly implement flag processors...
r37454 return self._addrawrevision(node, rawtext, transaction, linkrev, p1, p2,
flags)
def _addrawrevision(self, node, rawtext, transaction, link, p1, p2, flags):
transaction.addbackup(self._indexpath)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 path = b'/'.join([self._storepath, hex(node)])
Gregory Szorc
simplestore: correctly implement flag processors...
r37454 self._svfs.write(path, rawtext)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
self._indexdata.append({
b'node': node,
b'p1': p1,
b'p2': p2,
Gregory Szorc
simplestore: correctly implement flag processors...
r37454 b'linkrev': link,
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 b'flags': flags,
})
self._reflectindexupdate()
return node
def _reflectindexupdate(self):
self._refreshindex()
self._svfs.write(self._indexpath, cbor.dumps(self._indexdata))
def addgroup(self, deltas, linkmapper, transaction, addrevisioncb=None):
nodes = []
transaction.addbackup(self._indexpath)
for node, p1, p2, linknode, deltabase, delta, flags in deltas:
linkrev = linkmapper(linknode)
Gregory Szorc
simplestore: correctly implement flag processors...
r37454 flags = flags or revlog.REVIDX_DEFAULT_FLAGS
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
nodes.append(node)
if node in self._indexbynode:
continue
# Need to resolve the fulltext from the delta base.
if deltabase == nullid:
text = mdiff.patch(b'', delta)
else:
text = mdiff.patch(self.revision(deltabase), delta)
Gregory Szorc
simplestore: correctly implement flag processors...
r37454 self._addrawrevision(node, text, transaction, linkrev, p1, p2,
flags)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
if addrevisioncb:
addrevisioncb(self, node)
return nodes
def revdiff(self, rev1, rev2):
validaterev(rev1)
validaterev(rev2)
node1 = self.node(rev1)
node2 = self.node(rev2)
return mdiff.textdiff(self.revision(node1, raw=True),
self.revision(node2, raw=True))
Gregory Szorc
repository: establish API for emitting revision deltas...
r39267 def emitrevisiondeltas(self, requests):
for request in requests:
node = request.node
rev = self.rev(node)
if request.basenode == nullid:
baserev = nullrev
elif request.basenode is not None:
baserev = self.rev(request.basenode)
else:
# This is a test extension and we can do simple things
# for choosing a delta parent.
baserev = self.deltaparent(rev)
Gregory Szorc
repository: remove candelta() from ifileindex...
r39270 if baserev != nullrev and not self._candelta(baserev, rev):
Gregory Szorc
repository: establish API for emitting revision deltas...
r39267 baserev = nullrev
revision = None
delta = None
baserevisionsize = None
if self.iscensored(baserev) or self.iscensored(rev):
try:
revision = self.revision(node, raw=True)
except error.CensoredNodeError as e:
revision = e.tombstone
if baserev != nullrev:
baserevisionsize = self.rawsize(baserev)
elif baserev == nullrev:
revision = self.revision(node, raw=True)
else:
delta = self.revdiff(baserev, rev)
extraflags = revlog.REVIDX_ELLIPSIS if request.ellipsis else 0
yield simplestorerevisiondelta(
node=node,
p1node=request.p1node,
p2node=request.p2node,
linknode=request.linknode,
basenode=self.node(baserev),
flags=self.flags(rev) | extraflags,
baserevisionsize=baserevisionsize,
revision=revision,
delta=delta)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 def heads(self, start=None, stop=None):
# This is copied from revlog.py.
if start is None and stop is None:
if not len(self):
return [nullid]
return [self.node(r) for r in self.headrevs()]
if start is None:
start = nullid
if stop is None:
stop = []
stoprevs = set([self.rev(n) for n in stop])
startrev = self.rev(start)
reachable = {startrev}
heads = {startrev}
parentrevs = self.parentrevs
for r in self.revs(start=startrev + 1):
for p in parentrevs(r):
if p in reachable:
if r not in stoprevs:
reachable.add(r)
heads.add(r)
if p in heads and p not in stoprevs:
heads.remove(p)
return [self.node(r) for r in heads]
def children(self, node):
validatenode(node)
# This is a copy of revlog.children().
c = []
p = self.rev(node)
for r in self.revs(start=p + 1):
prevs = [pr for pr in self.parentrevs(r) if pr != nullrev]
if prevs:
for pr in prevs:
if pr == p:
c.append(self.node(r))
elif p == nullrev:
c.append(self.node(r))
return c
def getstrippoint(self, minlink):
# This is largely a copy of revlog.getstrippoint().
brokenrevs = set()
strippoint = len(self)
heads = {}
futurelargelinkrevs = set()
Gregory Szorc
filelog: stop proxying headrevs() (API)...
r39821 for head in self.heads():
headlinkrev = self.linkrev(self.rev(head))
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 heads[head] = headlinkrev
if headlinkrev >= minlink:
futurelargelinkrevs.add(headlinkrev)
# This algorithm involves walking down the rev graph, starting at the
# heads. Since the revs are topologically sorted according to linkrev,
# once all head linkrevs are below the minlink, we know there are
# no more revs that could have a linkrev greater than minlink.
# So we can stop walking.
while futurelargelinkrevs:
strippoint -= 1
linkrev = heads.pop(strippoint)
if linkrev < minlink:
brokenrevs.add(strippoint)
else:
futurelargelinkrevs.remove(linkrev)
for p in self.parentrevs(strippoint):
if p != nullrev:
plinkrev = self.linkrev(p)
heads[p] = plinkrev
if plinkrev >= minlink:
futurelargelinkrevs.add(plinkrev)
return strippoint, brokenrevs
def strip(self, minlink, transaction):
if not len(self):
return
rev, _ignored = self.getstrippoint(minlink)
if rev == len(self):
return
# Purge index data starting at the requested revision.
self._indexdata[rev:] = []
self._reflectindexupdate()
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 def issimplestorefile(f, kind, st):
if kind != stat.S_IFREG:
return False
if store.isrevlog(f, kind, st):
return False
# Ignore transaction undo files.
if f.startswith('undo.'):
return False
# Otherwise assume it belongs to the simple store.
return True
class simplestore(store.encodedstore):
def datafiles(self):
for x in super(simplestore, self).datafiles():
yield x
# Supplement with non-revlog files.
extrafiles = self._walk('data', True, filefilter=issimplestorefile)
for unencoded, encoded, size in extrafiles:
try:
unencoded = store.decodefilename(unencoded)
except KeyError:
unencoded = None
yield unencoded, encoded, size
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 def reposetup(ui, repo):
if not repo.local():
return
Gregory Szorc
tests: disallow using simple store repo with bundlerepo...
r37364 if isinstance(repo, bundlerepo.bundlerepository):
raise error.Abort(_('cannot use simple store with bundlerepo'))
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 class simplestorerepo(repo.__class__):
def file(self, f):
return filestorage(self.svfs, f)
repo.__class__ = simplestorerepo
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433
def featuresetup(ui, supported):
supported.add(REQUIREMENT)
Gregory Szorc
localrepo: pass ui to newreporequirements() (API)...
r39583 def newreporequirements(orig, ui):
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 """Modifies default requirements for new repos to use the simple store."""
Gregory Szorc
localrepo: pass ui to newreporequirements() (API)...
r39583 requirements = orig(ui)
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433
# These requirements are only used to affect creation of the store
# object. We have our own store. So we can remove them.
# TODO do this once we feel like taking the test hit.
#if 'fncache' in requirements:
# requirements.remove('fncache')
#if 'dotencode' in requirements:
# requirements.remove('dotencode')
requirements.add(REQUIREMENT)
return requirements
def makestore(orig, requirements, path, vfstype):
if REQUIREMENT not in requirements:
return orig(requirements, path, vfstype)
return simplestore(path, vfstype)
Gregory Szorc
verify: allow suppressing warnings about extra files...
r37435 def verifierinit(orig, self, *args, **kwargs):
orig(self, *args, **kwargs)
# We don't care that files in the store don't align with what is
# advertised. So suppress these warnings.
self.warnorphanstorefiles = False
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 def extsetup(ui):
localrepo.featuresetupfuncs.add(featuresetup)
extensions.wrapfunction(localrepo, 'newreporequirements',
newreporequirements)
extensions.wrapfunction(store, 'store', makestore)
Gregory Szorc
verify: allow suppressing warnings about extra files...
r37435 extensions.wrapfunction(verify.verifier, '__init__', verifierinit)