The delta comming from a bundle/stream does not exists in the revlog yet, so we
will need other way to retrieve the same information.
To prepare for this we split the function to use callbacks in the core logic.
pulkit |
hg-reviewers |
The delta comming from a bundle/stream does not exists in the revlog yet, so we
will need other way to retrieve the same information.
To prepare for this we split the function to use callbacks in the core logic.
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
✅ refresh by Heptapod after a successful CI run (🐙 💚)
⚠ This patch is intended for stable ⚠
if has_meta: | if has_meta: | ||||
(p1, p2) = parents_revs() | (p1, p2) = parents_revs() | ||||
if p1 != nullrev and p2 == nullrev: | if p1 != nullrev and p2 == nullrev: | ||||
return True | return True | ||||
return False | return False | ||||
def _is_revision_affected_fast(repo, fl, filerev, metadata_cache): | def _is_revision_affected_fast(repo, fl, filerev, metadata_cache): | ||||
rl = fl._revlog | |||||
is_censored = lambda: rl.iscensored(filerev) | |||||
delta_base = lambda: rl.deltaparent(filerev) | |||||
delta = lambda: rl._chunk(filerev) | |||||
full_text = lambda: rl.rawdata(filerev) | |||||
parent_revs = lambda: rl.parentrevs(filerev) | |||||
return _is_revision_affected_fast_inner( | |||||
is_censored, | |||||
delta_base, | |||||
delta, | |||||
full_text, | |||||
parent_revs, | |||||
filerev, | |||||
metadata_cache, | |||||
) | |||||
def _is_revision_affected_fast_inner( | |||||
is_censored, | |||||
delta_base, | |||||
delta, | |||||
full_text, | |||||
parent_revs, | |||||
filerev, | |||||
metadata_cache, | |||||
): | |||||
"""Optimization fast-path for `_is_revision_affected`. | """Optimization fast-path for `_is_revision_affected`. | ||||
`metadata_cache` is a dict of `{rev: has_metadata}` which allows any | `metadata_cache` is a dict of `{rev: has_metadata}` which allows any | ||||
revision to check if its base has metadata, saving computation of the full | revision to check if its base has metadata, saving computation of the full | ||||
text, instead looking at the current delta. | text, instead looking at the current delta. | ||||
This optimization only works if the revisions are looked at in order.""" | This optimization only works if the revisions are looked at in order.""" | ||||
rl = fl._revlog | |||||
if rl.iscensored(filerev): | if is_censored(): | ||||
# Censored revisions don't contain metadata, so they cannot be affected | # Censored revisions don't contain metadata, so they cannot be affected | ||||
metadata_cache[filerev] = False | metadata_cache[filerev] = False | ||||
return False | return False | ||||
p1, p2 = rl.parentrevs(filerev) | p1, p2 = parent_revs() | ||||
if p1 == nullrev or p2 != nullrev: | if p1 == nullrev or p2 != nullrev: | ||||
return False | return False | ||||
delta_parent = rl.deltaparent(filerev) | delta_parent = delta_base() | ||||
parent_has_metadata = metadata_cache.get(delta_parent) | parent_has_metadata = metadata_cache.get(delta_parent) | ||||
if parent_has_metadata is None: | if parent_has_metadata is None: | ||||
is_affected = _is_revision_affected(fl, filerev, metadata_cache) | return _is_revision_affected_inner( | ||||
return is_affected | full_text, | ||||
parent_revs, | |||||
filerev, | |||||
metadata_cache, | |||||
) | |||||
chunk = rl._chunk(filerev) | chunk = delta() | ||||
if not len(chunk): | if not len(chunk): | ||||
# No diff for this revision | # No diff for this revision | ||||
return parent_has_metadata | return parent_has_metadata | ||||
header_length = 12 | header_length = 12 | ||||
if len(chunk) < header_length: | if len(chunk) < header_length: | ||||
raise error.Abort(_(b"patch cannot be decoded")) | raise error.Abort(_(b"patch cannot be decoded")) | ||||
start, _end, _length = struct.unpack(b">lll", chunk[:header_length]) | start, _end, _length = struct.unpack(b">lll", chunk[:header_length]) | ||||
if start < 2: # len(b'\x01\n') == 2 | if start < 2: # len(b'\x01\n') == 2 | ||||
# This delta does *something* to the metadata marker (if any). | # This delta does *something* to the metadata marker (if any). | ||||
# Check it the slow way | # Check it the slow way | ||||
is_affected = _is_revision_affected(fl, filerev, metadata_cache) | is_affected = _is_revision_affected_inner( | ||||
full_text, | |||||
parent_revs, | |||||
filerev, | |||||
metadata_cache, | |||||
) | |||||
return is_affected | return is_affected | ||||
# The diff did not remove or add the metadata header, it's then in the same | # The diff did not remove or add the metadata header, it's then in the same | ||||
# situation as its parent | # situation as its parent | ||||
metadata_cache[filerev] = parent_has_metadata | metadata_cache[filerev] = parent_has_metadata | ||||
return parent_has_metadata | return parent_has_metadata | ||||