##// END OF EJS Templates
interfaces: convert `imanifestrevisionstored` from zope `Attribute` attrs...
interfaces: convert `imanifestrevisionstored` from zope `Attribute` attrs This is the same transformation as b455dfddfed0 did for dirstate.

File last commit:

r53365:4ef6dbc2 default
r53370:a1dd484b default
Show More
filelog.py
320 lines | 9.5 KiB | text/x-python | PythonLexer
mpm@selenic.com
Break apart hg.py...
r1089 # filelog.py - file history class for mercurial
#
Raphaël Gomès
contributor: change mentions of mpm to olivia...
r47575 # Copyright 2005-2007 Olivia Mackall <olivia@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
Matt Harbison
typing: add `from __future__ import annotations` to most files...
r52756 from __future__ import annotations
Gregory Szorc
filelog: use absolute_import
r25948
Matt Harbison
typing: lock in new pytype gains from making revlog related classes typeable...
r52719 from typing import (
Iterable,
Iterator,
)
Gregory Szorc
repository: teach addgroup() to receive data with missing parents...
r40425 from .i18n import _
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 from .node import 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,
Gregory Szorc
filelog: use absolute_import
r25948 )
Augie Fackler
formatting: blacken the codebase...
r43346 from .utils import storageutil
revlog: introduce an explicit tracking of what the revlog is about...
r47838 from .revlogutils import (
constants as revlog_constants,
issue6528: also filter delta on the fly when applying a changegroup...
r48629 rewrite,
revlog: introduce an explicit tracking of what the revlog is about...
r47838 )
Augie Fackler
formatting: blacken the codebase...
r43346
mpm@selenic.com
Break apart hg.py...
r1089
Matt Harbison
filelog: drop the CamelCase name for `filelog.filelog`...
r52959 class filelog: # (repository.ifilestorage)
Matt Harbison
typing: lock in new pytype gains from making revlog related classes typeable...
r52719 _revlog: revlog.revlog
nullid: bytes
_fix_issue6528: bool
revlog: improve the robustness of the splitting process...
r51242 def __init__(self, opener, path, try_split=False):
Augie Fackler
formatting: blacken the codebase...
r43346 self._revlog = revlog.revlog(
revlog: introduce an explicit tracking of what the revlog is about...
r47838 opener,
# XXX should use the unencoded path
target=(revlog_constants.KIND_FILELOG, path),
revlog: use a "radix" to address revlog...
r47921 radix=b'/'.join((b'data', path)),
revlog: introduce an explicit tracking of what the revlog is about...
r47838 censorable=True,
Joerg Sonnenberger
revlog: recommit 49fd21f32695 with a fix for issue6528...
r49876 canonical_parent_order=False, # see comment in revlog.py
revlog: improve the robustness of the splitting process...
r51242 try_split=try_split,
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
Joerg Sonnenberger
node: introduce nodeconstants class...
r47538 self.nullid = self._revlog.nullid
issue6528: add a config option to control the fixing on the fly...
r48630 opts = opener.options
self._fix_issue6528 = opts.get(b'issue6528.fix-incoming', True)
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515
Matt Harbison
typing: lock in new pytype gains from making revlog related classes typeable...
r52719 def get_revlog(self) -> revlog.revlog:
revlog: add a `get_revlog` method...
r51530 """return an actual revlog instance if any
This exist because a lot of code leverage the fact the underlying
storage is a revlog for optimization, so giving simple way to access
the revlog instance helps such code.
"""
return self._revlog
Matt Harbison
typing: lock in new pytype gains from making revlog related classes typeable...
r52719 def __len__(self) -> int:
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515 return len(self._revlog)
Matt Harbison
typing: lock in new pytype gains from making revlog related classes typeable...
r52719 def __iter__(self) -> Iterator[int]:
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515 return self._revlog.__iter__()
Gregory Szorc
filelog: add a hasnode() method (API)...
r40423 def hasnode(self, node):
Joerg Sonnenberger
node: replace nullid and friends with nodeconstants class...
r47771 if node in (self.nullid, nullrev):
Gregory Szorc
filelog: add a hasnode() method (API)...
r40423 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(
revlog: use revlog.display_id in LookupError...
r47926 self._revlog, node, self._revlog.display_id
Augie Fackler
formatting: blacken the codebase...
r43346 )
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)
revlog: drop the df argument to `revision`...
r51915 def revision(self, node):
return self._revlog.revision(node)
Gregory Szorc
filelog: wrap revlog instead of inheriting it (API)...
r37515
revlog: drop the df argument to `rawdata`...
r51916 def rawdata(self, node):
return self._revlog.rawdata(node)
rawdata: forward the method call on `filelog` object...
r42946
Augie Fackler
formatting: blacken the codebase...
r43346 def emitrevisions(
self,
nodes,
nodesorder=None,
revisiondata=False,
assumehaveparentrevisions=False,
deltamode=repository.CG_DELTAMODE_STD,
Raphaël Gomès
changegroupv4: add sidedata helpers...
r47449 sidedata_helpers=None,
debug: add an option to display statistic about a bundling operation...
r50505 debug_info=None,
Augie Fackler
formatting: blacken the codebase...
r43346 ):
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,
Raphaël Gomès
changegroupv4: add sidedata helpers...
r47449 sidedata_helpers=sidedata_helpers,
debug: add an option to display statistic about a bundling operation...
r50505 debug_info=debug_info,
Augie Fackler
formatting: blacken the codebase...
r43346 )
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,
Joerg Sonnenberger
revlog: extend addgroup() with callback for duplicates...
r46373 duplicaterevisioncb=None,
Augie Fackler
formatting: blacken the codebase...
r43346 maybemissingparents=False,
debug: add an option to display statistic about a unbundling operation...
r50506 debug_info=None,
changegroup: add `delta_base_reuse_policy` argument...
r50660 delta_base_reuse_policy=None,
Augie Fackler
formatting: blacken the codebase...
r43346 ):
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
filelog: open the writing context a bit earlier in `addgroup`...
r48628 with self._revlog._writing(transaction):
issue6528: add a config option to control the fixing on the fly...
r48630 if self._fix_issue6528:
deltas = rewrite.filter_delta_issue6528(self._revlog, deltas)
issue6528: also filter delta on the fly when applying a changegroup...
r48629
filelog: open the writing context a bit earlier in `addgroup`...
r48628 return self._revlog.addgroup(
deltas,
linkmapper,
transaction,
addrevisioncb=addrevisioncb,
duplicaterevisioncb=duplicaterevisioncb,
debug: add an option to display statistic about a unbundling operation...
r50506 debug_info=debug_info,
changegroup: add `delta_base_reuse_policy` argument...
r50660 delta_base_reuse_policy=delta_base_reuse_policy,
filelog: open the writing context a bit earlier in `addgroup`...
r48628 )
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)
Joerg Sonnenberger
revlog: change addrevision to return the new revision, not node...
r47258 rev = self.addrevision(text, transaction, link, p1, p2)
return self.node(rev)
mpm@selenic.com
Break apart hg.py...
r1089
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)
Arseniy Alekseyev
censor: fix [hg update] away from a revision with censored files...
r50066 if self.iscensored(rev):
return 0
Matt Mackall
merge: use file size stored in revlog index...
r2898 if self.renamed(node):
return len(self.read(node))
Nicolas Dumazet
filelog: test behaviour for data starting with "\1\n"...
r11540 # XXX if self.read(node).startswith("\1\n"), this returns (size+4)
Joerg Sonnenberger
revlog: recommit 49fd21f32695 with a fix for issue6528...
r49876 # XXX See also basefilectx.cmp.
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
Matt Harbison
revlog: subclass the new `repository.iverifyproblem` Protocol class...
r53365 def verifyintegrity(self, state) -> Iterable[repository.iverifyproblem]:
Gregory Szorc
verify: start to abstract file verification...
r39878 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 # 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):
filelog: show the passed argument on error...
r50102 msg = b'expected filelog to clone(), not %r'
msg %= destrevlog
raise error.ProgrammingError(msg)
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."""
revlog: improve the robustness of the splitting process...
r51242 def __init__(self, opener, path, narrowmatch, try_split=False):
super(narrowfilelog, self).__init__(opener, path, try_split=try_split)
Gregory Szorc
filelog: custom filelog to be used with narrow repos...
r39801 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):
Raphaël Gomès
narrow: fix flaky behavior described in issue6150...
r47280 # We don't call `super` because narrow parents can be buggy in case of a
# ambiguous dirstate. Always take the slow path until there is a better
# fix, see issue6150.
Gregory Szorc
filelog: custom filelog to be used with narrow repos...
r39801
Raphaël Gomès
narrow: fix flaky behavior described in issue6150...
r47280 # Censored files compare against the empty file.
if self.iscensored(self.rev(node)):
return text != b''
Gregory Szorc
filelog: custom filelog to be used with narrow repos...
r39801
Raphaël Gomès
narrow: fix flaky behavior described in issue6150...
r47280 return self.read(node) != text