##// END OF EJS Templates
revlog: extend addgroup() with callback for duplicates...
revlog: extend addgroup() with callback for duplicates The addgroup() interface currently doesn't allow the caller to keep track of duplicated nodes except by looking at the returned node list. Add an optional second callback for this purpose and change the return type to a boolean. This allows follow-up changes to use more efficient storage for the node list in places that are memory-sensitive. Differential Revision: https://phab.mercurial-scm.org/D9231

File last commit:

r46373:a5206e71 default
r46373:a5206e71 default
Show More
simplestorerepo.py
738 lines | 19.3 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,
)
Augie Fackler
formatting: blacken the codebase...
r43346 from mercurial.thirdparty import attr
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 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,
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 )
Pulkit Goyal
interfaces: create a new folder for interfaces and move repository.py in it...
r43078 from mercurial.interfaces import (
repository,
Pulkit Goyal
interfaceutil: move to interfaces/...
r43079 util as interfaceutil,
Pulkit Goyal
interfaces: create a new folder for interfaces and move repository.py in it...
r43078 )
Gregory Szorc
tests: use interfaceutil in simplestorerepo...
r38565 from mercurial.utils import (
Augie Fackler
simplestorerepo: migrate to in-hg CBOR code...
r41193 cborutil,
Gregory Szorc
storageutil: new module for storage primitives (API)...
r39913 storageutil,
Gregory Szorc
tests: use interfaceutil in simplestorerepo...
r38565 )
Augie Fackler
formatting: blacken the codebase...
r43346 from mercurial.revlogutils import flagutil
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.
Matt Harbison
tests: byteify a few more things in simplestorerepo.py...
r44132 testedwith = b'ships-with-hg-core'
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
Matt Harbison
tests: byteify a few more things in simplestorerepo.py...
r44132 REQUIREMENT = b'testonly-simplestore'
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433
Augie Fackler
formatting: blacken the codebase...
r43346
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')
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 def validaterev(rev):
if not isinstance(rev, int):
raise ValueError('expected int')
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
global: replace most uses of RevlogError with StorageError (API)...
r39813 class simplestoreerror(error.StorageError):
pass
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
repository: establish API for emitting revision deltas...
r39267 @interfaceutil.implementer(repository.irevisiondelta)
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 @attr.s(slots=True)
Gregory Szorc
repository: establish API for emitting revision deltas...
r39267 class simplestorerevisiondelta(object):
node = attr.ib()
p1node = attr.ib()
p2node = attr.ib()
basenode = attr.ib()
flags = attr.ib()
baserevisionsize = attr.ib()
revision = attr.ib()
delta = attr.ib()
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 linknode = attr.ib(default=None)
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 @interfaceutil.implementer(repository.iverifyproblem)
@attr.s(frozen=True)
class simplefilestoreproblem(object):
warning = attr.ib(default=None)
error = attr.ib(default=None)
node = attr.ib(default=None)
Gregory Szorc
repository: establish API for emitting revision deltas...
r39267
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
tests: use interfaceutil in simplestorerepo...
r38565 @interfaceutil.implementer(repository.ifilestorage)
flagprocessors: remove flagprocessorsmixin...
r43265 class filestorage(object):
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 """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.
"""
flagutil: use it in simplestorerepo...
r43143 _flagserrorclass = simplestoreerror
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 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:
Augie Fackler
simplestorerepo: migrate to in-hg CBOR code...
r41193 indexdata = cborutil.decodeall(indexdata)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
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()
flagutil: use it in simplestorerepo...
r43143 self._flagprocessors = dict(flagutil.flagprocessors)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 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
Augie Fackler
formatting: blacken the codebase...
r43346 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
Matt Harbison
tests: byteify a few more things in simplestorerepo.py...
r44132 raise error.ProgrammingError(b'this should not occur')
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
def node(self, rev):
validaterev(rev)
return self._indexbyrev[rev][b'node']
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 def hasnode(self, node):
validatenode(node)
return node in self._indexbynode
def censorrevision(self, tr, censornode, tombstone=b''):
raise NotImplementedError('TODO')
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 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']
Gregory Szorc
filelog: stop proxying flags() (API)...
r39909 def _flags(self, rev):
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 validaterev(rev)
return self._indexbyrev[rev][b'flags']
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)
Augie Fackler
formatting: blacken the codebase...
r43346 if (self._flags(baserev) & revlog.REVIDX_RAWTEXT_CHANGING_FLAGS) or (
self._flags(rev) & revlog.REVIDX_RAWTEXT_CHANGING_FLAGS
):
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 return False
return True
def checkhash(self, text, node, p1=None, p2=None, rev=None):
if p1 is None and p2 is None:
p1, p2 = self.parents(node)
Gregory Szorc
storageutil: new module for storage primitives (API)...
r39913 if node != storageutil.hashrevisionsha1(text, p1, p2):
Augie Fackler
formatting: blacken the codebase...
r43346 raise simplestoreerror(
_("integrity check failed on %s") % self._path
)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 def revision(self, nodeorrev, raw=False):
if isinstance(nodeorrev, int):
node = self.node(nodeorrev)
else:
node = nodeorrev
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 validatenode(node)
if node == nullid:
return b''
rev = self.rev(node)
Gregory Szorc
filelog: stop proxying flags() (API)...
r39909 flags = self._flags(rev)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
path = b'/'.join([self._storepath, hex(node)])
rawtext = self._svfs.read(path)
simplestorerepo: stop using `_processflags` directly...
r43149 if raw:
flagprocessors: make `processflagsraw` a module level function...
r43262 validatehash = flagutil.processflagsraw(self, rawtext, flags)
simplestorerepo: stop using `_processflags` directly...
r43149 text = rawtext
else:
flagprocessors: make `processflagsread` a module level function...
r43261 r = flagutil.processflagsread(self, rawtext, flags)
flagprocessors: return sidedata map in `_processflagsread`...
r43253 text, validatehash, sidedata = r
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 if validatehash:
self.checkhash(text, node, rev=rev)
return text
rawdata: implement `rawdata` for `simplestore` too...
r42950 def rawdata(self, nodeorrev):
return self.revision(raw=True)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 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)
Augie Fackler
formatting: blacken the codebase...
r43346 return revision[start + 2 :]
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
def renamed(self, node):
validatenode(node)
if self.parents(node)[0] != nullid:
return False
fulltext = self.revision(node)
Gregory Szorc
storageutil: move metadata parsing and packing from revlog (API)...
r39914 m = storageutil.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)
Gregory Szorc
storageutil: new module for storage primitives (API)...
r39913 if storageutil.hashrevisionsha1(t, p1, p2) == node:
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 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)
Gregory Szorc
repository: define and use revision flag constants...
r40083 return self._flags(rev) & repository.REVISION_FLAG_CENSORED
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
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]
Augie Fackler
formatting: blacken the codebase...
r43346 def storageinfo(
self,
exclusivefiles=False,
sharedfiles=False,
revisionscount=False,
trackedsize=False,
storedsize=False,
):
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 # TODO do a real implementation of this
return {
'exclusivefiles': [],
'sharedfiles': [],
'revisionscount': len(self),
'trackedsize': 0,
'storedsize': None,
}
def verifyintegrity(self, state):
state['skipread'] = set()
for rev in self:
node = self.node(rev)
try:
self.revision(node)
except Exception as e:
yield simplefilestoreproblem(
Augie Fackler
formatting: blacken the codebase...
r43346 error='unpacking %s: %s' % (node, e), node=node
)
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 state['skipread'].add(node)
Augie Fackler
formatting: blacken the codebase...
r43346 def emitrevisions(
self,
nodes,
nodesorder=None,
revisiondata=False,
assumehaveparentrevisions=False,
deltamode=repository.CG_DELTAMODE_STD,
):
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 # TODO this will probably break on some ordering options.
nodes = [n for n in nodes if n != nullid]
if not nodes:
return
for delta in storageutil.emitrevisions(
Augie Fackler
formatting: blacken the codebase...
r43346 self,
nodes,
nodesorder,
simplestorerevisiondelta,
revisiondata=revisiondata,
assumehaveparentrevisions=assumehaveparentrevisions,
deltamode=deltamode,
):
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 yield delta
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 def add(self, text, meta, transaction, linkrev, p1, p2):
if meta or text.startswith(b'\1\n'):
Gregory Szorc
storageutil: move metadata parsing and packing from revlog (API)...
r39914 text = storageutil.packmeta(meta, text)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
return self.addrevision(text, transaction, linkrev, p1, p2)
Augie Fackler
formatting: blacken the codebase...
r43346 def addrevision(
self,
text,
transaction,
linkrev,
p1,
p2,
node=None,
flags=revlog.REVIDX_DEFAULT_FLAGS,
cachedelta=None,
):
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 validatenode(p1)
validatenode(p2)
if flags:
Gregory Szorc
storageutil: new module for storage primitives (API)...
r39913 node = node or storageutil.hashrevisionsha1(text, p1, p2)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
flagprocessors: make `processflagswrite` a module level function...
r43260 rawtext, validatehash = flagutil.processflagswrite(self, text, flags)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
Gregory Szorc
storageutil: new module for storage primitives (API)...
r39913 node = node or storageutil.hashrevisionsha1(text, p1, p2)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
if node in self._indexbynode:
return node
if validatehash:
self.checkhash(rawtext, node, p1=p1, p2=p2)
Augie Fackler
formatting: blacken the codebase...
r43346 return self._addrawrevision(
node, rawtext, transaction, linkrev, p1, p2, flags
)
Gregory Szorc
simplestore: correctly implement flag processors...
r37454
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
Augie Fackler
formatting: blacken the codebase...
r43346 self._indexdata.append(
{
b'node': node,
b'p1': p1,
b'p2': p2,
b'linkrev': link,
b'flags': flags,
}
)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
self._reflectindexupdate()
return node
def _reflectindexupdate(self):
self._refreshindex()
Augie Fackler
formatting: blacken the codebase...
r43346 self._svfs.write(
self._indexpath, ''.join(cborutil.streamencode(self._indexdata))
)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
Augie Fackler
formatting: blacken the codebase...
r43346 def addgroup(
self,
deltas,
linkmapper,
transaction,
addrevisioncb=None,
Joerg Sonnenberger
revlog: extend addgroup() with callback for duplicates...
r46373 duplicaterevisioncb=None,
Augie Fackler
formatting: blacken the codebase...
r43346 maybemissingparents=False,
):
Gregory Szorc
repository: teach addgroup() to receive data with missing parents...
r40425 if maybemissingparents:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_('simple store does not support missing parents ' 'write mode')
)
Gregory Szorc
repository: teach addgroup() to receive data with missing parents...
r40425
Joerg Sonnenberger
revlog: extend addgroup() with callback for duplicates...
r46373 empty = True
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
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
if node in self._indexbynode:
Joerg Sonnenberger
revlog: extend addgroup() with callback for duplicates...
r46373 if duplicaterevisioncb:
duplicaterevisioncb(self, node)
empty = False
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 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)
Augie Fackler
formatting: blacken the codebase...
r43346 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)
Joerg Sonnenberger
revlog: extend addgroup() with callback for duplicates...
r46373 empty = False
return not empty
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 def _headrevs(self):
# Assume all revisions are heads by default.
revishead = {rev: True for rev in self._indexbyrev}
for rev, entry in self._indexbyrev.items():
# Unset head flag for all seen parents.
revishead[self.rev(entry[b'p1'])] = False
revishead[self.rev(entry[b'p2'])] = False
Augie Fackler
formatting: blacken the codebase...
r43346 return [rev for rev, ishead in sorted(revishead.items()) if ishead]
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]
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 return [self.node(r) for r in self._headrevs()]
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
if start is None:
start = nullid
if stop is None:
stop = []
Augie Fackler
cleanup: run pyupgrade on our source tree to clean up varying things...
r44937 stoprevs = {self.rev(n) for n in stop}
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355 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):
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 return storageutil.resolvestripinfo(
Augie Fackler
formatting: blacken the codebase...
r43346 minlink,
len(self) - 1,
self._headrevs(),
self.linkrev,
self.parentrevs,
)
Gregory Szorc
tests: add test extension implementing custom filelog storage...
r37355
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()
Augie Fackler
formatting: blacken the codebase...
r43346
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
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 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
Augie Fackler
formatting: blacken the codebase...
r43346
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
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 def featuresetup(ui, supported):
supported.add(REQUIREMENT)
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 def newreporequirements(orig, ui, createopts):
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 """Modifies default requirements for new repos to use the simple store."""
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 requirements = orig(ui, createopts)
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.
Augie Fackler
formatting: blacken the codebase...
r43346 # if 'fncache' in requirements:
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 # requirements.remove('fncache')
Augie Fackler
formatting: blacken the codebase...
r43346 # if 'dotencode' in requirements:
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 # requirements.remove('dotencode')
requirements.add(REQUIREMENT)
return requirements
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 def makestore(orig, requirements, path, vfstype):
if REQUIREMENT not in requirements:
return orig(requirements, path, vfstype)
return simplestore(path, vfstype)
Augie Fackler
formatting: blacken the codebase...
r43346
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
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
simplestore: use a custom store for the simple store repo...
r37433 def extsetup(ui):
localrepo.featuresetupfuncs.add(featuresetup)
Augie Fackler
formatting: blacken the codebase...
r43346 extensions.wrapfunction(
localrepo, 'newreporequirements', newreporequirements
)
Augie Fackler
simplestorerepo: minimal changes required to get this mostly working again...
r41192 extensions.wrapfunction(localrepo, 'makestore', makestore)
Gregory Szorc
verify: allow suppressing warnings about extra files...
r37435 extensions.wrapfunction(verify.verifier, '__init__', verifierinit)