##// END OF EJS Templates
nodemap: track the maximum revision tracked in the nodemap...
nodemap: track the maximum revision tracked in the nodemap We need a simple way to detect when the on disk data contains less revision than the index we read from disk. The docket file is meant for this, we just had to start tracking that data. We should also try to detect strip operation, but we will deal with this in later changesets. Right now we are focusing on defining the API for index supporting persistent nodemap. Differential Revision: https://phab.mercurial-scm.org/D7888

File last commit:

r43347:687b865b default
r44807:e41a164d default
Show More
filelog.py
287 lines | 8.2 KiB | text/x-python | PythonLexer
mpm@selenic.com
Break apart hg.py...
r1089 # filelog.py - file history class for mercurial
#
Thomas Arendsen Hein
Updated copyright notices and add "and others" to "hg version"
r4635 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
mpm@selenic.com
Break apart hg.py...
r1089 #
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # 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.
mpm@selenic.com
Break apart hg.py...
r1089
Gregory Szorc
filelog: use absolute_import
r25948 from __future__ import absolute_import
Gregory Szorc
repository: teach addgroup() to receive data with missing parents...
r40425 from .i18n import _
Gregory Szorc
filelog: add a hasnode() method (API)...
r40423 from .node import (
nullid,
nullrev,
)
Gregory Szorc
filelog: use absolute_import
r25948 from . import (
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515 error,
Pulkit Goyal
interfaces: create a new folder for interfaces and move repository.py in it...
r43078 revlog,
)
from .interfaces import (
Gregory Szorc
filelog: declare that filelog implements a storage interface...
r37459 repository,
Pulkit Goyal
interfaceutil: move to interfaces/...
r43079 util as interfaceutil,
Gregory Szorc
filelog: use absolute_import
r25948 )
Augie Fackler
formatting: blacken the codebase...
r43346 from .utils import storageutil
mpm@selenic.com
Break apart hg.py...
r1089
Gregory Szorc
interfaceutil: module to stub out zope.interface...
r37828 @interfaceutil.implementer(repository.ifilestorage)
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515 class filelog(object):
Matt Mackall
revlog: simplify revlog version handling...
r4258 def __init__(self, opener, path):
Augie Fackler
formatting: blacken the codebase...
r43346 self._revlog = revlog.revlog(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 opener, b'/'.join((b'data', path + b'.i')), censorable=True
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
filelog: record what's using attributes...
r39819 # Full name of the user visible file, relative to the repository root.
# Used by LFS.
Gregory Szorc
filelog: store filename directly on revlog instance...
r39892 self._revlog.filename = path
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515
def __len__(self):
return len(self._revlog)
def __iter__(self):
return self._revlog.__iter__()
Gregory Szorc
filelog: add a hasnode() method (API)...
r40423 def hasnode(self, node):
if node in (nullid, nullrev):
return False
try:
self._revlog.rev(node)
return True
except (TypeError, ValueError, IndexError, error.LookupError):
return False
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515 def revs(self, start=0, stop=None):
return self._revlog.revs(start=start, stop=stop)
def parents(self, node):
return self._revlog.parents(node)
def parentrevs(self, rev):
return self._revlog.parentrevs(rev)
def rev(self, node):
return self._revlog.rev(node)
def node(self, rev):
return self._revlog.node(rev)
def lookup(self, node):
Augie Fackler
formatting: blacken the codebase...
r43346 return storageutil.fileidlookup(
self._revlog, node, self._revlog.indexfile
)
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515
def linkrev(self, rev):
return self._revlog.linkrev(rev)
def commonancestorsheads(self, node1, node2):
return self._revlog.commonancestorsheads(node1, node2)
Gregory Szorc
filelog: record what's using attributes...
r39819 # Used by dagop.blockdescendants().
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515 def descendants(self, revs):
return self._revlog.descendants(revs)
def heads(self, start=None, stop=None):
return self._revlog.heads(start, stop)
Gregory Szorc
filelog: record what's using attributes...
r39819 # Used by hgweb, children extension.
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515 def children(self, node):
return self._revlog.children(node)
def iscensored(self, rev):
return self._revlog.iscensored(rev)
def revision(self, node, _df=None, raw=False):
return self._revlog.revision(node, _df=_df, raw=raw)
rawdata: forward the method call on `filelog` object...
r42946 def rawdata(self, node, _df=None):
return self._revlog.rawdata(node, _df=_df)
Augie Fackler
formatting: blacken the codebase...
r43346 def emitrevisions(
self,
nodes,
nodesorder=None,
revisiondata=False,
assumehaveparentrevisions=False,
deltamode=repository.CG_DELTAMODE_STD,
):
Gregory Szorc
revlog: new API to emit revision data...
r39898 return self._revlog.emitrevisions(
Augie Fackler
formatting: blacken the codebase...
r43346 nodes,
nodesorder=nodesorder,
revisiondata=revisiondata,
Gregory Szorc
revlog: new API to emit revision data...
r39898 assumehaveparentrevisions=assumehaveparentrevisions,
Augie Fackler
formatting: blacken the codebase...
r43346 deltamode=deltamode,
)
Gregory Szorc
revlog: new API to emit revision data...
r39898
Augie Fackler
formatting: blacken the codebase...
r43346 def addrevision(
self,
revisiondata,
transaction,
linkrev,
p1,
p2,
node=None,
flags=revlog.REVIDX_DEFAULT_FLAGS,
cachedelta=None,
):
return self._revlog.addrevision(
revisiondata,
transaction,
linkrev,
p1,
p2,
node=node,
flags=flags,
cachedelta=cachedelta,
)
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515
Augie Fackler
formatting: blacken the codebase...
r43346 def addgroup(
self,
deltas,
linkmapper,
transaction,
addrevisioncb=None,
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(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'revlog storage does not support missing '
b'parents write mode'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Gregory Szorc
repository: teach addgroup() to receive data with missing parents...
r40425
Augie Fackler
formatting: blacken the codebase...
r43346 return self._revlog.addgroup(
deltas, linkmapper, transaction, addrevisioncb=addrevisioncb
)
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515
def getstrippoint(self, minlink):
return self._revlog.getstrippoint(minlink)
def strip(self, minlink, transaction):
return self._revlog.strip(minlink, transaction)
Gregory Szorc
revlog: move censor logic out of censor extension...
r39814 def censorrevision(self, tr, node, tombstone=b''):
Gregory Szorc
revlog: rewrite censoring logic...
r40092 return self._revlog.censorrevision(tr, node, tombstone=tombstone)
Gregory Szorc
revlog: move censor logic out of censor extension...
r39814
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515 def files(self):
return self._revlog.files()
mpm@selenic.com
Break apart hg.py...
r1089 def read(self, node):
Gregory Szorc
storageutil: new function for extracting metadata-less content from text...
r39916 return storageutil.filtermetadata(self.revision(node))
mpm@selenic.com
Break apart hg.py...
r1089
def add(self, text, meta, transaction, link, p1=None, p2=None):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 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)
mpm@selenic.com
Break apart hg.py...
r1089 return self.addrevision(text, transaction, link, p1, p2)
mpm@selenic.com
Add some rename debugging support
r1116 def renamed(self, node):
Gregory Szorc
storageutil: extract copy metadata retrieval out of filelog...
r40041 return storageutil.filerevisioncopied(self, node)
mpm@selenic.com
Add some rename debugging support
r1116
Matt Mackall
merge: use file size stored in revlog index...
r2898 def size(self, rev):
"""return the size of a given revision"""
# for revisions with renames, we have to go the slow way
node = self.node(rev)
if self.renamed(node):
return len(self.read(node))
Mike Edgar
revlog: add "iscensored()" to revlog public API...
r24118 if self.iscensored(rev):
Mike Edgar
filelog: censored files compare against empty data, have 0 size...
r22597 return 0
Matt Mackall
merge: use file size stored in revlog index...
r2898
Nicolas Dumazet
filelog: test behaviour for data starting with "\1\n"...
r11540 # XXX if self.read(node).startswith("\1\n"), this returns (size+4)
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515 return self._revlog.size(rev)
Matt Mackall
merge: use file size stored in revlog index...
r2898
Matt Mackall
filelog: add hash-based comparisons...
r2887 def cmp(self, node, text):
Nicolas Dumazet
cmp: document the fact that we return True if content is different...
r11539 """compare text with a given file revision
returns True if text is different than what is stored.
"""
Gregory Szorc
storageutil: invert logic of file data comparison...
r40043 return not storageutil.filedataequivalent(self, node, text)
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515
Gregory Szorc
verify: start to abstract file verification...
r39878 def verifyintegrity(self, state):
return self._revlog.verifyintegrity(state)
Augie Fackler
formatting: blacken the codebase...
r43346 def storageinfo(
self,
exclusivefiles=False,
sharedfiles=False,
revisionscount=False,
trackedsize=False,
storedsize=False,
):
Gregory Szorc
revlog: add method for obtaining storage info (API)...
r39905 return self._revlog.storageinfo(
Augie Fackler
formatting: blacken the codebase...
r43346 exclusivefiles=exclusivefiles,
sharedfiles=sharedfiles,
revisionscount=revisionscount,
trackedsize=trackedsize,
storedsize=storedsize,
)
Gregory Szorc
revlog: add method for obtaining storage info (API)...
r39905
Gregory Szorc
filelog: record what's using attributes...
r39819 # TODO these aren't part of the interface and aren't internal methods.
# Callers should be fixed to not use them.
# Used by bundlefilelog, unionfilelog.
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515 @property
def indexfile(self):
return self._revlog.indexfile
@indexfile.setter
def indexfile(self, value):
self._revlog.indexfile = value
Gregory Szorc
filelog: record what's using attributes...
r39819 # Used by repo upgrade.
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515 def clone(self, tr, destrevlog, **kwargs):
if not isinstance(destrevlog, filelog):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.ProgrammingError(b'expected filelog to clone()')
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515
return self._revlog.clone(tr, destrevlog._revlog, **kwargs)
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
filelog: custom filelog to be used with narrow repos...
r39801 class narrowfilelog(filelog):
"""Filelog variation to be used with narrow stores."""
def __init__(self, opener, path, narrowmatch):
super(narrowfilelog, self).__init__(opener, path)
self._narrowmatch = narrowmatch
def renamed(self, node):
res = super(narrowfilelog, self).renamed(node)
# Renames that come from outside the narrowspec are problematic
# because we may lack the base text for the rename. This can result
# in code attempting to walk the ancestry or compute a diff
# encountering a missing revision. We address this by silently
# removing rename metadata if the source file is outside the
# narrow spec.
#
# A better solution would be to see if the base revision is available,
# rather than assuming it isn't.
#
# An even better solution would be to teach all consumers of rename
# metadata that the base revision may not be available.
#
# TODO consider better ways of doing this.
if res and not self._narrowmatch(res[0]):
return None
return res
def size(self, rev):
# Because we have a custom renamed() that may lie, we need to call
# the base renamed() to report accurate results.
node = self.node(rev)
if super(narrowfilelog, self).renamed(node):
return len(self.read(node))
else:
return super(narrowfilelog, self).size(rev)
def cmp(self, node, text):
different = super(narrowfilelog, self).cmp(node, text)
# Because renamed() may lie, we may get false positives for
# different content. Check for this by comparing against the original
# renamed() implementation.
if different:
if super(narrowfilelog, self).renamed(node):
t2 = self.read(node)
return t2 != text
return different