mercurial/store.py
author Raphaël Gomès <rgomes@octobus.net>
Mon, 04 Nov 2024 12:10:22 +0100
changeset 52308 7756494c5ecd
parent 52175 bd43465af568
permissions -rw-r--r--
rust-inner-revlog: cache the compressor The `compress` function is unlikely to be used in highly contended situations, and creating a compressor has some overhead, on top of losing out on some potential advantages of longer-running optimizations from the compressor.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50680
e324329fc97e store: use the revlog type from revlog's constant instead of custom one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50672
diff changeset
     1
# store.py - repository store handling for Mercurial)
6839
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     2
#
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46780
diff changeset
     3
# Copyright 2008 Olivia Mackall <olivia@selenic.com>
6839
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8210
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9133
diff changeset
     6
# GNU General Public License version 2 or any later version.
6839
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
     7
51863
f4733654f144 typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents: 51826
diff changeset
     8
from __future__ import annotations
f4733654f144 typing: add `from __future__ import annotations` to most files
Matt Harbison <matt_harbison@yahoo.com>
parents: 51826
diff changeset
     9
50479
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
    10
import collections
41978
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
    11
import functools
27480
509159675cdb store: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26778
diff changeset
    12
import os
46990
0b569c75d180 store: exclude `undo.` nodemap's file from `walk`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46989
diff changeset
    13
import re
27480
509159675cdb store: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26778
diff changeset
    14
import stat
51729
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51728
diff changeset
    15
import typing
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51728
diff changeset
    16
51882
2391a5fa111e store: fix a signature mismatch for a vfs subclass
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    17
from typing import (
2391a5fa111e store: fix a signature mismatch for a vfs subclass
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    18
    Generator,
2391a5fa111e store: fix a signature mismatch for a vfs subclass
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    19
    List,
2391a5fa111e store: fix a signature mismatch for a vfs subclass
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    20
    Optional,
2391a5fa111e store: fix a signature mismatch for a vfs subclass
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
    21
)
27480
509159675cdb store: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26778
diff changeset
    22
509159675cdb store: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26778
diff changeset
    23
from .i18n import _
50471
521fec115dad store: use a StoreEntry object instead of tuple for store files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50469
diff changeset
    24
from .thirdparty import attr
51729
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51728
diff changeset
    25
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51728
diff changeset
    26
# Force pytype to use the non-vendored package
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51728
diff changeset
    27
if typing.TYPE_CHECKING:
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51728
diff changeset
    28
    # noinspection PyPackageRequirements
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51728
diff changeset
    29
    import attr
278af66e6595 typing: induce pytype to use the standard `attr` instead of the vendored copy
Matt Harbison <matt_harbison@yahoo.com>
parents: 51728
diff changeset
    30
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
    31
from .node import hex
50672
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
    32
from .revlogutils.constants import (
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
    33
    INDEX_HEADER,
50680
e324329fc97e store: use the revlog type from revlog's constant instead of custom one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50672
diff changeset
    34
    KIND_CHANGELOG,
e324329fc97e store: use the revlog type from revlog's constant instead of custom one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50672
diff changeset
    35
    KIND_FILELOG,
e324329fc97e store: use the revlog type from revlog's constant instead of custom one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50672
diff changeset
    36
    KIND_MANIFESTLOG,
50672
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
    37
)
27480
509159675cdb store: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26778
diff changeset
    38
from . import (
42905
3df3b139a43d localrepo: push manifestlog and changelog construction code into store
Augie Fackler <augie@google.com>
parents: 42715
diff changeset
    39
    changelog,
27480
509159675cdb store: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26778
diff changeset
    40
    error,
50627
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
    41
    filelog,
42905
3df3b139a43d localrepo: push manifestlog and changelog construction code into store
Augie Fackler <augie@google.com>
parents: 42715
diff changeset
    42
    manifest,
32372
df448de7cf3b parsers: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 31362
diff changeset
    43
    policy,
30077
8f42d8c412c8 py3: make encodefun in store.py compatible with py3k
Mateusz Kwapich <mitrandir@fb.com>
parents: 30076
diff changeset
    44
    pycompat,
50672
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
    45
    revlog as revlogmod,
27480
509159675cdb store: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26778
diff changeset
    46
    util,
31234
9b7a2ef4f27c vfs: use 'vfs' module directly in 'mercurial.store'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31219
diff changeset
    47
    vfs as vfsmod,
27480
509159675cdb store: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26778
diff changeset
    48
)
44060
a61287a95dc3 core: migrate uses of hashlib.sha1 to hashutil.sha1
Augie Fackler <augie@google.com>
parents: 43506
diff changeset
    49
from .utils import hashutil
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
    50
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
    51
parsers = policy.importmod('parsers')
41978
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
    52
# how much bytes should be read from fncache in one read
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
    53
# It is done to prevent loading large fncache files into memory
51703
ca7bde5dbafb black: format the codebase with 23.3.0
Raphaël Gomès <rgomes@octobus.net>
parents: 51700
diff changeset
    54
fncache_chunksize = 10**6
32372
df448de7cf3b parsers: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 31362
diff changeset
    55
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
    56
51728
2e9e62242451 typing: disable some pytype errors in `mercurial.store`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51703
diff changeset
    57
def _match_tracked_entry(entry: "BaseStoreEntry", matcher):
40494
9aeb9e2d28a7 store: introduce _matchtrackedpath() and use it to filter store files
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40340
diff changeset
    58
    """parses a fncache entry and returns whether the entry is tracking a path
9aeb9e2d28a7 store: introduce _matchtrackedpath() and use it to filter store files
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40340
diff changeset
    59
    matched by matcher or not.
9aeb9e2d28a7 store: introduce _matchtrackedpath() and use it to filter store files
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40340
diff changeset
    60
9aeb9e2d28a7 store: introduce _matchtrackedpath() and use it to filter store files
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40340
diff changeset
    61
    If matcher is None, returns True"""
9aeb9e2d28a7 store: introduce _matchtrackedpath() and use it to filter store files
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40340
diff changeset
    62
9aeb9e2d28a7 store: introduce _matchtrackedpath() and use it to filter store files
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40340
diff changeset
    63
    if matcher is None:
9aeb9e2d28a7 store: introduce _matchtrackedpath() and use it to filter store files
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40340
diff changeset
    64
        return True
51728
2e9e62242451 typing: disable some pytype errors in `mercurial.store`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51703
diff changeset
    65
2e9e62242451 typing: disable some pytype errors in `mercurial.store`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51703
diff changeset
    66
    # TODO: make this safe for other entry types.  Currently, the various
2e9e62242451 typing: disable some pytype errors in `mercurial.store`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51703
diff changeset
    67
    #  store.data_entry generators only yield  RevlogStoreEntry, so the
2e9e62242451 typing: disable some pytype errors in `mercurial.store`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51703
diff changeset
    68
    #  attributes do exist on `entry`.
2e9e62242451 typing: disable some pytype errors in `mercurial.store`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51703
diff changeset
    69
    # pytype: disable=attribute-error
50498
1b776f25302f store: use the boolean property in `store`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50497
diff changeset
    70
    if entry.is_filelog:
50494
b4953fad744e store: do the revlog matching on entry directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50493
diff changeset
    71
        return matcher(entry.target_id)
50498
1b776f25302f store: use the boolean property in `store`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50497
diff changeset
    72
    elif entry.is_manifestlog:
50494
b4953fad744e store: do the revlog matching on entry directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50493
diff changeset
    73
        return matcher.visitdir(entry.target_id.rstrip(b'/'))
51728
2e9e62242451 typing: disable some pytype errors in `mercurial.store`
Matt Harbison <matt_harbison@yahoo.com>
parents: 51703
diff changeset
    74
    # pytype: enable=attribute-error
50494
b4953fad744e store: do the revlog matching on entry directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50493
diff changeset
    75
    raise error.ProgrammingError(b"cannot process entry %r" % entry)
40624
66adfd58cb77 store: raise ProgrammingError if unable to decode a storage path
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40584
diff changeset
    76
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
    77
8531
810387f59696 filelog encoding: move the encoding/decoding into store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8530
diff changeset
    78
# This avoids a collision between a file named foo and a dir named
810387f59696 filelog encoding: move the encoding/decoding into store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8530
diff changeset
    79
# foo.i or foo.d
17607
cc58dc47cb5e store: use fast C implementation of encodedir() if it's available
Adrian Buehlmann <adrian@cadifra.com>
parents: 17605
diff changeset
    80
def _encodedir(path):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
    81
    """
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
    82
    >>> _encodedir(b'data/foo.i')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
    83
    'data/foo.i'
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
    84
    >>> _encodedir(b'data/foo.i/bla.i')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
    85
    'data/foo.i.hg/bla.i'
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
    86
    >>> _encodedir(b'data/foo.i.hg/bla.i')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
    87
    'data/foo.i.hg.hg/bla.i'
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
    88
    >>> _encodedir(b'data/foo.i\\ndata/foo.i/bla.i\\ndata/foo.i.hg/bla.i\\n')
17605
e9cc29be3305 store: add multiline doctest case for encodedir()
Adrian Buehlmann <adrian@cadifra.com>
parents: 17604
diff changeset
    89
    'data/foo.i\\ndata/foo.i.hg/bla.i\\ndata/foo.i.hg.hg/bla.i\\n'
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
    90
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
    91
    return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    92
        path.replace(b".hg/", b".hg.hg/")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    93
        .replace(b".i/", b".i.hg/")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    94
        .replace(b".d/", b".d.hg/")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
    95
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
    96
8531
810387f59696 filelog encoding: move the encoding/decoding into store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8530
diff changeset
    97
17607
cc58dc47cb5e store: use fast C implementation of encodedir() if it's available
Adrian Buehlmann <adrian@cadifra.com>
parents: 17605
diff changeset
    98
encodedir = getattr(parsers, 'encodedir', _encodedir)
cc58dc47cb5e store: use fast C implementation of encodedir() if it's available
Adrian Buehlmann <adrian@cadifra.com>
parents: 17605
diff changeset
    99
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   100
8531
810387f59696 filelog encoding: move the encoding/decoding into store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8530
diff changeset
   101
def decodedir(path):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   102
    """
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   103
    >>> decodedir(b'data/foo.i')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   104
    'data/foo.i'
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   105
    >>> decodedir(b'data/foo.i.hg/bla.i')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   106
    'data/foo.i/bla.i'
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   107
    >>> decodedir(b'data/foo.i.hg.hg/bla.i')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   108
    'data/foo.i.hg/bla.i'
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   109
    """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   110
    if b".hg/" not in path:
8531
810387f59696 filelog encoding: move the encoding/decoding into store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8530
diff changeset
   111
        return path
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   112
    return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   113
        path.replace(b".d.hg/", b".d/")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   114
        .replace(b".i.hg/", b".i/")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   115
        .replace(b".hg.hg/", b".hg/")
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   116
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   117
8531
810387f59696 filelog encoding: move the encoding/decoding into store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8530
diff changeset
   118
29071
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   119
def _reserved():
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   120
    """characters that are problematic for filesystems
29071
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   121
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   122
    * ascii escapes (0..31)
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   123
    * ascii hi (126..255)
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   124
    * windows specials
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   125
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   126
    these characters will be escaped by encodefunctions
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   127
    """
30076
400dfded8a29 py3: make the string unicode so its iterable in py3k
Mateusz Kwapich <mitrandir@fb.com>
parents: 29338
diff changeset
   128
    winreserved = [ord(x) for x in u'\\:*?"<>|']
29071
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   129
    for x in range(32):
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   130
        yield x
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   131
    for x in range(126, 256):
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   132
        yield x
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   133
    for x in winreserved:
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   134
        yield x
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   135
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   136
6839
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   137
def _buildencodefun():
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   138
    """
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   139
    >>> enc, dec = _buildencodefun()
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   140
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   141
    >>> enc(b'nothing/special.txt')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   142
    'nothing/special.txt'
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   143
    >>> dec(b'nothing/special.txt')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   144
    'nothing/special.txt'
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   145
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   146
    >>> enc(b'HELLO')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   147
    '_h_e_l_l_o'
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   148
    >>> dec(b'_h_e_l_l_o')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   149
    'HELLO'
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   150
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   151
    >>> enc(b'hello:world?')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   152
    'hello~3aworld~3f'
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   153
    >>> dec(b'hello~3aworld~3f')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   154
    'hello:world?'
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   155
34136
414a3513c2bd doctest: do not embed non-ascii characters in docstring
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
   156
    >>> enc(b'the\\x07quick\\xADshot')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   157
    'the~07quick~adshot'
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   158
    >>> dec(b'the~07quick~adshot')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   159
    'the\\x07quick\\xadshot'
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   160
    """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   161
    e = b'_'
31253
64596338ba10 py3: factor out bytechr() function
Yuya Nishihara <yuya@tcha.org>
parents: 31234
diff changeset
   162
    xchr = pycompat.bytechr
64596338ba10 py3: factor out bytechr() function
Yuya Nishihara <yuya@tcha.org>
parents: 31234
diff changeset
   163
    asciistr = list(map(xchr, range(127)))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   164
    capitals = list(range(ord(b"A"), ord(b"Z") + 1))
30077
8f42d8c412c8 py3: make encodefun in store.py compatible with py3k
Mateusz Kwapich <mitrandir@fb.com>
parents: 30076
diff changeset
   165
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 44060
diff changeset
   166
    cmap = {x: x for x in asciistr}
29071
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   167
    for x in _reserved():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   168
        cmap[xchr(x)] = b"~%02x" % x
30077
8f42d8c412c8 py3: make encodefun in store.py compatible with py3k
Mateusz Kwapich <mitrandir@fb.com>
parents: 30076
diff changeset
   169
    for x in capitals + [ord(e)]:
8f42d8c412c8 py3: make encodefun in store.py compatible with py3k
Mateusz Kwapich <mitrandir@fb.com>
parents: 30076
diff changeset
   170
        cmap[xchr(x)] = e + xchr(x).lower()
8f42d8c412c8 py3: make encodefun in store.py compatible with py3k
Mateusz Kwapich <mitrandir@fb.com>
parents: 30076
diff changeset
   171
6839
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   172
    dmap = {}
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   173
    for k, v in cmap.items():
6839
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   174
        dmap[v] = k
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   175
6839
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   176
    def decode(s):
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   177
        i = 0
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   178
        while i < len(s):
49284
d44e3c45f0e4 py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
   179
            for l in range(1, 4):
6839
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   180
                try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   181
                    yield dmap[s[i : i + l]]
6839
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   182
                    i += l
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   183
                    break
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   184
                except KeyError:
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   185
                    pass
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   186
            else:
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   187
                raise KeyError
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   188
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   189
    return (
49284
d44e3c45f0e4 py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
   190
        lambda s: b''.join([cmap[s[c : c + 1]] for c in range(len(s))]),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   191
        lambda s: b''.join(list(decode(s))),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   192
    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   193
17608
776240123525 store: extract functions _encodefname and _decodefname
Adrian Buehlmann <adrian@cadifra.com>
parents: 17607
diff changeset
   194
776240123525 store: extract functions _encodefname and _decodefname
Adrian Buehlmann <adrian@cadifra.com>
parents: 17607
diff changeset
   195
_encodefname, _decodefname = _buildencodefun()
6839
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   196
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   197
17608
776240123525 store: extract functions _encodefname and _decodefname
Adrian Buehlmann <adrian@cadifra.com>
parents: 17607
diff changeset
   198
def encodefilename(s):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   199
    """
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   200
    >>> encodefilename(b'foo.i/bar.d/bla.hg/hi:world?/HELLO')
17608
776240123525 store: extract functions _encodefname and _decodefname
Adrian Buehlmann <adrian@cadifra.com>
parents: 17607
diff changeset
   201
    'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o'
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   202
    """
17608
776240123525 store: extract functions _encodefname and _decodefname
Adrian Buehlmann <adrian@cadifra.com>
parents: 17607
diff changeset
   203
    return _encodefname(encodedir(s))
776240123525 store: extract functions _encodefname and _decodefname
Adrian Buehlmann <adrian@cadifra.com>
parents: 17607
diff changeset
   204
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   205
17608
776240123525 store: extract functions _encodefname and _decodefname
Adrian Buehlmann <adrian@cadifra.com>
parents: 17607
diff changeset
   206
def decodefilename(s):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   207
    """
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   208
    >>> decodefilename(b'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o')
17608
776240123525 store: extract functions _encodefname and _decodefname
Adrian Buehlmann <adrian@cadifra.com>
parents: 17607
diff changeset
   209
    'foo.i/bar.d/bla.hg/hi:world?/HELLO'
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   210
    """
17608
776240123525 store: extract functions _encodefname and _decodefname
Adrian Buehlmann <adrian@cadifra.com>
parents: 17607
diff changeset
   211
    return decodedir(_decodefname(s))
6839
01db3e101362 move filename encoding functions from util.py to new store.py
Adrian Buehlmann <adrian@cadifra.com>
parents:
diff changeset
   212
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   213
14288
00a0ab08f986 store: change names to comply with project coding standards
Adrian Buehlmann <adrian@cadifra.com>
parents: 14194
diff changeset
   214
def _buildlowerencodefun():
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   215
    """
14288
00a0ab08f986 store: change names to comply with project coding standards
Adrian Buehlmann <adrian@cadifra.com>
parents: 14194
diff changeset
   216
    >>> f = _buildlowerencodefun()
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   217
    >>> f(b'nothing/special.txt')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   218
    'nothing/special.txt'
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   219
    >>> f(b'HELLO')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   220
    'hello'
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   221
    >>> f(b'hello:world?')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   222
    'hello~3aworld~3f'
34136
414a3513c2bd doctest: do not embed non-ascii characters in docstring
Yuya Nishihara <yuya@tcha.org>
parents: 34131
diff changeset
   223
    >>> f(b'the\\x07quick\\xADshot')
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   224
    'the~07quick~adshot'
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   225
    """
34214
7e3f078b6f31 py3: use bytechr() in store._buildlowerencodefun()
Yuya Nishihara <yuya@tcha.org>
parents: 34213
diff changeset
   226
    xchr = pycompat.bytechr
49284
d44e3c45f0e4 py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
   227
    cmap = {xchr(x): xchr(x) for x in range(127)}
29071
2f58975eb2cb store: treat range as a generator instead of a list for py3 compat
timeless <timeless@mozdev.org>
parents: 28007
diff changeset
   228
    for x in _reserved():
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   229
        cmap[xchr(x)] = b"~%02x" % x
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   230
    for x in range(ord(b"A"), ord(b"Z") + 1):
34214
7e3f078b6f31 py3: use bytechr() in store._buildlowerencodefun()
Yuya Nishihara <yuya@tcha.org>
parents: 34213
diff changeset
   231
        cmap[xchr(x)] = xchr(x).lower()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   232
34213
96808804b68f store: give name to lowerencode function
Yuya Nishihara <yuya@tcha.org>
parents: 34136
diff changeset
   233
    def lowerencode(s):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   234
        return b"".join([cmap[c] for c in pycompat.iterbytestr(s)])
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   235
34213
96808804b68f store: give name to lowerencode function
Yuya Nishihara <yuya@tcha.org>
parents: 34136
diff changeset
   236
    return lowerencode
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   237
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   238
18430
0459c6555f69 store: implement lowerencode in C
Bryan O'Sullivan <bryano@fb.com>
parents: 18054
diff changeset
   239
lowerencode = getattr(parsers, 'lowerencode', None) or _buildlowerencodefun()
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   240
17570
f53a7b256ca6 store: optimze _auxencode() a bit by grouping the reserved names by length
Adrian Buehlmann <adrian@cadifra.com>
parents: 17569
diff changeset
   241
# Windows reserved names: con, prn, aux, nul, com1..com9, lpt1..lpt9
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   242
_winres3 = (b'aux', b'con', b'prn', b'nul')  # length 3
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   243
_winres4 = (b'com', b'lpt')  # length 4 (with trailing 1..9)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   244
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   245
12687
34d8247a4595 store: encode first period or space in filenames (issue1713)
Adrian Buehlmann <adrian@cadifra.com>
parents: 12171
diff changeset
   246
def _auxencode(path, dotencode):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   247
    """
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   248
    Encodes filenames containing names reserved by Windows or which end in
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   249
    period or space. Does not touch other single reserved characters c.
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   250
    Specifically, c in '\\:*?"<>|' or ord(c) <= 31 are *not* encoded here.
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   251
    Additionally encodes space or period at the beginning, if dotencode is
17569
e9af2134825c store: explain "aux.foo" versus "foo.aux" in doc of _auxencode()
Adrian Buehlmann <adrian@cadifra.com>
parents: 17568
diff changeset
   252
    True. Parameter path is assumed to be all lowercase.
e9af2134825c store: explain "aux.foo" versus "foo.aux" in doc of _auxencode()
Adrian Buehlmann <adrian@cadifra.com>
parents: 17568
diff changeset
   253
    A segment only needs encoding if a reserved name appears as a
e9af2134825c store: explain "aux.foo" versus "foo.aux" in doc of _auxencode()
Adrian Buehlmann <adrian@cadifra.com>
parents: 17568
diff changeset
   254
    basename (e.g. "aux", "aux.foo"). A directory or file named "foo.aux"
e9af2134825c store: explain "aux.foo" versus "foo.aux" in doc of _auxencode()
Adrian Buehlmann <adrian@cadifra.com>
parents: 17568
diff changeset
   255
    doesn't need encoding.
13949
ba43aa1e173c store: add some doctests
Adrian Buehlmann <adrian@cadifra.com>
parents: 13426
diff changeset
   256
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   257
    >>> s = b'.foo/aux.txt/txt.aux/con/prn/nul/foo.'
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   258
    >>> _auxencode(s.split(b'/'), True)
17574
81a033bb29bc store: let _auxencode() return the list of path segments
Adrian Buehlmann <adrian@cadifra.com>
parents: 17573
diff changeset
   259
    ['~2efoo', 'au~78.txt', 'txt.aux', 'co~6e', 'pr~6e', 'nu~6c', 'foo~2e']
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   260
    >>> s = b'.com1com2/lpt9.lpt4.lpt1/conprn/com0/lpt0/foo.'
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   261
    >>> _auxencode(s.split(b'/'), False)
17574
81a033bb29bc store: let _auxencode() return the list of path segments
Adrian Buehlmann <adrian@cadifra.com>
parents: 17573
diff changeset
   262
    ['.com1com2', 'lp~749.lpt4.lpt1', 'conprn', 'com0', 'lpt0', 'foo~2e']
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   263
    >>> _auxencode([b'foo. '], True)
17574
81a033bb29bc store: let _auxencode() return the list of path segments
Adrian Buehlmann <adrian@cadifra.com>
parents: 17573
diff changeset
   264
    ['foo.~20']
34131
0fa781320203 doctest: bulk-replace string literals with b'' for Python 3
Yuya Nishihara <yuya@tcha.org>
parents: 33412
diff changeset
   265
    >>> _auxencode([b' .foo'], True)
17574
81a033bb29bc store: let _auxencode() return the list of path segments
Adrian Buehlmann <adrian@cadifra.com>
parents: 17573
diff changeset
   266
    ['~20.foo']
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   267
    """
17589
b11024849db6 store: parameter path of _auxencode is now a list of strings
Adrian Buehlmann <adrian@cadifra.com>
parents: 17588
diff changeset
   268
    for i, n in enumerate(path):
17572
b644287e79a8 store: unindent most of the contents of the for loop in _auxencode()
Adrian Buehlmann <adrian@cadifra.com>
parents: 17571
diff changeset
   269
        if not n:
b644287e79a8 store: unindent most of the contents of the for loop in _auxencode()
Adrian Buehlmann <adrian@cadifra.com>
parents: 17571
diff changeset
   270
            continue
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   271
        if dotencode and n[0] in b'. ':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   272
            n = b"~%02x" % ord(n[0:1]) + n[1:]
17589
b11024849db6 store: parameter path of _auxencode is now a list of strings
Adrian Buehlmann <adrian@cadifra.com>
parents: 17588
diff changeset
   273
            path[i] = n
17572
b644287e79a8 store: unindent most of the contents of the for loop in _auxencode()
Adrian Buehlmann <adrian@cadifra.com>
parents: 17571
diff changeset
   274
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   275
            l = n.find(b'.')
17572
b644287e79a8 store: unindent most of the contents of the for loop in _auxencode()
Adrian Buehlmann <adrian@cadifra.com>
parents: 17571
diff changeset
   276
            if l == -1:
b644287e79a8 store: unindent most of the contents of the for loop in _auxencode()
Adrian Buehlmann <adrian@cadifra.com>
parents: 17571
diff changeset
   277
                l = len(n)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   278
            if (l == 3 and n[:3] in _winres3) or (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   279
                l == 4
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   280
                and n[3:4] <= b'9'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   281
                and n[3:4] >= b'1'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   282
                and n[:3] in _winres4
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   283
            ):
17572
b644287e79a8 store: unindent most of the contents of the for loop in _auxencode()
Adrian Buehlmann <adrian@cadifra.com>
parents: 17571
diff changeset
   284
                # encode third letter ('aux' -> 'au~78')
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   285
                ec = b"~%02x" % ord(n[2:3])
17572
b644287e79a8 store: unindent most of the contents of the for loop in _auxencode()
Adrian Buehlmann <adrian@cadifra.com>
parents: 17571
diff changeset
   286
                n = n[0:2] + ec + n[3:]
17589
b11024849db6 store: parameter path of _auxencode is now a list of strings
Adrian Buehlmann <adrian@cadifra.com>
parents: 17588
diff changeset
   287
                path[i] = n
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   288
        if n[-1] in b'. ':
17572
b644287e79a8 store: unindent most of the contents of the for loop in _auxencode()
Adrian Buehlmann <adrian@cadifra.com>
parents: 17571
diff changeset
   289
            # encode last period or space ('foo...' -> 'foo..~2e')
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   290
            path[i] = n[:-1] + b"~%02x" % ord(n[-1:])
17589
b11024849db6 store: parameter path of _auxencode is now a list of strings
Adrian Buehlmann <adrian@cadifra.com>
parents: 17588
diff changeset
   291
    return path
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   292
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   293
14288
00a0ab08f986 store: change names to comply with project coding standards
Adrian Buehlmann <adrian@cadifra.com>
parents: 14194
diff changeset
   294
_maxstorepathlen = 120
00a0ab08f986 store: change names to comply with project coding standards
Adrian Buehlmann <adrian@cadifra.com>
parents: 14194
diff changeset
   295
_dirprefixlen = 8
00a0ab08f986 store: change names to comply with project coding standards
Adrian Buehlmann <adrian@cadifra.com>
parents: 14194
diff changeset
   296
_maxshortdirslen = 8 * (_dirprefixlen + 1) - 4
17610
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   297
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   298
17610
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   299
def _hashencode(path, dotencode):
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   300
    digest = hex(hashutil.sha1(path).digest())
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   301
    le = lowerencode(path[5:]).split(b'/')  # skips prefix 'data/' or 'meta/'
17610
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   302
    parts = _auxencode(le, dotencode)
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   303
    basename = parts[-1]
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   304
    _root, ext = os.path.splitext(basename)
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   305
    sdirs = []
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   306
    sdirslen = 0
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   307
    for p in parts[:-1]:
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   308
        d = p[:_dirprefixlen]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   309
        if d[-1] in b'. ':
17610
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   310
            # Windows can't access dirs ending in period or space
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   311
            d = d[:-1] + b'_'
17610
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   312
        if sdirslen == 0:
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   313
            t = len(d)
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   314
        else:
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   315
            t = sdirslen + 1 + len(d)
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   316
            if t > _maxshortdirslen:
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   317
                break
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   318
        sdirs.append(d)
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   319
        sdirslen = t
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   320
    dirs = b'/'.join(sdirs)
17610
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   321
    if len(dirs) > 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   322
        dirs += b'/'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   323
    res = b'dh/' + dirs + digest + ext
17610
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   324
    spaceleft = _maxstorepathlen - len(res)
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   325
    if spaceleft > 0:
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   326
        filler = basename[:spaceleft]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   327
        res = b'dh/' + dirs + filler + digest + ext
17610
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   328
    return res
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   329
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   330
17590
eb0884680f5c store: eliminate one level of lambda functions on _hybridencode
Adrian Buehlmann <adrian@cadifra.com>
parents: 17589
diff changeset
   331
def _hybridencode(path, dotencode):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   332
    """encodes path with a length limit
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   333
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   334
    Encodes all paths that begin with 'data/', according to the following.
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   335
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   336
    Default encoding (reversible):
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   337
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   338
    Encodes all uppercase letters 'X' as '_x'. All reserved or illegal
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   339
    characters are encoded as '~xx', where xx is the two digit hex code
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   340
    of the character (see encodefilename).
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   341
    Relevant path components consisting of Windows reserved filenames are
17738
b8424c92ba2b spelling: fix minor spell checker issues
Mads Kiilerich <mads@kiilerich.com>
parents: 17731
diff changeset
   342
    masked by encoding the third character ('aux' -> 'au~78', see _auxencode).
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   343
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   344
    Hashed encoding (not reversible):
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   345
14288
00a0ab08f986 store: change names to comply with project coding standards
Adrian Buehlmann <adrian@cadifra.com>
parents: 14194
diff changeset
   346
    If the default-encoded path is longer than _maxstorepathlen, a
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   347
    non-reversible hybrid hashing of the path is done instead.
14288
00a0ab08f986 store: change names to comply with project coding standards
Adrian Buehlmann <adrian@cadifra.com>
parents: 14194
diff changeset
   348
    This encoding uses up to _dirprefixlen characters of all directory
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   349
    levels of the lowerencoded path, but not more levels than can fit into
14288
00a0ab08f986 store: change names to comply with project coding standards
Adrian Buehlmann <adrian@cadifra.com>
parents: 14194
diff changeset
   350
    _maxshortdirslen.
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   351
    Then follows the filler followed by the sha digest of the full path.
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   352
    The filler is the beginning of the basename of the lowerencoded path
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   353
    (the basename is everything after the last path separator). The filler
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   354
    is as long as possible, filling in characters from the basename until
14288
00a0ab08f986 store: change names to comply with project coding standards
Adrian Buehlmann <adrian@cadifra.com>
parents: 14194
diff changeset
   355
    the encoded path has _maxstorepathlen characters (or all chars of the
00a0ab08f986 store: change names to comply with project coding standards
Adrian Buehlmann <adrian@cadifra.com>
parents: 14194
diff changeset
   356
    basename have been taken).
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   357
    The extension (e.g. '.i' or '.d') is preserved.
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   358
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   359
    The string 'data/' at the beginning is replaced with 'dh/', if the hashed
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   360
    encoding was used.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   361
    """
17609
cbc180cfd60b store: reuse direncoded path in _hybridencode
Adrian Buehlmann <adrian@cadifra.com>
parents: 17608
diff changeset
   362
    path = encodedir(path)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   363
    ef = _encodefname(path).split(b'/')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   364
    res = b'/'.join(_auxencode(ef, dotencode))
14288
00a0ab08f986 store: change names to comply with project coding standards
Adrian Buehlmann <adrian@cadifra.com>
parents: 14194
diff changeset
   365
    if len(res) > _maxstorepathlen:
17610
d0afa149e059 store: refactor hashed encoding into its own function
Bryan O'Sullivan <bryano@fb.com>
parents: 17609
diff changeset
   366
        res = _hashencode(path, dotencode)
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   367
    return res
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   368
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   369
17624
ae103510f6aa store: add a fallback _pathencode Python function
Adrian Buehlmann <adrian@cadifra.com>
parents: 17623
diff changeset
   370
def _pathencode(path):
18435
8c019d2fd7c0 store: switch to C-based hashed path encoding
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   371
    de = encodedir(path)
17693
0c6de45e1212 store: optimize _pathencode by checking the length of the unencoded path
Adrian Buehlmann <adrian@cadifra.com>
parents: 17653
diff changeset
   372
    if len(path) > _maxstorepathlen:
18435
8c019d2fd7c0 store: switch to C-based hashed path encoding
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   373
        return _hashencode(de, True)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   374
    ef = _encodefname(de).split(b'/')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   375
    res = b'/'.join(_auxencode(ef, True))
17624
ae103510f6aa store: add a fallback _pathencode Python function
Adrian Buehlmann <adrian@cadifra.com>
parents: 17623
diff changeset
   376
    if len(res) > _maxstorepathlen:
18435
8c019d2fd7c0 store: switch to C-based hashed path encoding
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
   377
        return _hashencode(de, True)
17624
ae103510f6aa store: add a fallback _pathencode Python function
Adrian Buehlmann <adrian@cadifra.com>
parents: 17623
diff changeset
   378
    return res
ae103510f6aa store: add a fallback _pathencode Python function
Adrian Buehlmann <adrian@cadifra.com>
parents: 17623
diff changeset
   379
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   380
17624
ae103510f6aa store: add a fallback _pathencode Python function
Adrian Buehlmann <adrian@cadifra.com>
parents: 17623
diff changeset
   381
_pathencode = getattr(parsers, 'pathencode', _pathencode)
ae103510f6aa store: add a fallback _pathencode Python function
Adrian Buehlmann <adrian@cadifra.com>
parents: 17623
diff changeset
   382
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   383
17623
448e6ed7c557 store: move _plainhybridencode and _dothybridencode higher up in the file
Adrian Buehlmann <adrian@cadifra.com>
parents: 17621
diff changeset
   384
def _plainhybridencode(f):
448e6ed7c557 store: move _plainhybridencode and _dothybridencode higher up in the file
Adrian Buehlmann <adrian@cadifra.com>
parents: 17621
diff changeset
   385
    return _hybridencode(f, False)
448e6ed7c557 store: move _plainhybridencode and _dothybridencode higher up in the file
Adrian Buehlmann <adrian@cadifra.com>
parents: 17621
diff changeset
   386
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   387
17726
7cb7e17c23b2 store: invoke "os.stat()" for "createmode" initialization via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17725
diff changeset
   388
def _calcmode(vfs):
6898
69aeaaaf6e07 store: simplify class hierarchy
Matt Mackall <mpm@selenic.com>
parents: 6897
diff changeset
   389
    try:
69aeaaaf6e07 store: simplify class hierarchy
Matt Mackall <mpm@selenic.com>
parents: 6897
diff changeset
   390
        # files in .hg/ will be created using this mode
17726
7cb7e17c23b2 store: invoke "os.stat()" for "createmode" initialization via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17725
diff changeset
   391
        mode = vfs.stat().st_mode
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   392
        # avoid some useless chmods
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25091
diff changeset
   393
        if (0o777 & ~util.umask) == (0o777 & mode):
6898
69aeaaaf6e07 store: simplify class hierarchy
Matt Mackall <mpm@selenic.com>
parents: 6897
diff changeset
   394
            mode = None
69aeaaaf6e07 store: simplify class hierarchy
Matt Mackall <mpm@selenic.com>
parents: 6897
diff changeset
   395
    except OSError:
69aeaaaf6e07 store: simplify class hierarchy
Matt Mackall <mpm@selenic.com>
parents: 6897
diff changeset
   396
        mode = None
69aeaaaf6e07 store: simplify class hierarchy
Matt Mackall <mpm@selenic.com>
parents: 6897
diff changeset
   397
    return mode
69aeaaaf6e07 store: simplify class hierarchy
Matt Mackall <mpm@selenic.com>
parents: 6897
diff changeset
   398
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   399
45351
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
   400
_data = [
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
   401
    b'bookmarks',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
   402
    b'narrowspec',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
   403
    b'data',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
   404
    b'meta',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
   405
    b'00manifest.d',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
   406
    b'00manifest.i',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
   407
    b'00changelog.d',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
   408
    b'00changelog.i',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
   409
    b'phaseroots',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
   410
    b'obsstore',
45483
d252f51ab032 share: introduce config option to store requires in .hg/store
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45351
diff changeset
   411
    b'requires',
45351
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
   412
]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   413
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   414
REVLOG_FILES_EXT = (
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   415
    b'.i',
47324
0a3fa41fa719 revlogv2: use a unique filename for data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47234
diff changeset
   416
    b'.idx',
0a3fa41fa719 revlogv2: use a unique filename for data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47234
diff changeset
   417
    b'.d',
0a3fa41fa719 revlogv2: use a unique filename for data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47234
diff changeset
   418
    b'.dat',
0a3fa41fa719 revlogv2: use a unique filename for data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47234
diff changeset
   419
    b'.n',
0a3fa41fa719 revlogv2: use a unique filename for data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47234
diff changeset
   420
    b'.nd',
47389
e6292eb33384 revlog: store sidedata in their own file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47324
diff changeset
   421
    b'.sda',
47324
0a3fa41fa719 revlogv2: use a unique filename for data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47234
diff changeset
   422
)
50479
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   423
# file extension that also use a `-SOMELONGIDHASH.ext` form
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   424
REVLOG_FILES_LONG_EXT = (
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   425
    b'.nd',
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   426
    b'.idx',
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   427
    b'.dat',
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   428
    b'.sda',
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   429
)
46989
aed6ceaad6d7 streamclone: treat volatile file as "fullfile"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46895
diff changeset
   430
# files that are "volatile" and might change between listing and streaming
aed6ceaad6d7 streamclone: treat volatile file as "fullfile"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46895
diff changeset
   431
#
aed6ceaad6d7 streamclone: treat volatile file as "fullfile"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46895
diff changeset
   432
# note: the ".nd" file are nodemap data and won't "change" but they might be
aed6ceaad6d7 streamclone: treat volatile file as "fullfile"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46895
diff changeset
   433
# deleted.
aed6ceaad6d7 streamclone: treat volatile file as "fullfile"
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46895
diff changeset
   434
REVLOG_FILES_VOLATILE_EXT = (b'.n', b'.nd')
46895
6085b7f1536d store: also return some information about the type of file `walk` found
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46854
diff changeset
   435
46990
0b569c75d180 store: exclude `undo.` nodemap's file from `walk`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46989
diff changeset
   436
# some exception to the above matching
47659
f030c7d22032 walk: no longer ignore revlogs of files starting with `undo.` (issue6542)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   437
#
f030c7d22032 walk: no longer ignore revlogs of files starting with `undo.` (issue6542)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47443
diff changeset
   438
# XXX This is currently not in use because of issue6542
50319
4be9ecc982e1 py3: fix for Python 3.12 emitting SyntaxWarning on invalid escape sequences
Mads Kiilerich <mads@kiilerich.com>
parents: 50315
diff changeset
   439
EXCLUDED = re.compile(br'.*undo\.[^/]+\.(nd?|i)$')
46990
0b569c75d180 store: exclude `undo.` nodemap's file from `walk`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46989
diff changeset
   440
46895
6085b7f1536d store: also return some information about the type of file `walk` found
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46854
diff changeset
   441
6085b7f1536d store: also return some information about the type of file `walk` found
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46854
diff changeset
   442
def is_revlog(f, kind, st):
6085b7f1536d store: also return some information about the type of file `walk` found
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46854
diff changeset
   443
    if kind != stat.S_IFREG:
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   444
        return False
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   445
    if f.endswith(REVLOG_FILES_EXT):
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   446
        return True
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   447
    return False
46895
6085b7f1536d store: also return some information about the type of file `walk` found
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46854
diff changeset
   448
6085b7f1536d store: also return some information about the type of file `walk` found
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46854
diff changeset
   449
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   450
def is_revlog_file(f):
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   451
    if f.endswith(REVLOG_FILES_EXT):
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   452
        return True
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   453
    return False
46383
374d7fff7cb5 store: use `endswith` to detect revlog extension
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46322
diff changeset
   454
6903
0642d9d7ec80 clone: get a list of files to clone from store
Matt Mackall <mpm@selenic.com>
parents: 6902
diff changeset
   455
50638
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   456
@attr.s(slots=True)
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   457
class StoreFile:
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   458
    """a file matching a store entry"""
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   459
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   460
    unencoded_path = attr.ib()
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   461
    _file_size = attr.ib(default=None)
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   462
    is_volatile = attr.ib(default=False)
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   463
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   464
    def file_size(self, vfs):
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   465
        if self._file_size is None:
50639
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   466
            if vfs is None:
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   467
                msg = b"calling vfs-less file_size without prior call: %s"
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   468
                msg %= self.unencoded_path
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   469
                raise error.ProgrammingError(msg)
50638
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   470
            try:
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   471
                self._file_size = vfs.stat(self.unencoded_path).st_size
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   472
            except FileNotFoundError:
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   473
                self._file_size = 0
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   474
        return self._file_size
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   475
51547
8e2a68e10f5c stream: in v3, skip the "size" fast path if the entries as some unknown size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
   476
    @property
8e2a68e10f5c stream: in v3, skip the "size" fast path if the entries as some unknown size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
   477
    def has_size(self):
8e2a68e10f5c stream: in v3, skip the "size" fast path if the entries as some unknown size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
   478
        return self._file_size is not None
8e2a68e10f5c stream: in v3, skip the "size" fast path if the entries as some unknown size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
   479
52016
e308439339e2 stream: rename TempCopyManager to VolatileManager
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51882
diff changeset
   480
    def get_stream(self, vfs, volatiles):
50639
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   481
        """return data "stream" information for this file
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   482
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   483
        (unencoded_file_path, content_iterator, content_size)
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   484
        """
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   485
        size = self.file_size(None)
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   486
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   487
        def get_stream():
52017
0ad269e24075 stream: open volatile file through the manager
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 52016
diff changeset
   488
            path = vfs.join(self.unencoded_path)
0ad269e24075 stream: open volatile file through the manager
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 52016
diff changeset
   489
            with volatiles.open(path) as fp:
50639
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   490
                yield None  # ready to stream
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   491
                if size <= 65536:
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   492
                    yield fp.read(size)
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   493
                else:
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   494
                    yield from util.filechunkiter(fp, limit=size)
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   495
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   496
        s = get_stream()
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   497
        next(s)
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   498
        return (self.unencoded_path, s, size)
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   499
50638
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   500
50474
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   501
@attr.s(slots=True, init=False)
50473
5a2fb64d38b2 store: use specialized class for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50472
diff changeset
   502
class BaseStoreEntry:
50471
521fec115dad store: use a StoreEntry object instead of tuple for store files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50469
diff changeset
   503
    """An entry in the store
521fec115dad store: use a StoreEntry object instead of tuple for store files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50469
diff changeset
   504
521fec115dad store: use a StoreEntry object instead of tuple for store files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50469
diff changeset
   505
    This is returned by `store.walk` and represent some data in the store."""
521fec115dad store: use a StoreEntry object instead of tuple for store files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50469
diff changeset
   506
51552
49faa72b994e streamclone: stop listing files for entries that have no volatile files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51547
diff changeset
   507
    maybe_volatile = True
49faa72b994e streamclone: stop listing files for entries that have no volatile files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51547
diff changeset
   508
50638
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   509
    def files(self) -> List[StoreFile]:
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   510
        raise NotImplementedError
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   511
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   512
    def get_streams(
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   513
        self,
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   514
        repo=None,
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   515
        vfs=None,
52016
e308439339e2 stream: rename TempCopyManager to VolatileManager
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51882
diff changeset
   516
        volatiles=None,
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   517
        max_changeset=None,
50706
0452af304808 stream-clone: add a v3 version of the protocol
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50680
diff changeset
   518
        preserve_file_count=False,
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   519
    ):
50639
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   520
        """return a list of data stream associated to files for this entry
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   521
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   522
        return [(unencoded_file_path, content_iterator, content_size), …]
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   523
        """
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   524
        assert vfs is not None
52016
e308439339e2 stream: rename TempCopyManager to VolatileManager
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51882
diff changeset
   525
        return [f.get_stream(vfs, volatiles) for f in self.files()]
50639
5e60abf811f3 stream-clone: make it the responsability of the store entry to stream content
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50638
diff changeset
   526
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   527
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   528
@attr.s(slots=True, init=False)
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   529
class SimpleStoreEntry(BaseStoreEntry):
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   530
    """A generic entry in the store"""
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   531
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   532
    is_revlog = False
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   533
51552
49faa72b994e streamclone: stop listing files for entries that have no volatile files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51547
diff changeset
   534
    maybe_volatile = attr.ib()
50495
ed8cda1c18e1 store: rename `unencoded_path` to `entry_path` for StoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50494
diff changeset
   535
    _entry_path = attr.ib()
50476
2b2284cf949b store: only access is_volatile information through the file object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50475
diff changeset
   536
    _is_volatile = attr.ib(default=False)
50475
7d4d2a160cf5 store: only access file_size information through the file object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50474
diff changeset
   537
    _file_size = attr.ib(default=None)
50631
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   538
    _files = attr.ib(default=None)
50471
521fec115dad store: use a StoreEntry object instead of tuple for store files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50469
diff changeset
   539
50474
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   540
    def __init__(
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   541
        self,
50495
ed8cda1c18e1 store: rename `unencoded_path` to `entry_path` for StoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50494
diff changeset
   542
        entry_path,
50474
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   543
        is_volatile=False,
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   544
        file_size=None,
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   545
    ):
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   546
        super().__init__()
50495
ed8cda1c18e1 store: rename `unencoded_path` to `entry_path` for StoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50494
diff changeset
   547
        self._entry_path = entry_path
50476
2b2284cf949b store: only access is_volatile information through the file object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50475
diff changeset
   548
        self._is_volatile = is_volatile
50475
7d4d2a160cf5 store: only access file_size information through the file object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50474
diff changeset
   549
        self._file_size = file_size
50631
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   550
        self._files = None
51552
49faa72b994e streamclone: stop listing files for entries that have no volatile files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51547
diff changeset
   551
        self.maybe_volatile = is_volatile
50474
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   552
50638
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   553
    def files(self) -> List[StoreFile]:
50631
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   554
        if self._files is None:
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   555
            self._files = [
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   556
                StoreFile(
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   557
                    unencoded_path=self._entry_path,
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   558
                    file_size=self._file_size,
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   559
                    is_volatile=self._is_volatile,
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   560
                )
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   561
            ]
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   562
        return self._files
50472
9fdc28e21b68 store: introduce a EntryFile object to actually access file info
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50471
diff changeset
   563
9fdc28e21b68 store: introduce a EntryFile object to actually access file info
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50471
diff changeset
   564
50474
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   565
@attr.s(slots=True, init=False)
50473
5a2fb64d38b2 store: use specialized class for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50472
diff changeset
   566
class RevlogStoreEntry(BaseStoreEntry):
5a2fb64d38b2 store: use specialized class for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50472
diff changeset
   567
    """A revlog entry in the store"""
5a2fb64d38b2 store: use specialized class for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50472
diff changeset
   568
5a2fb64d38b2 store: use specialized class for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50472
diff changeset
   569
    is_revlog = True
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   570
50473
5a2fb64d38b2 store: use specialized class for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50472
diff changeset
   571
    revlog_type = attr.ib(default=None)
50483
60e613f6a229 store: add a `target_id` attribute on RevlogStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50482
diff changeset
   572
    target_id = attr.ib(default=None)
51552
49faa72b994e streamclone: stop listing files for entries that have no volatile files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51547
diff changeset
   573
    maybe_volatile = attr.ib(default=True)
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   574
    _path_prefix = attr.ib(default=None)
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   575
    _details = attr.ib(default=None)
50631
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   576
    _files = attr.ib(default=None)
50473
5a2fb64d38b2 store: use specialized class for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50472
diff changeset
   577
50474
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   578
    def __init__(
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   579
        self,
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   580
        revlog_type,
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   581
        path_prefix,
50483
60e613f6a229 store: add a `target_id` attribute on RevlogStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50482
diff changeset
   582
        target_id,
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   583
        details,
50474
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   584
    ):
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   585
        super().__init__()
50474
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   586
        self.revlog_type = revlog_type
50483
60e613f6a229 store: add a `target_id` attribute on RevlogStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50482
diff changeset
   587
        self.target_id = target_id
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   588
        self._path_prefix = path_prefix
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   589
        assert b'.i' in details, (path_prefix, details)
51552
49faa72b994e streamclone: stop listing files for entries that have no volatile files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51547
diff changeset
   590
        for ext in details:
49faa72b994e streamclone: stop listing files for entries that have no volatile files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51547
diff changeset
   591
            if ext.endswith(REVLOG_FILES_VOLATILE_EXT):
49faa72b994e streamclone: stop listing files for entries that have no volatile files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51547
diff changeset
   592
                self.maybe_volatile = True
49faa72b994e streamclone: stop listing files for entries that have no volatile files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51547
diff changeset
   593
                break
49faa72b994e streamclone: stop listing files for entries that have no volatile files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51547
diff changeset
   594
        else:
49faa72b994e streamclone: stop listing files for entries that have no volatile files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51547
diff changeset
   595
            self.maybe_volatile = False
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   596
        self._details = details
50631
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   597
        self._files = None
50474
c37450a5f1dc store: have custom init for entries class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50473
diff changeset
   598
50497
66c556968222 store: introduce boolean property for revlog type
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50496
diff changeset
   599
    @property
66c556968222 store: introduce boolean property for revlog type
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50496
diff changeset
   600
    def is_changelog(self):
50680
e324329fc97e store: use the revlog type from revlog's constant instead of custom one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50672
diff changeset
   601
        return self.revlog_type == KIND_CHANGELOG
50497
66c556968222 store: introduce boolean property for revlog type
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50496
diff changeset
   602
66c556968222 store: introduce boolean property for revlog type
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50496
diff changeset
   603
    @property
66c556968222 store: introduce boolean property for revlog type
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50496
diff changeset
   604
    def is_manifestlog(self):
50680
e324329fc97e store: use the revlog type from revlog's constant instead of custom one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50672
diff changeset
   605
        return self.revlog_type == KIND_MANIFESTLOG
50497
66c556968222 store: introduce boolean property for revlog type
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50496
diff changeset
   606
66c556968222 store: introduce boolean property for revlog type
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50496
diff changeset
   607
    @property
66c556968222 store: introduce boolean property for revlog type
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50496
diff changeset
   608
    def is_filelog(self):
50680
e324329fc97e store: use the revlog type from revlog's constant instead of custom one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50672
diff changeset
   609
        return self.revlog_type == KIND_FILELOG
50497
66c556968222 store: introduce boolean property for revlog type
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50496
diff changeset
   610
50492
3473d18c029a store: introduce a main_file_path method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50483
diff changeset
   611
    def main_file_path(self):
3473d18c029a store: introduce a main_file_path method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50483
diff changeset
   612
        """unencoded path of the main revlog file"""
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   613
        return self._path_prefix + b'.i'
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   614
50638
8fc10bfd9887 store: declare a `files` method on BaseStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50632
diff changeset
   615
    def files(self) -> List[StoreFile]:
50631
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   616
        if self._files is None:
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   617
            self._files = []
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   618
            for ext in sorted(self._details, key=_ext_key):
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   619
                path = self._path_prefix + ext
50670
11562d72cb7b store: directly pass the filesize in the `details` of revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50669
diff changeset
   620
                file_size = self._details[ext]
50668
6b522a9e7451 store: have the revlog determine which files are volatile itself
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50641
diff changeset
   621
                # files that are "volatile" and might change between
6b522a9e7451 store: have the revlog determine which files are volatile itself
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50641
diff changeset
   622
                # listing and streaming
6b522a9e7451 store: have the revlog determine which files are volatile itself
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50641
diff changeset
   623
                #
6b522a9e7451 store: have the revlog determine which files are volatile itself
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50641
diff changeset
   624
                # note: the ".nd" file are nodemap data and won't "change"
6b522a9e7451 store: have the revlog determine which files are volatile itself
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50641
diff changeset
   625
                # but they might be deleted.
6b522a9e7451 store: have the revlog determine which files are volatile itself
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50641
diff changeset
   626
                volatile = ext.endswith(REVLOG_FILES_VOLATILE_EXT)
50669
cdb471c8ebcf store: explicitly pass file_size when creating StoreFile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50668
diff changeset
   627
                f = StoreFile(path, file_size, volatile)
50668
6b522a9e7451 store: have the revlog determine which files are volatile itself
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50641
diff changeset
   628
                self._files.append(f)
50631
b59e0a4f692f store: cache the `files()` return for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50629
diff changeset
   629
        return self._files
50492
3473d18c029a store: introduce a main_file_path method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50483
diff changeset
   630
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   631
    def get_streams(
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   632
        self,
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   633
        repo=None,
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   634
        vfs=None,
52016
e308439339e2 stream: rename TempCopyManager to VolatileManager
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51882
diff changeset
   635
        volatiles=None,
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   636
        max_changeset=None,
50706
0452af304808 stream-clone: add a v3 version of the protocol
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50680
diff changeset
   637
        preserve_file_count=False,
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   638
    ):
51547
8e2a68e10f5c stream: in v3, skip the "size" fast path if the entries as some unknown size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
   639
        pre_sized = all(f.has_size for f in self.files())
8e2a68e10f5c stream: in v3, skip the "size" fast path if the entries as some unknown size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50929
diff changeset
   640
        if pre_sized and (
50672
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   641
            repo is None
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   642
            or max_changeset is None
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   643
            # This use revlog-v2, ignore for now
50672
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   644
            or any(k.endswith(b'.idx') for k in self._details.keys())
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   645
            # This is not inline, no race expected
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   646
            or b'.d' in self._details
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   647
        ):
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   648
            return super().get_streams(
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   649
                repo=repo,
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   650
                vfs=vfs,
52016
e308439339e2 stream: rename TempCopyManager to VolatileManager
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51882
diff changeset
   651
                volatiles=volatiles,
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   652
                max_changeset=max_changeset,
50706
0452af304808 stream-clone: add a v3 version of the protocol
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50680
diff changeset
   653
                preserve_file_count=preserve_file_count,
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   654
            )
50706
0452af304808 stream-clone: add a v3 version of the protocol
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50680
diff changeset
   655
        elif not preserve_file_count:
0452af304808 stream-clone: add a v3 version of the protocol
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50680
diff changeset
   656
            stream = [
52016
e308439339e2 stream: rename TempCopyManager to VolatileManager
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51882
diff changeset
   657
                f.get_stream(vfs, volatiles)
50706
0452af304808 stream-clone: add a v3 version of the protocol
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50680
diff changeset
   658
                for f in self.files()
0452af304808 stream-clone: add a v3 version of the protocol
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50680
diff changeset
   659
                if not f.unencoded_path.endswith((b'.i', b'.d'))
0452af304808 stream-clone: add a v3 version of the protocol
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50680
diff changeset
   660
            ]
0452af304808 stream-clone: add a v3 version of the protocol
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50680
diff changeset
   661
            rl = self.get_revlog_instance(repo).get_revlog()
0452af304808 stream-clone: add a v3 version of the protocol
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50680
diff changeset
   662
            rl_stream = rl.get_streams(max_changeset)
0452af304808 stream-clone: add a v3 version of the protocol
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50680
diff changeset
   663
            stream.extend(rl_stream)
0452af304808 stream-clone: add a v3 version of the protocol
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50680
diff changeset
   664
            return stream
50672
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   665
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   666
        name_to_size = {}
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   667
        for f in self.files():
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   668
            name_to_size[f.unencoded_path] = f.file_size(None)
50672
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   669
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   670
        stream = [
52016
e308439339e2 stream: rename TempCopyManager to VolatileManager
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51882
diff changeset
   671
            f.get_stream(vfs, volatiles)
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   672
            for f in self.files()
50672
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   673
            if not f.unencoded_path.endswith(b'.i')
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   674
        ]
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   675
50672
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   676
        index_path = self._path_prefix + b'.i'
50641
5460424092e2 stream-clone: smoothly detect and handle a case were a revlog is split
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50640
diff changeset
   677
50672
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   678
        index_file = None
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   679
        try:
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   680
            index_file = vfs(index_path)
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   681
            header = index_file.read(INDEX_HEADER.size)
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   682
            if revlogmod.revlog.is_inline_index(header):
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   683
                size = name_to_size[index_path]
50641
5460424092e2 stream-clone: smoothly detect and handle a case were a revlog is split
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50640
diff changeset
   684
50672
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   685
                # no split underneath, just return the stream
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   686
                def get_stream():
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   687
                    fp = index_file
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   688
                    try:
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   689
                        fp.seek(0)
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   690
                        yield None
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   691
                        if size <= 65536:
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   692
                            yield fp.read(size)
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   693
                        else:
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   694
                            yield from util.filechunkiter(fp, limit=size)
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   695
                    finally:
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   696
                        fp.close()
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   697
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   698
                s = get_stream()
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   699
                next(s)
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   700
                index_file = None
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   701
                stream.append((index_path, s, size))
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   702
            else:
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   703
                rl = self.get_revlog_instance(repo).get_revlog()
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   704
                rl_stream = rl.get_streams(max_changeset, force_inline=True)
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   705
                for name, s, size in rl_stream:
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   706
                    if name_to_size.get(name, 0) != size:
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   707
                        msg = _(b"expected %d bytes but %d provided for %s")
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   708
                        msg %= name_to_size.get(name, 0), size, name
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   709
                        raise error.Abort(msg)
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   710
                stream.extend(rl_stream)
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   711
        finally:
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   712
            if index_file is not None:
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   713
                index_file.close()
3b56395404a1 stream-clone: avoid opening a revlog in case we do not need it
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50671
diff changeset
   714
50640
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   715
        files = self.files()
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   716
        assert len(stream) == len(files), (
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   717
            stream,
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   718
            files,
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   719
            self._path_prefix,
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   720
            self.target_id,
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   721
        )
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   722
        return stream
9caa860dcbec stream-clone: implement decidated `get_streams` method for revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50639
diff changeset
   723
50627
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   724
    def get_revlog_instance(self, repo):
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   725
        """Obtain a revlog instance from this store entry
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   726
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   727
        An instance of the appropriate class is returned.
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   728
        """
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   729
        if self.is_changelog:
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   730
            return changelog.changelog(repo.svfs)
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   731
        elif self.is_manifestlog:
50628
3ea3767c23a4 store: do not drop the final `/` when creating manifestlog instance
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50627
diff changeset
   732
            mandir = self.target_id
50627
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   733
            return manifest.manifestrevlog(
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   734
                repo.nodeconstants, repo.svfs, tree=mandir
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   735
            )
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   736
        else:
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   737
            return filelog.filelog(repo.svfs, self.target_id)
e1ee6910f6bc store: add a `get_revlog_instance` method on revlog entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50514
diff changeset
   738
50473
5a2fb64d38b2 store: use specialized class for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50472
diff changeset
   739
50479
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   740
def _gather_revlog(files_data):
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   741
    """group files per revlog prefix
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   742
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   743
    The returns a two level nested dict. The top level key is the revlog prefix
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   744
    without extension, the second level is all the file "suffix" that were
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   745
    seen for this revlog and arbitrary file data as value.
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   746
    """
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   747
    revlogs = collections.defaultdict(dict)
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   748
    for u, value in files_data:
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   749
        name, ext = _split_revlog_ext(u)
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   750
        revlogs[name][ext] = value
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   751
    return sorted(revlogs.items())
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   752
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   753
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   754
def _split_revlog_ext(filename):
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   755
    """split the revlog file prefix from the variable extension"""
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   756
    if filename.endswith(REVLOG_FILES_LONG_EXT):
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   757
        char = b'-'
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   758
    else:
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   759
        char = b'.'
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   760
    idx = filename.rfind(char)
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   761
    return filename[:idx], filename[idx:]
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   762
5217e36356bb store: add logic to group revlog file together
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50478
diff changeset
   763
50481
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   764
def _ext_key(ext):
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   765
    """a key to order revlog suffix
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   766
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   767
    important to issue .i after other entry."""
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   768
    # the only important part of this order is to keep the `.i` last.
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   769
    if ext.endswith(b'.n'):
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   770
        return (0, ext)
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   771
    elif ext.endswith(b'.nd'):
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   772
        return (10, ext)
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   773
    elif ext.endswith(b'.d'):
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   774
        return (20, ext)
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   775
    elif ext.endswith(b'.i'):
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   776
        return (50, ext)
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   777
    else:
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   778
        return (40, ext)
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   779
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   780
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48941
diff changeset
   781
class basicstore:
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   782
    '''base class for local repository stores'''
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   783
17651
3b49c28658f6 store: rename "openertype" argument to "vfstype"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17649
diff changeset
   784
    def __init__(self, path, vfstype):
17724
bf4b72d8dd4d store: initialize vfs field first to use it for initialization of others
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17722
diff changeset
   785
        vfs = vfstype(path)
bf4b72d8dd4d store: initialize vfs field first to use it for initialization of others
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17722
diff changeset
   786
        self.path = vfs.base
17726
7cb7e17c23b2 store: invoke "os.stat()" for "createmode" initialization via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17725
diff changeset
   787
        self.createmode = _calcmode(vfs)
17652
2c6f7231becc store: rename "op" variables to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17651
diff changeset
   788
        vfs.createmode = self.createmode
17728
004bd533880d store: invoke "os.path.isdir()" via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17727
diff changeset
   789
        self.rawvfs = vfs
31234
9b7a2ef4f27c vfs: use 'vfs' module directly in 'mercurial.store'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31219
diff changeset
   790
        self.vfs = vfsmod.filtervfs(vfs, encodedir)
17653
dacb50696b75 store: initialize "vfs" fields by "vfs" constructors
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17652
diff changeset
   791
        self.opener = self.vfs
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   792
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   793
    def join(self, f):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   794
        return self.path + b'/' + encodedir(f)
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   795
50493
816e8bc6e066 store: split the wrapping of encodedstore between _wrap and datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50492
diff changeset
   796
    def _walk(self, relpath, recurse, undecodable=None):
47877
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   797
        '''yields (revlog_type, unencoded, size)'''
13426
643b8212813e store: remove pointless pathjoiner parameter
Adrian Buehlmann <adrian@cadifra.com>
parents: 13391
diff changeset
   798
        path = self.path
643b8212813e store: remove pointless pathjoiner parameter
Adrian Buehlmann <adrian@cadifra.com>
parents: 13391
diff changeset
   799
        if relpath:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   800
            path += b'/' + relpath
13426
643b8212813e store: remove pointless pathjoiner parameter
Adrian Buehlmann <adrian@cadifra.com>
parents: 13391
diff changeset
   801
        striplen = len(self.path) + 1
6899
56a7a54e074f store: simplify walking
Matt Mackall <mpm@selenic.com>
parents: 6898
diff changeset
   802
        l = []
17728
004bd533880d store: invoke "os.path.isdir()" via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17727
diff changeset
   803
        if self.rawvfs.isdir(path):
6899
56a7a54e074f store: simplify walking
Matt Mackall <mpm@selenic.com>
parents: 6898
diff changeset
   804
            visit = [path]
17747
aad3bce98f76 store: invoke "osutil.listdir()" via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17745
diff changeset
   805
            readdir = self.rawvfs.readdir
6899
56a7a54e074f store: simplify walking
Matt Mackall <mpm@selenic.com>
parents: 6898
diff changeset
   806
            while visit:
56a7a54e074f store: simplify walking
Matt Mackall <mpm@selenic.com>
parents: 6898
diff changeset
   807
                p = visit.pop()
17747
aad3bce98f76 store: invoke "osutil.listdir()" via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17745
diff changeset
   808
                for f, kind, st in readdir(p, stat=True):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   809
                    fp = p + b'/' + f
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   810
                    if is_revlog(f, kind, st):
6900
def492d1b592 store: change handling of decoding errors
Matt Mackall <mpm@selenic.com>
parents: 6899
diff changeset
   811
                        n = util.pconvert(fp[striplen:])
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   812
                        l.append((decodedir(n), st.st_size))
6899
56a7a54e074f store: simplify walking
Matt Mackall <mpm@selenic.com>
parents: 6898
diff changeset
   813
                    elif kind == stat.S_IFDIR and recurse:
56a7a54e074f store: simplify walking
Matt Mackall <mpm@selenic.com>
parents: 6898
diff changeset
   814
                        visit.append(fp)
50478
1c0244a8cdaf store: change `_walk` return to `(filename, (type, size))`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50477
diff changeset
   815
17054
125ff5654b72 store: sort filenames in place
Bryan O'Sullivan <bryano@fb.com>
parents: 16404
diff changeset
   816
        l.sort()
125ff5654b72 store: sort filenames in place
Bryan O'Sullivan <bryano@fb.com>
parents: 16404
diff changeset
   817
        return l
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   818
46607
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents: 46383
diff changeset
   819
    def changelog(self, trypending, concurrencychecker=None):
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents: 46383
diff changeset
   820
        return changelog.changelog(
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents: 46383
diff changeset
   821
            self.vfs,
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents: 46383
diff changeset
   822
            trypending=trypending,
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents: 46383
diff changeset
   823
            concurrencychecker=concurrencychecker,
e9901d01d135 revlog: add a mechanism to verify expected file position before appending
Kyle Lippincott <spectral@google.com>
parents: 46383
diff changeset
   824
        )
42905
3df3b139a43d localrepo: push manifestlog and changelog construction code into store
Augie Fackler <augie@google.com>
parents: 42715
diff changeset
   825
52070
6641a3ae8313 manifest: drop the CamelCase name for `manifest.manifestlog`
Matt Harbison <matt_harbison@yahoo.com>
parents: 52017
diff changeset
   826
    def manifestlog(self, repo, storenarrowmatch) -> manifest.manifestlog:
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46607
diff changeset
   827
        rootstore = manifest.manifestrevlog(repo.nodeconstants, self.vfs)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   828
        return manifest.manifestlog(self.vfs, repo, rootstore, storenarrowmatch)
42905
3df3b139a43d localrepo: push manifestlog and changelog construction code into store
Augie Fackler <augie@google.com>
parents: 42715
diff changeset
   829
50504
862e3a13da44 store: rename `datafiles` to `data_entries`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50498
diff changeset
   830
    def data_entries(
50471
521fec115dad store: use a StoreEntry object instead of tuple for store files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50469
diff changeset
   831
        self, matcher=None, undecodable=None
50473
5a2fb64d38b2 store: use specialized class for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50472
diff changeset
   832
    ) -> Generator[BaseStoreEntry, None, None]:
47877
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   833
        """Like walk, but excluding the changelog and root manifest.
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   834
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   835
        When [undecodable] is None, revlogs names that can't be
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   836
        decoded cause an exception. When it is provided, it should
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   837
        be a list and the filenames that can't be decoded are added
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   838
        to it instead. This is very rarely needed."""
50482
1fc25227b068 store: actually tag tree manifest revlogs as manifest revlogs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50481
diff changeset
   839
        dirs = [
50680
e324329fc97e store: use the revlog type from revlog's constant instead of custom one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50672
diff changeset
   840
            (b'data', KIND_FILELOG, False),
e324329fc97e store: use the revlog type from revlog's constant instead of custom one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50672
diff changeset
   841
            (b'meta', KIND_MANIFESTLOG, True),
50482
1fc25227b068 store: actually tag tree manifest revlogs as manifest revlogs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50481
diff changeset
   842
        ]
50629
309cbd8400ae store: properly compute the targer_id of manifestlog in no-fncache walk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50628
diff changeset
   843
        for base_dir, rl_type, strip_filename in dirs:
50493
816e8bc6e066 store: split the wrapping of encodedstore between _wrap and datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50492
diff changeset
   844
            files = self._walk(base_dir, True, undecodable=undecodable)
50482
1fc25227b068 store: actually tag tree manifest revlogs as manifest revlogs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50481
diff changeset
   845
            for revlog, details in _gather_revlog(files):
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   846
                revlog_target_id = revlog.split(b'/', 1)[1]
50629
309cbd8400ae store: properly compute the targer_id of manifestlog in no-fncache walk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50628
diff changeset
   847
                if strip_filename and b'/' in revlog:
309cbd8400ae store: properly compute the targer_id of manifestlog in no-fncache walk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50628
diff changeset
   848
                    revlog_target_id = revlog_target_id.rsplit(b'/', 1)[0]
309cbd8400ae store: properly compute the targer_id of manifestlog in no-fncache walk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50628
diff changeset
   849
                    revlog_target_id += b'/'
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   850
                yield RevlogStoreEntry(
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   851
                    path_prefix=revlog,
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   852
                    revlog_type=rl_type,
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   853
                    target_id=revlog_target_id,
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   854
                    details=details,
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   855
                )
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   856
50514
0925eaf09c8b store: make `walk` return an entry for obsolescence if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50513
diff changeset
   857
    def top_entries(
0925eaf09c8b store: make `walk` return an entry for obsolescence if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50513
diff changeset
   858
        self, phase=False, obsolescence=False
0925eaf09c8b store: make `walk` return an entry for obsolescence if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50513
diff changeset
   859
    ) -> Generator[BaseStoreEntry, None, None]:
50513
5a62d56e3955 store: yield phases before changelog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50512
diff changeset
   860
        if phase and self.vfs.exists(b'phaseroots'):
5a62d56e3955 store: yield phases before changelog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50512
diff changeset
   861
            yield SimpleStoreEntry(
5a62d56e3955 store: yield phases before changelog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50512
diff changeset
   862
                entry_path=b'phaseroots',
5a62d56e3955 store: yield phases before changelog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50512
diff changeset
   863
                is_volatile=True,
5a62d56e3955 store: yield phases before changelog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50512
diff changeset
   864
            )
5a62d56e3955 store: yield phases before changelog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50512
diff changeset
   865
50514
0925eaf09c8b store: make `walk` return an entry for obsolescence if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50513
diff changeset
   866
        if obsolescence and self.vfs.exists(b'obsstore'):
0925eaf09c8b store: make `walk` return an entry for obsolescence if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50513
diff changeset
   867
            # XXX if we had the file size it could be non-volatile
0925eaf09c8b store: make `walk` return an entry for obsolescence if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50513
diff changeset
   868
            yield SimpleStoreEntry(
0925eaf09c8b store: make `walk` return an entry for obsolescence if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50513
diff changeset
   869
                entry_path=b'obsstore',
0925eaf09c8b store: make `walk` return an entry for obsolescence if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50513
diff changeset
   870
                is_volatile=True,
0925eaf09c8b store: make `walk` return an entry for obsolescence if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50513
diff changeset
   871
            )
0925eaf09c8b store: make `walk` return an entry for obsolescence if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50513
diff changeset
   872
50481
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   873
        files = reversed(self._walk(b'', False))
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   874
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   875
        changelogs = collections.defaultdict(dict)
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   876
        manifestlogs = collections.defaultdict(dict)
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   877
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   878
        for u, s in files:
46895
6085b7f1536d store: also return some information about the type of file `walk` found
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46854
diff changeset
   879
            if u.startswith(b'00changelog'):
50481
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   880
                name, ext = _split_revlog_ext(u)
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   881
                changelogs[name][ext] = s
46895
6085b7f1536d store: also return some information about the type of file `walk` found
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46854
diff changeset
   882
            elif u.startswith(b'00manifest'):
50481
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   883
                name, ext = _split_revlog_ext(u)
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   884
                manifestlogs[name][ext] = s
46895
6085b7f1536d store: also return some information about the type of file `walk` found
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46854
diff changeset
   885
            else:
50473
5a2fb64d38b2 store: use specialized class for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50472
diff changeset
   886
                yield SimpleStoreEntry(
50495
ed8cda1c18e1 store: rename `unencoded_path` to `entry_path` for StoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50494
diff changeset
   887
                    entry_path=u,
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   888
                    is_volatile=False,
50473
5a2fb64d38b2 store: use specialized class for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50472
diff changeset
   889
                    file_size=s,
5a2fb64d38b2 store: use specialized class for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50472
diff changeset
   890
                )
50481
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   891
        # yield manifest before changelog
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   892
        top_rl = [
50680
e324329fc97e store: use the revlog type from revlog's constant instead of custom one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50672
diff changeset
   893
            (manifestlogs, KIND_MANIFESTLOG),
e324329fc97e store: use the revlog type from revlog's constant instead of custom one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50672
diff changeset
   894
            (changelogs, KIND_CHANGELOG),
50481
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   895
        ]
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   896
        assert len(manifestlogs) <= 1
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   897
        assert len(changelogs) <= 1
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   898
        for data, revlog_type in top_rl:
b08243dbc2e3 store: also gather files per revlog in `topfiles`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50480
diff changeset
   899
            for revlog, details in sorted(data.items()):
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   900
                yield RevlogStoreEntry(
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   901
                    path_prefix=revlog,
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   902
                    revlog_type=revlog_type,
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   903
                    target_id=b'',
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
   904
                    details=details,
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
   905
                )
19177
1e104aaa4c44 store: move top file walk to a separate function
Durham Goode <durham@fb.com>
parents: 18435
diff changeset
   906
50512
a32d739b0ffb store: make `walk` return an entry for phase if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50505
diff changeset
   907
    def walk(
50514
0925eaf09c8b store: make `walk` return an entry for obsolescence if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50513
diff changeset
   908
        self, matcher=None, phase=False, obsolescence=False
50512
a32d739b0ffb store: make `walk` return an entry for phase if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50505
diff changeset
   909
    ) -> Generator[BaseStoreEntry, None, None]:
50451
584ff1f97201 comments: fix spelling
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50319
diff changeset
   910
        """return files related to data storage (ie: revlogs)
46853
eed3e2b79b48 store: document the `walk` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46819
diff changeset
   911
50512
a32d739b0ffb store: make `walk` return an entry for phase if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50505
diff changeset
   912
        yields instance from BaseStoreEntry subclasses
40340
2d45b549392f store: pass matcher to store.datafiles()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39698
diff changeset
   913
2d45b549392f store: pass matcher to store.datafiles()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39698
diff changeset
   914
        if a matcher is passed, storage files of only those tracked paths
2d45b549392f store: pass matcher to store.datafiles()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39698
diff changeset
   915
        are passed with matches the matcher
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
   916
        """
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   917
        # yield data files first
50504
862e3a13da44 store: rename `datafiles` to `data_entries`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50498
diff changeset
   918
        for x in self.data_entries(matcher):
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   919
            yield x
50514
0925eaf09c8b store: make `walk` return an entry for obsolescence if requested so
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50513
diff changeset
   920
        for x in self.top_entries(phase=phase, obsolescence=obsolescence):
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   921
            yield x
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   922
6903
0642d9d7ec80 clone: get a list of files to clone from store
Matt Mackall <mpm@selenic.com>
parents: 6902
diff changeset
   923
    def copylist(self):
45483
d252f51ab032 share: introduce config option to store requires in .hg/store
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45351
diff changeset
   924
        return _data
6903
0642d9d7ec80 clone: get a list of files to clone from store
Matt Mackall <mpm@selenic.com>
parents: 6902
diff changeset
   925
20883
cd443c7589cc fncache: move fncache writing to be in a transaction
Durham Goode <durham@fb.com>
parents: 20879
diff changeset
   926
    def write(self, tr):
13391
d00bbff8600e fncachestore: defer updating the fncache file to a single file open
Adrian Buehlmann <adrian@cadifra.com>
parents: 13169
diff changeset
   927
        pass
d00bbff8600e fncachestore: defer updating the fncache file to a single file open
Adrian Buehlmann <adrian@cadifra.com>
parents: 13169
diff changeset
   928
20884
2efdd186925d caches: invalidate store caches when lock is taken
Durham Goode <durham@fb.com>
parents: 20883
diff changeset
   929
    def invalidatecaches(self):
2efdd186925d caches: invalidate store caches when lock is taken
Durham Goode <durham@fb.com>
parents: 20883
diff changeset
   930
        pass
2efdd186925d caches: invalidate store caches when lock is taken
Durham Goode <durham@fb.com>
parents: 20883
diff changeset
   931
20885
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
   932
    def markremoved(self, fn):
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
   933
        pass
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
   934
17744
09d5b2055295 store: add a contains method to basicstore
smuralid
parents: 17738
diff changeset
   935
    def __contains__(self, path):
09d5b2055295 store: add a contains method to basicstore
smuralid
parents: 17738
diff changeset
   936
        '''Checks if the store contains path'''
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   937
        path = b"/".join((b"data", path))
17744
09d5b2055295 store: add a contains method to basicstore
smuralid
parents: 17738
diff changeset
   938
        # file?
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   939
        if self.vfs.exists(path + b".i"):
17744
09d5b2055295 store: add a contains method to basicstore
smuralid
parents: 17738
diff changeset
   940
            return True
09d5b2055295 store: add a contains method to basicstore
smuralid
parents: 17738
diff changeset
   941
        # dir?
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   942
        if not path.endswith(b"/"):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   943
            path = path + b"/"
19903
ca875b271ac3 store: use "vfs.exists()" instead of "os.path.exists()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19177
diff changeset
   944
        return self.vfs.exists(path)
17744
09d5b2055295 store: add a contains method to basicstore
smuralid
parents: 17738
diff changeset
   945
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   946
6898
69aeaaaf6e07 store: simplify class hierarchy
Matt Mackall <mpm@selenic.com>
parents: 6897
diff changeset
   947
class encodedstore(basicstore):
17651
3b49c28658f6 store: rename "openertype" argument to "vfstype"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17649
diff changeset
   948
    def __init__(self, path, vfstype):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   949
        vfs = vfstype(path + b'/store')
17724
bf4b72d8dd4d store: initialize vfs field first to use it for initialization of others
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17722
diff changeset
   950
        self.path = vfs.base
17726
7cb7e17c23b2 store: invoke "os.stat()" for "createmode" initialization via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17725
diff changeset
   951
        self.createmode = _calcmode(vfs)
17652
2c6f7231becc store: rename "op" variables to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17651
diff changeset
   952
        vfs.createmode = self.createmode
17728
004bd533880d store: invoke "os.path.isdir()" via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17727
diff changeset
   953
        self.rawvfs = vfs
31234
9b7a2ef4f27c vfs: use 'vfs' module directly in 'mercurial.store'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31219
diff changeset
   954
        self.vfs = vfsmod.filtervfs(vfs, encodefilename)
17653
dacb50696b75 store: initialize "vfs" fields by "vfs" constructors
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17652
diff changeset
   955
        self.opener = self.vfs
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   956
50493
816e8bc6e066 store: split the wrapping of encodedstore between _wrap and datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50492
diff changeset
   957
    def _walk(self, relpath, recurse, undecodable=None):
816e8bc6e066 store: split the wrapping of encodedstore between _wrap and datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50492
diff changeset
   958
        old = super()._walk(relpath, recurse)
816e8bc6e066 store: split the wrapping of encodedstore between _wrap and datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50492
diff changeset
   959
        new = []
816e8bc6e066 store: split the wrapping of encodedstore between _wrap and datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50492
diff changeset
   960
        for f1, value in old:
6892
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6890
diff changeset
   961
            try:
47877
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   962
                f2 = decodefilename(f1)
6892
dab95717058d verify: check repo.store
Adrian Buehlmann <adrian@cadifra.com>
parents: 6890
diff changeset
   963
            except KeyError:
47877
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   964
                if undecodable is None:
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   965
                    msg = _(b'undecodable revlog name %s') % f1
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   966
                    raise error.StorageError(msg)
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   967
                else:
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   968
                    undecodable.append(f1)
2174f54aab18 store: return just one filename in walk functions
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47785
diff changeset
   969
                    continue
50493
816e8bc6e066 store: split the wrapping of encodedstore between _wrap and datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50492
diff changeset
   970
            new.append((f2, value))
816e8bc6e066 store: split the wrapping of encodedstore between _wrap and datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50492
diff changeset
   971
        return new
816e8bc6e066 store: split the wrapping of encodedstore between _wrap and datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50492
diff changeset
   972
50504
862e3a13da44 store: rename `datafiles` to `data_entries`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50498
diff changeset
   973
    def data_entries(
50493
816e8bc6e066 store: split the wrapping of encodedstore between _wrap and datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50492
diff changeset
   974
        self, matcher=None, undecodable=None
816e8bc6e066 store: split the wrapping of encodedstore between _wrap and datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50492
diff changeset
   975
    ) -> Generator[BaseStoreEntry, None, None]:
50504
862e3a13da44 store: rename `datafiles` to `data_entries`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50498
diff changeset
   976
        entries = super(encodedstore, self).data_entries(
862e3a13da44 store: rename `datafiles` to `data_entries`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50498
diff changeset
   977
            undecodable=undecodable
862e3a13da44 store: rename `datafiles` to `data_entries`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50498
diff changeset
   978
        )
50493
816e8bc6e066 store: split the wrapping of encodedstore between _wrap and datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50492
diff changeset
   979
        for entry in entries:
50494
b4953fad744e store: do the revlog matching on entry directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50493
diff changeset
   980
            if _match_tracked_entry(entry, matcher):
50493
816e8bc6e066 store: split the wrapping of encodedstore between _wrap and datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50492
diff changeset
   981
                yield entry
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   982
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   983
    def join(self, f):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   984
        return self.path + b'/' + encodefilename(f)
6840
80e51429cb9a introduce store classes
Adrian Buehlmann <adrian@cadifra.com>
parents: 6839
diff changeset
   985
6903
0642d9d7ec80 clone: get a list of files to clone from store
Matt Mackall <mpm@selenic.com>
parents: 6902
diff changeset
   986
    def copylist(self):
45351
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
   987
        return [b'requires', b'00changelog.i'] + [b'store/' + f for f in _data]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
   988
6903
0642d9d7ec80 clone: get a list of files to clone from store
Matt Mackall <mpm@selenic.com>
parents: 6902
diff changeset
   989
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48941
diff changeset
   990
class fncache:
8531
810387f59696 filelog encoding: move the encoding/decoding into store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8530
diff changeset
   991
    # the filename used to be partially encoded
810387f59696 filelog encoding: move the encoding/decoding into store
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8530
diff changeset
   992
    # hence the encodedir/decodedir dance
17722
3b976051034d store: rename field name from "opener" to "vfs" in internal classes for fncache
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17721
diff changeset
   993
    def __init__(self, vfs):
3b976051034d store: rename field name from "opener" to "vfs" in internal classes for fncache
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17721
diff changeset
   994
        self.vfs = vfs
50315
cf6e1d535602 fncache: make it possible to ignore some file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   995
        self._ignores = set()
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
   996
        self.entries = None
13391
d00bbff8600e fncachestore: defer updating the fncache file to a single file open
Adrian Buehlmann <adrian@cadifra.com>
parents: 13169
diff changeset
   997
        self._dirty = False
40736
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
   998
        # set of new additions to fncache
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
   999
        self.addls = set()
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
  1000
52173
ba9df4e6abb8 fncache: refactor load check into a property
Raphaël Gomès <rgomes@octobus.net>
parents: 52070
diff changeset
  1001
    @property
ba9df4e6abb8 fncache: refactor load check into a property
Raphaël Gomès <rgomes@octobus.net>
parents: 52070
diff changeset
  1002
    def is_loaded(self):
ba9df4e6abb8 fncache: refactor load check into a property
Raphaël Gomès <rgomes@octobus.net>
parents: 52070
diff changeset
  1003
        return self.entries is not None
ba9df4e6abb8 fncache: refactor load check into a property
Raphaël Gomès <rgomes@octobus.net>
parents: 52070
diff changeset
  1004
42715
f59f8a5e9096 fncache: make debugrebuildfncache not fail on broken fncache
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 42341
diff changeset
  1005
    def ensureloaded(self, warn=None):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
  1006
        """read the fncache file if not already read.
42715
f59f8a5e9096 fncache: make debugrebuildfncache not fail on broken fncache
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 42341
diff changeset
  1007
f59f8a5e9096 fncache: make debugrebuildfncache not fail on broken fncache
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 42341
diff changeset
  1008
        If the file on disk is corrupted, raise. If warn is provided,
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45483
diff changeset
  1009
        warn and keep going instead."""
52173
ba9df4e6abb8 fncache: refactor load check into a property
Raphaël Gomès <rgomes@octobus.net>
parents: 52070
diff changeset
  1010
        if not self.is_loaded:
42715
f59f8a5e9096 fncache: make debugrebuildfncache not fail on broken fncache
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 42341
diff changeset
  1011
            self._load(warn)
f59f8a5e9096 fncache: make debugrebuildfncache not fail on broken fncache
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 42341
diff changeset
  1012
f59f8a5e9096 fncache: make debugrebuildfncache not fail on broken fncache
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 42341
diff changeset
  1013
    def _load(self, warn=None):
8530
03196ac9a8b9 store: refactor the fncache handling
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8480
diff changeset
  1014
        '''fill the entries from the fncache file'''
13391
d00bbff8600e fncachestore: defer updating the fncache file to a single file open
Adrian Buehlmann <adrian@cadifra.com>
parents: 13169
diff changeset
  1015
        self._dirty = False
8530
03196ac9a8b9 store: refactor the fncache handling
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8480
diff changeset
  1016
        try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1017
            fp = self.vfs(b'fncache', mode=b'rb')
8530
03196ac9a8b9 store: refactor the fncache handling
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8480
diff changeset
  1018
        except IOError:
03196ac9a8b9 store: refactor the fncache handling
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8480
diff changeset
  1019
            # skip nonexistent file
16404
9fca5b056c0a store: speed up read and write of large fncache files
Bryan O'Sullivan <bryano@fb.com>
parents: 15742
diff changeset
  1020
            self.entries = set()
8530
03196ac9a8b9 store: refactor the fncache handling
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8480
diff changeset
  1021
            return
41978
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
  1022
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
  1023
        self.entries = set()
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
  1024
        chunk = b''
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
  1025
        for c in iter(functools.partial(fp.read, fncache_chunksize), b''):
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
  1026
            chunk += c
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
  1027
            try:
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
  1028
                p = chunk.rindex(b'\n')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
  1029
                self.entries.update(decodedir(chunk[: p + 1]).splitlines())
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
  1030
                chunk = chunk[p + 1 :]
41978
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
  1031
            except ValueError:
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
  1032
                # substring '\n' not found, maybe the entry is bigger than the
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
  1033
                # chunksize, so let's keep iterating
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
  1034
                pass
a56487081109 store: don't read the whole fncache in memory
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41973
diff changeset
  1035
41981
a920a9e1795a store: error out if fncache does not ends with a newline
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41978
diff changeset
  1036
        if chunk:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1037
            msg = _(b"fncache does not ends with a newline")
42715
f59f8a5e9096 fncache: make debugrebuildfncache not fail on broken fncache
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 42341
diff changeset
  1038
            if warn:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1039
                warn(msg + b'\n')
42715
f59f8a5e9096 fncache: make debugrebuildfncache not fail on broken fncache
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 42341
diff changeset
  1040
            else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
  1041
                raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
  1042
                    msg,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
  1043
                    hint=_(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1044
                        b"use 'hg debugrebuildfncache' to "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1045
                        b"rebuild the fncache"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
  1046
                    ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
  1047
                )
42715
f59f8a5e9096 fncache: make debugrebuildfncache not fail on broken fncache
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 42341
diff changeset
  1048
        self._checkentries(fp, warn)
41973
d7ef84e595f8 store: move logic to check for invalid entry in fncache to own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41093
diff changeset
  1049
        fp.close()
d7ef84e595f8 store: move logic to check for invalid entry in fncache to own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41093
diff changeset
  1050
42715
f59f8a5e9096 fncache: make debugrebuildfncache not fail on broken fncache
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 42341
diff changeset
  1051
    def _checkentries(self, fp, warn):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46990
diff changeset
  1052
        """make sure there is no empty string in entries"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1053
        if b'' in self.entries:
16404
9fca5b056c0a store: speed up read and write of large fncache files
Bryan O'Sullivan <bryano@fb.com>
parents: 15742
diff changeset
  1054
            fp.seek(0)
48941
fd5b8e696b75 py3: stop using util.iterfile()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
  1055
            for n, line in enumerate(fp):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1056
                if not line.rstrip(b'\n'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1057
                    t = _(b'invalid entry in fncache, line %d') % (n + 1)
42715
f59f8a5e9096 fncache: make debugrebuildfncache not fail on broken fncache
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 42341
diff changeset
  1058
                    if warn:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1059
                        warn(t + b'\n')
42715
f59f8a5e9096 fncache: make debugrebuildfncache not fail on broken fncache
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 42341
diff changeset
  1060
                    else:
f59f8a5e9096 fncache: make debugrebuildfncache not fail on broken fncache
Valentin Gatien-Baron <vgatien-baron@janestreet.com>
parents: 42341
diff changeset
  1061
                        raise error.Abort(t)
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
  1062
20883
cd443c7589cc fncache: move fncache writing to be in a transaction
Durham Goode <durham@fb.com>
parents: 20879
diff changeset
  1063
    def write(self, tr):
16404
9fca5b056c0a store: speed up read and write of large fncache files
Bryan O'Sullivan <bryano@fb.com>
parents: 15742
diff changeset
  1064
        if self._dirty:
52173
ba9df4e6abb8 fncache: refactor load check into a property
Raphaël Gomès <rgomes@octobus.net>
parents: 52070
diff changeset
  1065
            assert self.is_loaded
40748
df8ed31a8ad8 store: write fncache only once if there are both adds and removes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40736
diff changeset
  1066
            self.entries = self.entries | self.addls
df8ed31a8ad8 store: write fncache only once if there are both adds and removes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40736
diff changeset
  1067
            self.addls = set()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1068
            tr.addbackup(b'fncache')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1069
            fp = self.vfs(b'fncache', mode=b'wb', atomictemp=True)
20879
cd03854a2e06 fncache: remove the rewriting logic
Durham Goode <durham@fb.com>
parents: 19903
diff changeset
  1070
            if self.entries:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1071
                fp.write(encodedir(b'\n'.join(self.entries) + b'\n'))
20879
cd03854a2e06 fncache: remove the rewriting logic
Durham Goode <durham@fb.com>
parents: 19903
diff changeset
  1072
            fp.close()
cd03854a2e06 fncache: remove the rewriting logic
Durham Goode <durham@fb.com>
parents: 19903
diff changeset
  1073
            self._dirty = False
40736
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1074
        if self.addls:
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1075
            # if we have just new entries, let's append them to the fncache
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1076
            tr.addbackup(b'fncache')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1077
            fp = self.vfs(b'fncache', mode=b'ab', atomictemp=True)
40736
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1078
            if self.addls:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1079
                fp.write(encodedir(b'\n'.join(self.addls) + b'\n'))
40736
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1080
            fp.close()
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1081
            self.entries = None
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1082
            self.addls = set()
8530
03196ac9a8b9 store: refactor the fncache handling
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8480
diff changeset
  1083
50315
cf6e1d535602 fncache: make it possible to ignore some file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
  1084
    def addignore(self, fn):
cf6e1d535602 fncache: make it possible to ignore some file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
  1085
        self._ignores.add(fn)
cf6e1d535602 fncache: make it possible to ignore some file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
  1086
8530
03196ac9a8b9 store: refactor the fncache handling
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8480
diff changeset
  1087
    def add(self, fn):
50315
cf6e1d535602 fncache: make it possible to ignore some file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
  1088
        if fn in self._ignores:
cf6e1d535602 fncache: make it possible to ignore some file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
  1089
            return
52173
ba9df4e6abb8 fncache: refactor load check into a property
Raphaël Gomès <rgomes@octobus.net>
parents: 52070
diff changeset
  1090
        if not self.is_loaded:
8530
03196ac9a8b9 store: refactor the fncache handling
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8480
diff changeset
  1091
            self._load()
10577
d5bd1beff794 store: only add new entries to the fncache file
Adrian Buehlmann <adrian@cadifra.com>
parents: 10339
diff changeset
  1092
        if fn not in self.entries:
40736
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1093
            self.addls.add(fn)
8530
03196ac9a8b9 store: refactor the fncache handling
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8480
diff changeset
  1094
20885
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
  1095
    def remove(self, fn):
52173
ba9df4e6abb8 fncache: refactor load check into a property
Raphaël Gomès <rgomes@octobus.net>
parents: 52070
diff changeset
  1096
        if not self.is_loaded:
20885
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
  1097
            self._load()
40736
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1098
        if fn in self.addls:
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1099
            self.addls.remove(fn)
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1100
            return
20885
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
  1101
        try:
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
  1102
            self.entries.remove(fn)
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
  1103
            self._dirty = True
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
  1104
        except KeyError:
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
  1105
            pass
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
  1106
17782
8095306c1fb2 store: move __contains__() implementation from class fncache into fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17747
diff changeset
  1107
    def __contains__(self, fn):
40736
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1108
        if fn in self.addls:
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1109
            return True
52173
ba9df4e6abb8 fncache: refactor load check into a property
Raphaël Gomès <rgomes@octobus.net>
parents: 52070
diff changeset
  1110
        if not self.is_loaded:
8530
03196ac9a8b9 store: refactor the fncache handling
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8480
diff changeset
  1111
            self._load()
17782
8095306c1fb2 store: move __contains__() implementation from class fncache into fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17747
diff changeset
  1112
        return fn in self.entries
8530
03196ac9a8b9 store: refactor the fncache handling
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8480
diff changeset
  1113
03196ac9a8b9 store: refactor the fncache handling
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8480
diff changeset
  1114
    def __iter__(self):
52173
ba9df4e6abb8 fncache: refactor load check into a property
Raphaël Gomès <rgomes@octobus.net>
parents: 52070
diff changeset
  1115
        if not self.is_loaded:
8530
03196ac9a8b9 store: refactor the fncache handling
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8480
diff changeset
  1116
            self._load()
40736
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1117
        return iter(self.entries | self.addls)
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
  1118
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
  1119
41093
6498f0e03526 vfs: fix proxyvfs inheritance
Boris Feld <boris.feld@octobus.net>
parents: 40748
diff changeset
  1120
class _fncachevfs(vfsmod.proxyvfs):
17721
cf236e3501c3 store: rename argument name from "op"(ener) to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17693
diff changeset
  1121
    def __init__(self, vfs, fnc, encode):
33412
a42369e04aee vfs: rename auditvfs to proxyvfs
Yuya Nishihara <yuya@tcha.org>
parents: 32372
diff changeset
  1122
        vfsmod.proxyvfs.__init__(self, vfs)
52174
9fbdf355c916 fncachestore: add typing information
Raphaël Gomès <rgomes@octobus.net>
parents: 52173
diff changeset
  1123
        self.fncache: fncache = fnc
14194
3a90fb3addc1 store: break up reference cycle introduced in 9cbff8a39a2a
Adrian Buehlmann <adrian@cadifra.com>
parents: 14166
diff changeset
  1124
        self.encode = encode
52175
bd43465af568 fncache: add attribute to check whether we're using dotencode
Raphaël Gomès <rgomes@octobus.net>
parents: 52174
diff changeset
  1125
        self.uses_dotencode = encode is _pathencode
14194
3a90fb3addc1 store: break up reference cycle introduced in 9cbff8a39a2a
Adrian Buehlmann <adrian@cadifra.com>
parents: 14166
diff changeset
  1126
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1127
    def __call__(self, path, mode=b'r', *args, **kw):
38661
8ac0c9cd4c48 fncache: avoid loading the filename cache when not actually modifying it
Martijn Pieters <mj@zopatista.com>
parents: 37409
diff changeset
  1128
        encoded = self.encode(path)
50467
0dbab42adca5 store: do not record file that are not part of a revlog in fncache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50451
diff changeset
  1129
        if (
0dbab42adca5 store: do not record file that are not part of a revlog in fncache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50451
diff changeset
  1130
            mode not in (b'r', b'rb')
0dbab42adca5 store: do not record file that are not part of a revlog in fncache
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50451
diff changeset
  1131
            and (path.startswith(b'data/') or path.startswith(b'meta/'))
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
  1132
            and is_revlog_file(path)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
  1133
        ):
38661
8ac0c9cd4c48 fncache: avoid loading the filename cache when not actually modifying it
Martijn Pieters <mj@zopatista.com>
parents: 37409
diff changeset
  1134
            # do not trigger a fncache load when adding a file that already is
8ac0c9cd4c48 fncache: avoid loading the filename cache when not actually modifying it
Martijn Pieters <mj@zopatista.com>
parents: 37409
diff changeset
  1135
            # known to exist.
52173
ba9df4e6abb8 fncache: refactor load check into a property
Raphaël Gomès <rgomes@octobus.net>
parents: 52070
diff changeset
  1136
            notload = not self.fncache.is_loaded and (
50812
30381812708d fncache: fix a bug that corrupts the fncache after transaction rollback
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50706
diff changeset
  1137
                # if the file has size zero, it should be considered as missing.
30381812708d fncache: fix a bug that corrupts the fncache after transaction rollback
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50706
diff changeset
  1138
                # Such zero-size files are the result of truncation when a
30381812708d fncache: fix a bug that corrupts the fncache after transaction rollback
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50706
diff changeset
  1139
                # transaction is aborted.
30381812708d fncache: fix a bug that corrupts the fncache after transaction rollback
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50706
diff changeset
  1140
                self.vfs.exists(encoded)
30381812708d fncache: fix a bug that corrupts the fncache after transaction rollback
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50706
diff changeset
  1141
                and self.vfs.stat(encoded).st_size
30381812708d fncache: fix a bug that corrupts the fncache after transaction rollback
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50706
diff changeset
  1142
            )
38661
8ac0c9cd4c48 fncache: avoid loading the filename cache when not actually modifying it
Martijn Pieters <mj@zopatista.com>
parents: 37409
diff changeset
  1143
            if not notload:
8ac0c9cd4c48 fncache: avoid loading the filename cache when not actually modifying it
Martijn Pieters <mj@zopatista.com>
parents: 37409
diff changeset
  1144
                self.fncache.add(path)
8ac0c9cd4c48 fncache: avoid loading the filename cache when not actually modifying it
Martijn Pieters <mj@zopatista.com>
parents: 37409
diff changeset
  1145
        return self.vfs(encoded, mode, *args, **kw)
14194
3a90fb3addc1 store: break up reference cycle introduced in 9cbff8a39a2a
Adrian Buehlmann <adrian@cadifra.com>
parents: 14166
diff changeset
  1146
51882
2391a5fa111e store: fix a signature mismatch for a vfs subclass
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1147
    def join(self, path: Optional[bytes], *insidef: bytes) -> bytes:
2391a5fa111e store: fix a signature mismatch for a vfs subclass
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1148
        insidef = (self.encode(f) for f in insidef)
2391a5fa111e store: fix a signature mismatch for a vfs subclass
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1149
17725
ffd589d4b785 vfs: define "join()" in each classes derived from "abstractvfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17724
diff changeset
  1150
        if path:
51882
2391a5fa111e store: fix a signature mismatch for a vfs subclass
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1151
            return self.vfs.join(self.encode(path), *insidef)
17725
ffd589d4b785 vfs: define "join()" in each classes derived from "abstractvfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17724
diff changeset
  1152
        else:
51882
2391a5fa111e store: fix a signature mismatch for a vfs subclass
Matt Harbison <matt_harbison@yahoo.com>
parents: 51863
diff changeset
  1153
            return self.vfs.join(path, *insidef)
17725
ffd589d4b785 vfs: define "join()" in each classes derived from "abstractvfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17724
diff changeset
  1154
47443
9ab54aa56982 vfs: add a `register_file` method on the vfs class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47389
diff changeset
  1155
    def register_file(self, path):
9ab54aa56982 vfs: add a `register_file` method on the vfs class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47389
diff changeset
  1156
        """generic hook point to lets fncache steer its stew"""
9ab54aa56982 vfs: add a `register_file` method on the vfs class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47389
diff changeset
  1157
        if path.startswith(b'data/') or path.startswith(b'meta/'):
9ab54aa56982 vfs: add a `register_file` method on the vfs class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47389
diff changeset
  1158
            self.fncache.add(path)
9ab54aa56982 vfs: add a `register_file` method on the vfs class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47389
diff changeset
  1159
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
  1160
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
  1161
class fncachestore(basicstore):
17651
3b49c28658f6 store: rename "openertype" argument to "vfstype"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17649
diff changeset
  1162
    def __init__(self, path, vfstype, dotencode):
17591
9a5c2ecd1158 store: move encode lambda logic into fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17590
diff changeset
  1163
        if dotencode:
18435
8c019d2fd7c0 store: switch to C-based hashed path encoding
Bryan O'Sullivan <bryano@fb.com>
parents: 18430
diff changeset
  1164
            encode = _pathencode
17591
9a5c2ecd1158 store: move encode lambda logic into fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17590
diff changeset
  1165
        else:
9a5c2ecd1158 store: move encode lambda logic into fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17590
diff changeset
  1166
            encode = _plainhybridencode
12687
34d8247a4595 store: encode first period or space in filenames (issue1713)
Adrian Buehlmann <adrian@cadifra.com>
parents: 12171
diff changeset
  1167
        self.encode = encode
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1168
        vfs = vfstype(path + b'/store')
17724
bf4b72d8dd4d store: initialize vfs field first to use it for initialization of others
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17722
diff changeset
  1169
        self.path = vfs.base
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1170
        self.pathsep = self.path + b'/'
17726
7cb7e17c23b2 store: invoke "os.stat()" for "createmode" initialization via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17725
diff changeset
  1171
        self.createmode = _calcmode(vfs)
17652
2c6f7231becc store: rename "op" variables to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17651
diff changeset
  1172
        vfs.createmode = self.createmode
17727
6492b39a44d5 store: replace invocation of "getsize()" by "vfs.stat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17726
diff changeset
  1173
        self.rawvfs = vfs
17652
2c6f7231becc store: rename "op" variables to "vfs"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17651
diff changeset
  1174
        fnc = fncache(vfs)
9133
996c1cd8f530 store: eliminate reference cycle in fncachestore
Simon Heimberg <simohe@besonet.ch>
parents: 8778
diff changeset
  1175
        self.fncache = fnc
17653
dacb50696b75 store: initialize "vfs" fields by "vfs" constructors
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17652
diff changeset
  1176
        self.vfs = _fncachevfs(vfs, fnc, encode)
dacb50696b75 store: initialize "vfs" fields by "vfs" constructors
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17652
diff changeset
  1177
        self.opener = self.vfs
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
  1178
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
  1179
    def join(self, f):
17562
b42b0729744d store: reduce string concatenation when joining
Bryan O'Sullivan <bryano@fb.com>
parents: 17555
diff changeset
  1180
        return self.pathsep + self.encode(f)
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
  1181
17731
c85dbae29684 store: restore getsize method
Matt Mackall <mpm@selenic.com>
parents: 17728
diff changeset
  1182
    def getsize(self, path):
c85dbae29684 store: restore getsize method
Matt Mackall <mpm@selenic.com>
parents: 17728
diff changeset
  1183
        return self.rawvfs.stat(path).st_size
c85dbae29684 store: restore getsize method
Matt Mackall <mpm@selenic.com>
parents: 17728
diff changeset
  1184
50504
862e3a13da44 store: rename `datafiles` to `data_entries`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50498
diff changeset
  1185
    def data_entries(
50471
521fec115dad store: use a StoreEntry object instead of tuple for store files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50469
diff changeset
  1186
        self, matcher=None, undecodable=None
50473
5a2fb64d38b2 store: use specialized class for store entries
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50472
diff changeset
  1187
    ) -> Generator[BaseStoreEntry, None, None]:
50480
d4f54aded22e store: also group files by revlog in fncache version of datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50479
diff changeset
  1188
        # Note: all files in fncache should be revlog related, However the
d4f54aded22e store: also group files by revlog in fncache version of datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50479
diff changeset
  1189
        # fncache might contains such file added by previous version of
d4f54aded22e store: also group files by revlog in fncache version of datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50479
diff changeset
  1190
        # Mercurial.
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
  1191
        files = ((f, None) for f in self.fncache if is_revlog_file(f))
50480
d4f54aded22e store: also group files by revlog in fncache version of datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50479
diff changeset
  1192
        by_revlog = _gather_revlog(files)
d4f54aded22e store: also group files by revlog in fncache version of datafiles
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50479
diff changeset
  1193
        for revlog, details in by_revlog:
50482
1fc25227b068 store: actually tag tree manifest revlogs as manifest revlogs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50481
diff changeset
  1194
            if revlog.startswith(b'data/'):
50680
e324329fc97e store: use the revlog type from revlog's constant instead of custom one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50672
diff changeset
  1195
                rl_type = KIND_FILELOG
50483
60e613f6a229 store: add a `target_id` attribute on RevlogStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50482
diff changeset
  1196
                revlog_target_id = revlog.split(b'/', 1)[1]
50482
1fc25227b068 store: actually tag tree manifest revlogs as manifest revlogs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50481
diff changeset
  1197
            elif revlog.startswith(b'meta/'):
50680
e324329fc97e store: use the revlog type from revlog's constant instead of custom one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50672
diff changeset
  1198
                rl_type = KIND_MANIFESTLOG
50483
60e613f6a229 store: add a `target_id` attribute on RevlogStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50482
diff changeset
  1199
                # drop the initial directory and the `00manifest` file part
60e613f6a229 store: add a `target_id` attribute on RevlogStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50482
diff changeset
  1200
                tmp = revlog.split(b'/', 1)[1]
60e613f6a229 store: add a `target_id` attribute on RevlogStoreEntry
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50482
diff changeset
  1201
                revlog_target_id = tmp.rsplit(b'/', 1)[0] + b'/'
50482
1fc25227b068 store: actually tag tree manifest revlogs as manifest revlogs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50481
diff changeset
  1202
            else:
1fc25227b068 store: actually tag tree manifest revlogs as manifest revlogs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50481
diff changeset
  1203
                # unreachable
1fc25227b068 store: actually tag tree manifest revlogs as manifest revlogs
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50481
diff changeset
  1204
                assert False, revlog
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
  1205
            entry = RevlogStoreEntry(
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
  1206
                path_prefix=revlog,
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
  1207
                revlog_type=rl_type,
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
  1208
                target_id=revlog_target_id,
50671
e06d1a779eb6 store: stop relying on a `revlog_type` property
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50670
diff changeset
  1209
                details=details,
50496
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
  1210
            )
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
  1211
            if _match_tracked_entry(entry, matcher):
e50d1fe7ebb4 store: issue a single entry for each revlog
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50495
diff changeset
  1212
                yield entry
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
  1213
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
  1214
    def copylist(self):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
  1215
        d = (
45351
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
  1216
            b'bookmarks',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
  1217
            b'narrowspec',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
  1218
            b'data',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
  1219
            b'meta',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
  1220
            b'dh',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
  1221
            b'fncache',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
  1222
            b'phaseroots',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
  1223
            b'obsstore',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
  1224
            b'00manifest.d',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
  1225
            b'00manifest.i',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
  1226
            b'00changelog.d',
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
  1227
            b'00changelog.i',
45483
d252f51ab032 share: introduce config option to store requires in .hg/store
Pulkit Goyal <7895pulkit@gmail.com>
parents: 45351
diff changeset
  1228
            b'requires',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42905
diff changeset
  1229
        )
45351
909dafff6a78 store: refactor space delimited list to proper data structure
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44452
diff changeset
  1230
        return [b'requires', b'00changelog.i'] + [b'store/' + f for f in d]
7229
7946503ec76e introduce fncache repository layout
Adrian Buehlmann <adrian@cadifra.com>
parents: 6989
diff changeset
  1231
20883
cd443c7589cc fncache: move fncache writing to be in a transaction
Durham Goode <durham@fb.com>
parents: 20879
diff changeset
  1232
    def write(self, tr):
cd443c7589cc fncache: move fncache writing to be in a transaction
Durham Goode <durham@fb.com>
parents: 20879
diff changeset
  1233
        self.fncache.write(tr)
13391
d00bbff8600e fncachestore: defer updating the fncache file to a single file open
Adrian Buehlmann <adrian@cadifra.com>
parents: 13169
diff changeset
  1234
20884
2efdd186925d caches: invalidate store caches when lock is taken
Durham Goode <durham@fb.com>
parents: 20883
diff changeset
  1235
    def invalidatecaches(self):
2efdd186925d caches: invalidate store caches when lock is taken
Durham Goode <durham@fb.com>
parents: 20883
diff changeset
  1236
        self.fncache.entries = None
40736
0728d87a8631 store: append to fncache if there are only new files to write
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40624
diff changeset
  1237
        self.fncache.addls = set()
20884
2efdd186925d caches: invalidate store caches when lock is taken
Durham Goode <durham@fb.com>
parents: 20883
diff changeset
  1238
20885
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
  1239
    def markremoved(self, fn):
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
  1240
        self.fncache.remove(fn)
f49d60fa40a5 fncache: clean up fncache during strips
Durham Goode <durham@fb.com>
parents: 20884
diff changeset
  1241
17783
df55ce6854c3 store: add new _exists helper function on fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17782
diff changeset
  1242
    def _exists(self, f):
df55ce6854c3 store: add new _exists helper function on fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17782
diff changeset
  1243
        ef = self.encode(f)
df55ce6854c3 store: add new _exists helper function on fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17782
diff changeset
  1244
        try:
df55ce6854c3 store: add new _exists helper function on fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17782
diff changeset
  1245
            self.getsize(ef)
df55ce6854c3 store: add new _exists helper function on fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17782
diff changeset
  1246
            return True
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 49284
diff changeset
  1247
        except FileNotFoundError:
17783
df55ce6854c3 store: add new _exists helper function on fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17782
diff changeset
  1248
            return False
df55ce6854c3 store: add new _exists helper function on fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17782
diff changeset
  1249
17745
b9a56b816ff2 store: add a contains method to fncachestore
smuralid
parents: 17744
diff changeset
  1250
    def __contains__(self, path):
b9a56b816ff2 store: add a contains method to fncachestore
smuralid
parents: 17744
diff changeset
  1251
        '''Checks if the store contains path'''
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1252
        path = b"/".join((b"data", path))
17782
8095306c1fb2 store: move __contains__() implementation from class fncache into fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17747
diff changeset
  1253
        # check for files (exact match)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1254
        e = path + b'.i'
17784
73e1ab39792c store: fncache may contain non-existent entries (fixes b9a56b816ff2)
Adrian Buehlmann <adrian@cadifra.com>
parents: 17783
diff changeset
  1255
        if e in self.fncache and self._exists(e):
17782
8095306c1fb2 store: move __contains__() implementation from class fncache into fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17747
diff changeset
  1256
            return True
8095306c1fb2 store: move __contains__() implementation from class fncache into fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17747
diff changeset
  1257
        # now check for directories (prefix match)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1258
        if not path.endswith(b'/'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1259
            path += b'/'
17782
8095306c1fb2 store: move __contains__() implementation from class fncache into fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17747
diff changeset
  1260
        for e in self.fncache:
17784
73e1ab39792c store: fncache may contain non-existent entries (fixes b9a56b816ff2)
Adrian Buehlmann <adrian@cadifra.com>
parents: 17783
diff changeset
  1261
            if e.startswith(path) and self._exists(e):
17782
8095306c1fb2 store: move __contains__() implementation from class fncache into fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17747
diff changeset
  1262
                return True
8095306c1fb2 store: move __contains__() implementation from class fncache into fncachestore
Adrian Buehlmann <adrian@cadifra.com>
parents: 17747
diff changeset
  1263
        return False