mercurial/dirstatemap.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Fri, 15 Mar 2024 01:31:57 +0100
branchstable
changeset 51505 c9ceb4f60256
parent 50928 d718eddf01d9
permissions -rw-r--r--
phases: avoid N² behavior in `advanceboundary` We allowed duplicated entries in the deque, which each entry could potentially insert all its ancestors. So advancing boundary for the full repository would mean each revision would walk all its ancestors, resulting in O(N²) iteration. For repository of any decent size, N² is quickly insane. We introduce a simple set to avoid this and get back to reasonable performance.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
47501
8b7e47802deb dirstate: split dirstatemap in its own file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47489
diff changeset
     1
# dirstatemap.py
8226
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     2
#
8b2cd04a6e97 put license and copyright info into comment blocks
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     3
# 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: 9678
diff changeset
     4
# GNU General Public License version 2 or any later version.
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     5
27503
0f4596622273 dirstate: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27399
diff changeset
     6
0f4596622273 dirstate: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27399
diff changeset
     7
from .i18n import _
43239
6fcdcea2b03a dirstate: add some traces on listdir calls
Augie Fackler <augie@google.com>
parents: 43117
diff changeset
     8
27503
0f4596622273 dirstate: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27399
diff changeset
     9
from . import (
0f4596622273 dirstate: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27399
diff changeset
    10
    error,
0f4596622273 dirstate: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27399
diff changeset
    11
    pathutil,
32372
df448de7cf3b parsers: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32352
diff changeset
    12
    policy,
50228
fc8e37c380d3 dirstate: add a synchronisation point before doing a full dirstate read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50222
diff changeset
    13
    testing,
31050
206532700213 txnutil: factor out the logic to read file in according to HG_PENDING
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 30634
diff changeset
    14
    txnutil,
27503
0f4596622273 dirstate: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27399
diff changeset
    15
    util,
0f4596622273 dirstate: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 27399
diff changeset
    16
)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    17
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47672
diff changeset
    18
from .dirstateutils import (
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47672
diff changeset
    19
    docket as docketmod,
48221
a32a96079e2d dirstate-v2: initial Python parser
Simon Sapin <simon.sapin@octobus.net>
parents: 48220
diff changeset
    20
    v2,
47674
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47672
diff changeset
    21
)
ff97e793ed36 dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents: 47672
diff changeset
    22
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43505
diff changeset
    23
parsers = policy.importmod('parsers')
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43505
diff changeset
    24
rustmod = policy.importrust('dirstate')
32372
df448de7cf3b parsers: switch to policy importer
Yuya Nishihara <yuya@tcha.org>
parents: 32352
diff changeset
    25
8261
0fe1f57ac2bd dirstate: use propertycache
Matt Mackall <mpm@selenic.com>
parents: 8226
diff changeset
    26
propertycache = util.propertycache
16201
fb7c4c14223f dirstate: filecacheify _branch
Idan Kamara <idankk86@gmail.com>
parents: 16200
diff changeset
    27
48044
d5528ac9b4f2 dirstate: Use the Rust implementation of DirstateItem when Rust is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48024
diff changeset
    28
if rustmod is None:
d5528ac9b4f2 dirstate: Use the Rust implementation of DirstateItem when Rust is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48024
diff changeset
    29
    DirstateItem = parsers.DirstateItem
d5528ac9b4f2 dirstate: Use the Rust implementation of DirstateItem when Rust is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48024
diff changeset
    30
else:
d5528ac9b4f2 dirstate: Use the Rust implementation of DirstateItem when Rust is enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48024
diff changeset
    31
    DirstateItem = rustmod.DirstateItem
21808
7537e57f5dbd dirstate: add dirstatetuple to create dirstate values
Siddharth Agarwal <sid0@fb.com>
parents: 21116
diff changeset
    32
47521
abed645b8e96 dirstate: move the handling of special case within the dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47514
diff changeset
    33
rangemask = 0x7FFFFFFF
abed645b8e96 dirstate: move the handling of special case within the dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47514
diff changeset
    34
50221
1891086f6c7f dirstate: use more than a bool to control append behavior
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50097
diff changeset
    35
WRITE_MODE_AUTO = 0
1891086f6c7f dirstate: use more than a bool to control append behavior
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50097
diff changeset
    36
WRITE_MODE_FORCE_NEW = 1
50222
ecd28d89c29e dirstate-v2: add devel config option to control write behavior
Raphaël Gomès <rgomes@octobus.net>
parents: 50221
diff changeset
    37
WRITE_MODE_FORCE_APPEND = 2
50221
1891086f6c7f dirstate: use more than a bool to control append behavior
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50097
diff changeset
    38
47482
cb29484eaade dirstate: introduce a symbolic constant for the FROM_P2 marker
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47481
diff changeset
    39
50237
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
    40
V2_MAX_READ_ATTEMPTS = 5
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
    41
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
    42
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
    43
class _dirstatemapcommon:
48119
aec5b0981c26 dirstatemap: introduce a common base for the dirstatemap class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48109
diff changeset
    44
    """
aec5b0981c26 dirstatemap: introduce a common base for the dirstatemap class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48109
diff changeset
    45
    Methods that are identical for both implementations of the dirstatemap
aec5b0981c26 dirstatemap: introduce a common base for the dirstatemap class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48109
diff changeset
    46
    class, with and without Rust extensions enabled.
aec5b0981c26 dirstatemap: introduce a common base for the dirstatemap class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48109
diff changeset
    47
    """
aec5b0981c26 dirstatemap: introduce a common base for the dirstatemap class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48109
diff changeset
    48
48122
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
    49
    # please pytype
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
    50
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
    51
    _map = None
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
    52
    copymap = None
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
    53
48120
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    54
    def __init__(self, ui, opener, root, nodeconstants, use_dirstate_v2):
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    55
        self._use_dirstate_v2 = use_dirstate_v2
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    56
        self._nodeconstants = nodeconstants
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    57
        self._ui = ui
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    58
        self._opener = opener
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    59
        self._root = root
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    60
        self._filename = b'dirstate'
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    61
        self._nodelen = 20  # Also update Rust code when changing this!
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    62
        self._parents = None
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    63
        self._dirtyparents = False
48220
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
    64
        self._docket = None
50222
ecd28d89c29e dirstate-v2: add devel config option to control write behavior
Raphaël Gomès <rgomes@octobus.net>
parents: 50221
diff changeset
    65
        write_mode = ui.config(b"devel", b"dirstate.v2.data_update_mode")
ecd28d89c29e dirstate-v2: add devel config option to control write behavior
Raphaël Gomès <rgomes@octobus.net>
parents: 50221
diff changeset
    66
        if write_mode == b"auto":
ecd28d89c29e dirstate-v2: add devel config option to control write behavior
Raphaël Gomès <rgomes@octobus.net>
parents: 50221
diff changeset
    67
            self._write_mode = WRITE_MODE_AUTO
ecd28d89c29e dirstate-v2: add devel config option to control write behavior
Raphaël Gomès <rgomes@octobus.net>
parents: 50221
diff changeset
    68
        elif write_mode == b"force-append":
ecd28d89c29e dirstate-v2: add devel config option to control write behavior
Raphaël Gomès <rgomes@octobus.net>
parents: 50221
diff changeset
    69
            self._write_mode = WRITE_MODE_FORCE_APPEND
ecd28d89c29e dirstate-v2: add devel config option to control write behavior
Raphaël Gomès <rgomes@octobus.net>
parents: 50221
diff changeset
    70
        elif write_mode == b"force-new":
ecd28d89c29e dirstate-v2: add devel config option to control write behavior
Raphaël Gomès <rgomes@octobus.net>
parents: 50221
diff changeset
    71
            self._write_mode = WRITE_MODE_FORCE_NEW
ecd28d89c29e dirstate-v2: add devel config option to control write behavior
Raphaël Gomès <rgomes@octobus.net>
parents: 50221
diff changeset
    72
        else:
ecd28d89c29e dirstate-v2: add devel config option to control write behavior
Raphaël Gomès <rgomes@octobus.net>
parents: 50221
diff changeset
    73
            # unknown value, fallback to default
ecd28d89c29e dirstate-v2: add devel config option to control write behavior
Raphaël Gomès <rgomes@octobus.net>
parents: 50221
diff changeset
    74
            self._write_mode = WRITE_MODE_AUTO
48120
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    75
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    76
        # for consistent view between _pl() and _read() invocations
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    77
        self._pendingmode = None
fe6617715464 dirstatemap: use a common __init__ for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48119
diff changeset
    78
50241
342c3c4640b7 dirstate: factor the identity setting code in the dirstate map
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50238
diff changeset
    79
    def _set_identity(self):
50126
85746485a4dd dirstate: factor the identity getting/setting code in the dirstate map
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50125
diff changeset
    80
        self.identity = self._get_current_identity()
85746485a4dd dirstate: factor the identity getting/setting code in the dirstate map
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50125
diff changeset
    81
85746485a4dd dirstate: factor the identity getting/setting code in the dirstate map
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50125
diff changeset
    82
    def _get_current_identity(self):
85746485a4dd dirstate: factor the identity getting/setting code in the dirstate map
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50125
diff changeset
    83
        try:
85746485a4dd dirstate: factor the identity getting/setting code in the dirstate map
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50125
diff changeset
    84
            return util.cachestat(self._opener.join(self._filename))
85746485a4dd dirstate: factor the identity getting/setting code in the dirstate map
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50125
diff changeset
    85
        except FileNotFoundError:
85746485a4dd dirstate: factor the identity getting/setting code in the dirstate map
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50125
diff changeset
    86
            return None
85746485a4dd dirstate: factor the identity getting/setting code in the dirstate map
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50125
diff changeset
    87
50128
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
    88
    def may_need_refresh(self):
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
    89
        if 'identity' not in vars(self):
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
    90
            # no existing identity, we need a refresh
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
    91
            return True
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
    92
        if self.identity is None:
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
    93
            return True
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
    94
        if not self.identity.cacheable():
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
    95
            # We cannot trust the entry
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
    96
            # XXX this is a problem on windows, NFS, or other inode less system
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
    97
            return True
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
    98
        current_identity = self._get_current_identity()
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
    99
        if current_identity is None:
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
   100
            return True
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
   101
        if not current_identity.cacheable():
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
   102
            # We cannot trust the entry
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
   103
            # XXX this is a problem on windows, NFS, or other inode less system
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
   104
            return True
2f60cd6442fd dirstate: only reload the dirstate when it may have changed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50126
diff changeset
   105
        return current_identity != self.identity
50241
342c3c4640b7 dirstate: factor the identity setting code in the dirstate map
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50238
diff changeset
   106
48122
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   107
    def preload(self):
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   108
        """Loads the underlying data, if it's not already loaded"""
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   109
        self._map
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   110
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   111
    def get(self, key, default=None):
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   112
        return self._map.get(key, default)
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   113
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   114
    def __len__(self):
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   115
        return len(self._map)
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   116
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   117
    def __iter__(self):
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   118
        return iter(self._map)
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   119
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   120
    def __contains__(self, key):
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   121
        return key in self._map
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   122
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   123
    def __getitem__(self, item):
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   124
        return self._map[item]
bbd924a36a6e dirstatemap: move a multiple simple functions in the common class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48121
diff changeset
   125
48220
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   126
    ### disk interaction
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   127
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   128
    def _opendirstatefile(self):
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   129
        fp, mode = txnutil.trypending(self._root, self._opener, self._filename)
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   130
        if self._pendingmode is not None and self._pendingmode != mode:
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   131
            fp.close()
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   132
            raise error.Abort(
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   133
                _(b'working directory state may be changed parallelly')
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   134
            )
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   135
        self._pendingmode = mode
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   136
        return fp
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   137
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   138
    def _readdirstatefile(self, size=-1):
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   139
        try:
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   140
            with self._opendirstatefile() as fp:
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   141
                return fp.read(size)
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 49120
diff changeset
   142
        except FileNotFoundError:
48220
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   143
            # File doesn't exist, so the current state is empty
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   144
            return b''
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   145
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   146
    @property
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   147
    def docket(self):
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   148
        if not self._docket:
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   149
            if not self._use_dirstate_v2:
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   150
                raise error.ProgrammingError(
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   151
                    b'dirstate only has a docket in v2 format'
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   152
                )
50242
379a78001d8e dirstate: set identity whenever we read the dirstate's v2 docket
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50241
diff changeset
   153
            self._set_identity()
50723
bfbd84c57bda dirstate-v2: actually fix the dirstate-v2 upgrade race
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50686
diff changeset
   154
            data = self._readdirstatefile()
bfbd84c57bda dirstate-v2: actually fix the dirstate-v2 upgrade race
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50686
diff changeset
   155
            if data == b'' or data.startswith(docketmod.V2_FORMAT_MARKER):
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   156
                self._docket = docketmod.DirstateDocket.parse(
50723
bfbd84c57bda dirstate-v2: actually fix the dirstate-v2 upgrade race
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50686
diff changeset
   157
                    data, self._nodeconstants
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   158
                )
50723
bfbd84c57bda dirstate-v2: actually fix the dirstate-v2 upgrade race
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50686
diff changeset
   159
            else:
bfbd84c57bda dirstate-v2: actually fix the dirstate-v2 upgrade race
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50686
diff changeset
   160
                raise error.CorruptedDirstate(b"dirstate is not in v2 format")
48220
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   161
        return self._docket
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   162
50236
53f196622699 dirstate: abstract the reading of the data file in v2 in a method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50234
diff changeset
   163
    def _read_v2_data(self):
50237
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   164
        data = None
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   165
        attempts = 0
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   166
        while attempts < V2_MAX_READ_ATTEMPTS:
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   167
            attempts += 1
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   168
            try:
50238
c9066fc609ef dirstate: deal with read-race for python code using rust object
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50237
diff changeset
   169
                # TODO: use mmap when possible
50237
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   170
                data = self._opener.read(self.docket.data_filename())
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   171
            except FileNotFoundError:
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   172
                # read race detected between docket and data file
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   173
                # reload the docket and retry
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   174
                self._docket = None
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   175
        if data is None:
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   176
            assert attempts >= V2_MAX_READ_ATTEMPTS
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   177
            msg = b"dirstate read race happened %d times in a row"
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   178
            msg %= attempts
a3b1ab5f5dee dirstate: deal with read-race for pure python code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50236
diff changeset
   179
            raise error.Abort(msg)
50236
53f196622699 dirstate: abstract the reading of the data file in v2 in a method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50234
diff changeset
   180
        return self._opener.read(self.docket.data_filename())
53f196622699 dirstate: abstract the reading of the data file in v2 in a method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50234
diff changeset
   181
48220
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   182
    def write_v2_no_append(self, tr, st, meta, packed):
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   183
        try:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   184
            old_docket = self.docket
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   185
        except error.CorruptedDirstate:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   186
            # This means we've identified a dirstate-v1 file on-disk when we
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   187
            # were expecting a dirstate-v2 docket. We've managed to recover
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   188
            # from that unexpected situation, and now we want to write back a
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   189
            # dirstate-v2 file to make the on-disk situation right again.
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   190
            #
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   191
            # This shouldn't be triggered since `self.docket` is cached and
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   192
            # we would have called parents() or read() first, but it's here
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   193
            # just in case.
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   194
            old_docket = None
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   195
48220
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   196
        new_docket = docketmod.DirstateDocket.with_new_uuid(
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   197
            self.parents(), len(packed), meta
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   198
        )
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   199
        if old_docket is not None and old_docket.uuid == new_docket.uuid:
50097
ca9d65d69c27 dirstate-v2: complain early on docket name collision
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49619
diff changeset
   200
            raise error.ProgrammingError(b'dirstate docket name collision')
48220
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   201
        data_filename = new_docket.data_filename()
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   202
        self._opener.write(data_filename, packed)
50081
9a0778bbae6a dirstate: explicitly backup the datafile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49619
diff changeset
   203
        # tell the transaction that we are adding a new file
9a0778bbae6a dirstate: explicitly backup the datafile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49619
diff changeset
   204
        if tr is not None:
9a0778bbae6a dirstate: explicitly backup the datafile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49619
diff changeset
   205
            tr.addbackup(data_filename, location=b'plain')
48220
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   206
        # Write the new docket after the new data file has been
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   207
        # written. Because `st` was opened with `atomictemp=True`,
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   208
        # the actual `.hg/dirstate` file is only affected on close.
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   209
        st.write(new_docket.serialize())
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   210
        st.close()
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   211
        # Remove the old data file after the new docket pointing to
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   212
        # the new data file was written.
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   213
        if old_docket is not None and old_docket.uuid:
48220
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   214
            data_filename = old_docket.data_filename()
50081
9a0778bbae6a dirstate: explicitly backup the datafile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49619
diff changeset
   215
            if tr is not None:
9a0778bbae6a dirstate: explicitly backup the datafile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49619
diff changeset
   216
                tr.addbackup(data_filename, location=b'plain')
48220
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   217
            unlink = lambda _tr=None: self._opener.unlink(data_filename)
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   218
            if tr:
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   219
                category = b"dirstate-v2-clean-" + old_docket.uuid
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   220
                tr.addpostclose(category, unlink)
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   221
            else:
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   222
                unlink()
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   223
        self._docket = new_docket
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   224
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   225
    ### reading/setting parents
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   226
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   227
    def parents(self):
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   228
        if not self._parents:
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   229
            if self._use_dirstate_v2:
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   230
                try:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   231
                    self.docket
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   232
                except error.CorruptedDirstate as e:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   233
                    # fall back to dirstate-v1 if we fail to read v2
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   234
                    self._v1_parents(e)
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   235
                else:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   236
                    self._parents = self.docket.parents
48220
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   237
            else:
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   238
                self._v1_parents()
48220
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   239
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   240
        return self._parents
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   241
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   242
    def _v1_parents(self, from_v2_exception=None):
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   243
        read_len = self._nodelen * 2
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   244
        st = self._readdirstatefile(read_len)
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   245
        l = len(st)
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   246
        if l == read_len:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   247
            self._parents = (
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   248
                st[: self._nodelen],
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   249
                st[self._nodelen : 2 * self._nodelen],
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   250
            )
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   251
        elif l == 0:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   252
            self._parents = (
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   253
                self._nodeconstants.nullid,
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   254
                self._nodeconstants.nullid,
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   255
            )
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   256
        else:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   257
            hint = None
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   258
            if from_v2_exception is not None:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   259
                hint = _(b"falling back to dirstate-v1 from v2 also failed")
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   260
            raise error.Abort(
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   261
                _(b'working directory state appears damaged!'), hint
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   262
            )
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   263
48119
aec5b0981c26 dirstatemap: introduce a common base for the dirstatemap class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48109
diff changeset
   264
aec5b0981c26 dirstatemap: introduce a common base for the dirstatemap class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48109
diff changeset
   265
class dirstatemap(_dirstatemapcommon):
35078
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   266
    """Map encapsulating the dirstate's contents.
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   267
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   268
    The dirstate contains the following state:
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   269
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   270
    - `identity` is the identity of the dirstate file, which can be used to
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   271
      detect when changes have occurred to the dirstate file.
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   272
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   273
    - `parents` is a pair containing the parents of the working copy. The
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   274
      parents are updated by calling `setparents`.
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   275
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   276
    - the state map maps filenames to tuples of (state, mode, size, mtime),
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   277
      where state is a single character representing 'normal', 'added',
35079
853b7c41d19c dirstate: add explicit methods for modifying dirstate
Mark Thomas <mbthomas@fb.com>
parents: 35078
diff changeset
   278
      'removed', or 'merged'. It is read by treating the dirstate as a
47996
aa442fde0ea5 dirstate: update the documentation of the dirstatemap API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47990
diff changeset
   279
      dict.  File state is updated by calling various methods (see each
aa442fde0ea5 dirstate: update the documentation of the dirstatemap API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47990
diff changeset
   280
      documentation for details):
aa442fde0ea5 dirstate: update the documentation of the dirstatemap API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47990
diff changeset
   281
aa442fde0ea5 dirstate: update the documentation of the dirstatemap API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47990
diff changeset
   282
      - `reset_state`,
aa442fde0ea5 dirstate: update the documentation of the dirstatemap API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47990
diff changeset
   283
      - `set_tracked`
aa442fde0ea5 dirstate: update the documentation of the dirstatemap API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47990
diff changeset
   284
      - `set_untracked`
aa442fde0ea5 dirstate: update the documentation of the dirstatemap API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47990
diff changeset
   285
      - `set_clean`
aa442fde0ea5 dirstate: update the documentation of the dirstatemap API
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47990
diff changeset
   286
      - `set_possibly_dirty`
35078
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   287
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   288
    - `copymap` maps destination filenames to their source filename.
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   289
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   290
    The dirstate also provides the following views onto the state:
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   291
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   292
    - `filefoldmap` is a dict mapping normalized filenames to the denormalized
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   293
      form that they appear as in the dirstate.
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   294
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   295
    - `dirfoldmap` is a dict mapping normalized directory names to the
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   296
      denormalized form that they appear as in the dirstate.
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   297
    """
a052022639cc dirstate: document dirstatemap interface
Mark Thomas <mbthomas@fb.com>
parents: 35016
diff changeset
   298
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   299
    ### Core data storage and access
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   300
34934
6e66033f91cc dirstate: avoid reading the map when possible (issue5713) (issue5717)
Durham Goode <durham@fb.com>
parents: 34933
diff changeset
   301
    @propertycache
6e66033f91cc dirstate: avoid reading the map when possible (issue5713) (issue5717)
Durham Goode <durham@fb.com>
parents: 34933
diff changeset
   302
    def _map(self):
6e66033f91cc dirstate: avoid reading the map when possible (issue5713) (issue5717)
Durham Goode <durham@fb.com>
parents: 34933
diff changeset
   303
        self._map = {}
6e66033f91cc dirstate: avoid reading the map when possible (issue5713) (issue5717)
Durham Goode <durham@fb.com>
parents: 34933
diff changeset
   304
        self.read()
6e66033f91cc dirstate: avoid reading the map when possible (issue5713) (issue5717)
Durham Goode <durham@fb.com>
parents: 34933
diff changeset
   305
        return self._map
6e66033f91cc dirstate: avoid reading the map when possible (issue5713) (issue5717)
Durham Goode <durham@fb.com>
parents: 34933
diff changeset
   306
6e66033f91cc dirstate: avoid reading the map when possible (issue5713) (issue5717)
Durham Goode <durham@fb.com>
parents: 34933
diff changeset
   307
    @propertycache
6e66033f91cc dirstate: avoid reading the map when possible (issue5713) (issue5717)
Durham Goode <durham@fb.com>
parents: 34933
diff changeset
   308
    def copymap(self):
6e66033f91cc dirstate: avoid reading the map when possible (issue5713) (issue5717)
Durham Goode <durham@fb.com>
parents: 34933
diff changeset
   309
        self.copymap = {}
6e66033f91cc dirstate: avoid reading the map when possible (issue5713) (issue5717)
Durham Goode <durham@fb.com>
parents: 34933
diff changeset
   310
        self._map
6e66033f91cc dirstate: avoid reading the map when possible (issue5713) (issue5717)
Durham Goode <durham@fb.com>
parents: 34933
diff changeset
   311
        return self.copymap
6e66033f91cc dirstate: avoid reading the map when possible (issue5713) (issue5717)
Durham Goode <durham@fb.com>
parents: 34933
diff changeset
   312
34933
0217f75b6e59 dirstate: move clear onto dirstatemap class
Durham Goode <durham@fb.com>
parents: 34678
diff changeset
   313
    def clear(self):
34935
ffeea2406276 dirstate: remove excess attribute lookups for dirstate.status (issue5714)
Durham Goode <durham@fb.com>
parents: 34934
diff changeset
   314
        self._map.clear()
ffeea2406276 dirstate: remove excess attribute lookups for dirstate.status (issue5714)
Durham Goode <durham@fb.com>
parents: 34934
diff changeset
   315
        self.copymap.clear()
47012
d55b71393907 node: replace nullid and friends with nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46819
diff changeset
   316
        self.setparents(self._nodeconstants.nullid, self._nodeconstants.nullid)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   317
        util.clearcachedproperty(self, b"_dirs")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   318
        util.clearcachedproperty(self, b"_alldirs")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   319
        util.clearcachedproperty(self, b"filefoldmap")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   320
        util.clearcachedproperty(self, b"dirfoldmap")
34933
0217f75b6e59 dirstate: move clear onto dirstatemap class
Durham Goode <durham@fb.com>
parents: 34678
diff changeset
   321
35878
6e7fae8f1c6c contrib: fix dirstatenonnormalcheck to work in Python 3
Augie Fackler <augie@google.com>
parents: 35835
diff changeset
   322
    def items(self):
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   323
        return self._map.items()
34332
b36881c68569 dirstate: create new dirstatemap class
Durham Goode <durham@fb.com>
parents: 34188
diff changeset
   324
35878
6e7fae8f1c6c contrib: fix dirstatenonnormalcheck to work in Python 3
Augie Fackler <augie@google.com>
parents: 35835
diff changeset
   325
    # forward for python2,3 compat
6e7fae8f1c6c contrib: fix dirstatenonnormalcheck to work in Python 3
Augie Fackler <augie@google.com>
parents: 35835
diff changeset
   326
    iteritems = items
6e7fae8f1c6c contrib: fix dirstatenonnormalcheck to work in Python 3
Augie Fackler <augie@google.com>
parents: 35835
diff changeset
   327
48023
357307feaf61 debugstate: Always call dirstatemap.debug_iter()
Simon Sapin <simon.sapin@octobus.net>
parents: 48019
diff changeset
   328
    def debug_iter(self, all):
357307feaf61 debugstate: Always call dirstatemap.debug_iter()
Simon Sapin <simon.sapin@octobus.net>
parents: 48019
diff changeset
   329
        """
48024
cedfe2606adf debugsate: Change debug_iter() to yield tuples instead of DirstateItem
Simon Sapin <simon.sapin@octobus.net>
parents: 48023
diff changeset
   330
        Return an iterator of (filename, state, mode, size, mtime) tuples
cedfe2606adf debugsate: Change debug_iter() to yield tuples instead of DirstateItem
Simon Sapin <simon.sapin@octobus.net>
parents: 48023
diff changeset
   331
48023
357307feaf61 debugstate: Always call dirstatemap.debug_iter()
Simon Sapin <simon.sapin@octobus.net>
parents: 48019
diff changeset
   332
        `all` is unused when Rust is not enabled
357307feaf61 debugstate: Always call dirstatemap.debug_iter()
Simon Sapin <simon.sapin@octobus.net>
parents: 48019
diff changeset
   333
        """
48024
cedfe2606adf debugsate: Change debug_iter() to yield tuples instead of DirstateItem
Simon Sapin <simon.sapin@octobus.net>
parents: 48023
diff changeset
   334
        for (filename, item) in self.items():
cedfe2606adf debugsate: Change debug_iter() to yield tuples instead of DirstateItem
Simon Sapin <simon.sapin@octobus.net>
parents: 48023
diff changeset
   335
            yield (filename, item.state, item.mode, item.size, item.mtime)
47683
284a20269a97 dirstate-v2: Separate iterators for dirfoldmap and debugdirstate
Simon Sapin <simon.sapin@octobus.net>
parents: 47682
diff changeset
   336
34332
b36881c68569 dirstate: create new dirstatemap class
Durham Goode <durham@fb.com>
parents: 34188
diff changeset
   337
    def keys(self):
b36881c68569 dirstate: create new dirstatemap class
Durham Goode <durham@fb.com>
parents: 34188
diff changeset
   338
        return self._map.keys()
34333
4ac04418ce66 dirstate: move nonnormalentries to dirstatemap
Durham Goode <durham@fb.com>
parents: 34332
diff changeset
   339
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   340
    ### reading/setting parents
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   341
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   342
    def setparents(self, p1, p2, fold_p2=False):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   343
        self._parents = (p1, p2)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   344
        self._dirtyparents = True
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   345
        copies = {}
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   346
        if fold_p2:
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   347
            for f, s in self._map.items():
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   348
                # Discard "merged" markers when moving away from a merge state
48148
e2753a7acfa7 dirstate-item: use the `p2_info` property to replace more verbose call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48140
diff changeset
   349
                if s.p2_info:
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   350
                    source = self.copymap.pop(f, None)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   351
                    if source:
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   352
                        copies[f] = source
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   353
                    s.drop_merge_data()
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   354
        return copies
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   355
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   356
    ### disk interaction
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   357
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   358
    def read(self):
50228
fc8e37c380d3 dirstate: add a synchronisation point before doing a full dirstate read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50222
diff changeset
   359
        testing.wait_on_cfg(self._ui, b'dirstate.pre-read-file')
48223
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   360
        if self._use_dirstate_v2:
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   361
            try:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   362
                self.docket
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   363
            except error.CorruptedDirstate:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   364
                # fall back to dirstate-v1 if we fail to read v2
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   365
                self._set_identity()
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   366
                st = self._readdirstatefile()
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   367
            else:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   368
                if not self.docket.uuid:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   369
                    return
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   370
                testing.wait_on_cfg(self._ui, b'dirstate.post-docket-read-file')
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   371
                st = self._read_v2_data()
48223
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   372
        else:
50242
379a78001d8e dirstate: set identity whenever we read the dirstate's v2 docket
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50241
diff changeset
   373
            self._set_identity()
48223
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   374
            st = self._readdirstatefile()
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   375
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   376
        if not st:
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   377
            return
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   378
48223
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   379
        # TODO: adjust this estimate for dirstate-v2
50928
d718eddf01d9 safehasattr: drop usage in favor of hasattr
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50723
diff changeset
   380
        if hasattr(parsers, 'dict_new_presized'):
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   381
            # Make an estimate of the number of files in the dirstate based on
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   382
            # its size. This trades wasting some memory for avoiding costly
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   383
            # resizes. Each entry have a prefix of 17 bytes followed by one or
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   384
            # two path names. Studies on various large-scale real-world repositories
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   385
            # found 54 bytes a reasonable upper limit for the average path names.
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   386
            # Copy entries are ignored for the sake of this estimate.
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   387
            self._map = parsers.dict_new_presized(len(st) // 71)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   388
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   389
        # Python's garbage collector triggers a GC each time a certain number
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   390
        # of container objects (the number being defined by
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   391
        # gc.get_threshold()) are allocated. parse_dirstate creates a tuple
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   392
        # for each file in the dirstate. The C version then immediately marks
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   393
        # them as not to be tracked by the collector. However, this has no
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   394
        # effect on when GCs are triggered, only on what objects the GC looks
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   395
        # into. This means that O(number of files) GCs are unavoidable.
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   396
        # Depending on when in the process's lifetime the dirstate is parsed,
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   397
        # this can get very expensive. As a workaround, disable GC while
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   398
        # parsing the dirstate.
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   399
        #
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   400
        # (we cannot decorate the function directly since it is in a C module)
48223
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   401
        if self._use_dirstate_v2:
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   402
            try:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   403
                self.docket
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   404
            except error.CorruptedDirstate:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   405
                # fall back to dirstate-v1 if we fail to parse v2
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   406
                parse_dirstate = util.nogc(parsers.parse_dirstate)
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   407
                p = parse_dirstate(self._map, self.copymap, st)
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   408
            else:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   409
                p = self.docket.parents
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   410
                meta = self.docket.tree_metadata
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   411
                parse_dirstate = util.nogc(v2.parse_dirstate)
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   412
                parse_dirstate(self._map, self.copymap, st, meta)
48223
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   413
        else:
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   414
            parse_dirstate = util.nogc(parsers.parse_dirstate)
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   415
            p = parse_dirstate(self._map, self.copymap, st)
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   416
        if not self._dirtyparents:
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   417
            self.setparents(*p)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   418
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   419
        # Avoid excess attribute lookups by fast pathing certain checks
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   420
        self.__contains__ = self._map.__contains__
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   421
        self.__getitem__ = self._map.__getitem__
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   422
        self.get = self._map.get
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   423
48393
1a8a70b4b0ad dirstate: cleanup remaining of "now" during write
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48392
diff changeset
   424
    def write(self, tr, st):
48223
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   425
        if self._use_dirstate_v2:
48392
434de12918fd dirstate: remove need_delay logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48260
diff changeset
   426
            packed, meta = v2.pack_dirstate(self._map, self.copymap)
48223
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   427
            self.write_v2_no_append(tr, st, meta, packed)
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   428
        else:
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   429
            packed = parsers.pack_dirstate(
48392
434de12918fd dirstate: remove need_delay logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48260
diff changeset
   430
                self._map, self.copymap, self.parents()
48223
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   431
            )
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   432
            st.write(packed)
b4f83c9e7905 dirstate-v2: Add support when Rust is not enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 48221
diff changeset
   433
            st.close()
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   434
        self._dirtyparents = False
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   435
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   436
    @propertycache
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   437
    def identity(self):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   438
        self._map
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   439
        return self.identity
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   440
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   441
    ### code related to maintaining and accessing "extra" property
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   442
    # (e.g. "has_dir")
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   443
47687
e59bd6723f2f dirstate-map: factor out the change to _dirs and _alldirs on adding
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47686
diff changeset
   444
    def _dirs_incr(self, filename, old_entry=None):
49118
2c78dd3f11de dirstatemap: move `_dirs_incr` and `_dirs_decr` methods out of the common
Raphaël Gomès <rgomes@octobus.net>
parents: 49117
diff changeset
   445
        """increment the dirstate counter if applicable"""
47687
e59bd6723f2f dirstate-map: factor out the change to _dirs and _alldirs on adding
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47686
diff changeset
   446
        if (
e59bd6723f2f dirstate-map: factor out the change to _dirs and _alldirs on adding
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47686
diff changeset
   447
            old_entry is None or old_entry.removed
e59bd6723f2f dirstate-map: factor out the change to _dirs and _alldirs on adding
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47686
diff changeset
   448
        ) and "_dirs" in self.__dict__:
e59bd6723f2f dirstate-map: factor out the change to _dirs and _alldirs on adding
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47686
diff changeset
   449
            self._dirs.addpath(filename)
e59bd6723f2f dirstate-map: factor out the change to _dirs and _alldirs on adding
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47686
diff changeset
   450
        if old_entry is None and "_alldirs" in self.__dict__:
e59bd6723f2f dirstate-map: factor out the change to _dirs and _alldirs on adding
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47686
diff changeset
   451
            self._alldirs.addpath(filename)
e59bd6723f2f dirstate-map: factor out the change to _dirs and _alldirs on adding
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47686
diff changeset
   452
47689
f2aef39abc14 dirstate-map: factor out the change to _dirs and _alldirs on removing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47688
diff changeset
   453
    def _dirs_decr(self, filename, old_entry=None, remove_variant=False):
49118
2c78dd3f11de dirstatemap: move `_dirs_incr` and `_dirs_decr` methods out of the common
Raphaël Gomès <rgomes@octobus.net>
parents: 49117
diff changeset
   454
        """decrement the dirstate counter if applicable"""
47688
b37ab6b5c438 dirstate-map: factor out the change to _dirs and _alldirs on dropping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47687
diff changeset
   455
        if old_entry is not None:
b37ab6b5c438 dirstate-map: factor out the change to _dirs and _alldirs on dropping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47687
diff changeset
   456
            if "_dirs" in self.__dict__ and not old_entry.removed:
b37ab6b5c438 dirstate-map: factor out the change to _dirs and _alldirs on dropping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47687
diff changeset
   457
                self._dirs.delpath(filename)
47689
f2aef39abc14 dirstate-map: factor out the change to _dirs and _alldirs on removing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47688
diff changeset
   458
            if "_alldirs" in self.__dict__ and not remove_variant:
47688
b37ab6b5c438 dirstate-map: factor out the change to _dirs and _alldirs on dropping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47687
diff changeset
   459
                self._alldirs.delpath(filename)
47689
f2aef39abc14 dirstate-map: factor out the change to _dirs and _alldirs on removing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47688
diff changeset
   460
        elif remove_variant and "_alldirs" in self.__dict__:
f2aef39abc14 dirstate-map: factor out the change to _dirs and _alldirs on removing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47688
diff changeset
   461
            self._alldirs.addpath(filename)
47688
b37ab6b5c438 dirstate-map: factor out the change to _dirs and _alldirs on dropping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47687
diff changeset
   462
        if "filefoldmap" in self.__dict__:
b37ab6b5c438 dirstate-map: factor out the change to _dirs and _alldirs on dropping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47687
diff changeset
   463
            normed = util.normcase(filename)
b37ab6b5c438 dirstate-map: factor out the change to _dirs and _alldirs on dropping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47687
diff changeset
   464
            self.filefoldmap.pop(normed, None)
b37ab6b5c438 dirstate-map: factor out the change to _dirs and _alldirs on dropping
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47687
diff changeset
   465
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   466
    @propertycache
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   467
    def filefoldmap(self):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   468
        """Returns a dictionary mapping normalized case paths to their
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   469
        non-normalized versions.
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   470
        """
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   471
        try:
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   472
            makefilefoldmap = parsers.make_file_foldmap
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   473
        except AttributeError:
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   474
            pass
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   475
        else:
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   476
            return makefilefoldmap(
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   477
                self._map, util.normcasespec, util.normcasefallback
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   478
            )
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   479
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   480
        f = {}
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   481
        normcase = util.normcase
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   482
        for name, s in self._map.items():
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   483
            if not s.removed:
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   484
                f[normcase(name)] = name
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   485
        f[b'.'] = b'.'  # prevents useless util.fspath() invocation
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   486
        return f
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   487
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   488
    @propertycache
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   489
    def dirfoldmap(self):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   490
        f = {}
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   491
        normcase = util.normcase
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   492
        for name in self._dirs:
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   493
            f[normcase(name)] = name
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   494
        return f
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   495
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   496
    def hastrackeddir(self, d):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   497
        """
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   498
        Returns True if the dirstate contains a tracked (not removed) file
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   499
        in this directory.
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   500
        """
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   501
        return d in self._dirs
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   502
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   503
    def hasdir(self, d):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   504
        """
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   505
        Returns True if the dirstate contains a file (tracked or removed)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   506
        in this directory.
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   507
        """
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   508
        return d in self._alldirs
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   509
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   510
    @propertycache
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   511
    def _dirs(self):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   512
        return pathutil.dirs(self._map, only_tracked=True)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   513
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   514
    @propertycache
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   515
    def _alldirs(self):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   516
        return pathutil.dirs(self._map)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   517
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   518
    ### code related to manipulation of entries and copy-sources
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   519
49102
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   520
    def reset_state(
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   521
        self,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   522
        filename,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   523
        wc_tracked=False,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   524
        p1_tracked=False,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   525
        p2_info=False,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   526
        has_meaningful_mtime=True,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   527
        parentfiledata=None,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   528
    ):
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   529
        """Set a entry to a given state, diregarding all previous state
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   530
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   531
        This is to be used by the part of the dirstate API dedicated to
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   532
        adjusting the dirstate after a update/merge.
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   533
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   534
        note: calling this might result to no entry existing at all if the
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   535
        dirstate map does not see any point at having one for this file
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   536
        anymore.
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   537
        """
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   538
        # copy information are now outdated
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   539
        # (maybe new information should be in directly passed to this function)
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   540
        self.copymap.pop(filename, None)
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   541
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   542
        if not (p1_tracked or p2_info or wc_tracked):
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   543
            old_entry = self._map.get(filename)
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   544
            self._drop_entry(filename)
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   545
            self._dirs_decr(filename, old_entry=old_entry)
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   546
            return
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   547
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   548
        old_entry = self._map.get(filename)
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   549
        self._dirs_incr(filename, old_entry)
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   550
        entry = DirstateItem(
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   551
            wc_tracked=wc_tracked,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   552
            p1_tracked=p1_tracked,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   553
            p2_info=p2_info,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   554
            has_meaningful_mtime=has_meaningful_mtime,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   555
            parentfiledata=parentfiledata,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   556
        )
49103
77dfde417e5e dirstatemap: remove `_insert_entry`
Raphaël Gomès <rgomes@octobus.net>
parents: 49102
diff changeset
   557
        self._map[filename] = entry
49102
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   558
49098
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   559
    def set_tracked(self, filename):
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   560
        new = False
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   561
        entry = self.get(filename)
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   562
        if entry is None:
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   563
            self._dirs_incr(filename)
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   564
            entry = DirstateItem(
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   565
                wc_tracked=True,
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   566
            )
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   567
49103
77dfde417e5e dirstatemap: remove `_insert_entry`
Raphaël Gomès <rgomes@octobus.net>
parents: 49102
diff changeset
   568
            self._map[filename] = entry
49098
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   569
            new = True
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   570
        elif not entry.tracked:
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   571
            self._dirs_incr(filename, entry)
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   572
            entry.set_tracked()
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   573
            self._refresh_entry(filename, entry)
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   574
            new = True
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   575
        else:
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   576
            # XXX This is probably overkill for more case, but we need this to
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   577
            # fully replace the `normallookup` call with `set_tracked` one.
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   578
            # Consider smoothing this in the future.
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   579
            entry.set_possibly_dirty()
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   580
            self._refresh_entry(filename, entry)
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   581
        return new
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   582
49109
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   583
    def set_untracked(self, f):
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   584
        """Mark a file as no longer tracked in the dirstate map"""
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   585
        entry = self.get(f)
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   586
        if entry is None:
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   587
            return False
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   588
        else:
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   589
            self._dirs_decr(f, old_entry=entry, remove_variant=not entry.added)
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   590
            if not entry.p2_info:
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   591
                self.copymap.pop(f, None)
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   592
            entry.set_untracked()
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   593
            self._refresh_entry(f, entry)
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   594
            return True
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   595
49105
a69ea5a3c5a5 dirstatemap: move `set_clean` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49103
diff changeset
   596
    def set_clean(self, filename, mode, size, mtime):
a69ea5a3c5a5 dirstatemap: move `set_clean` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49103
diff changeset
   597
        """mark a file as back to a clean state"""
a69ea5a3c5a5 dirstatemap: move `set_clean` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49103
diff changeset
   598
        entry = self[filename]
a69ea5a3c5a5 dirstatemap: move `set_clean` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49103
diff changeset
   599
        size = size & rangemask
a69ea5a3c5a5 dirstatemap: move `set_clean` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49103
diff changeset
   600
        entry.set_clean(mode, size, mtime)
a69ea5a3c5a5 dirstatemap: move `set_clean` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49103
diff changeset
   601
        self._refresh_entry(filename, entry)
a69ea5a3c5a5 dirstatemap: move `set_clean` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49103
diff changeset
   602
        self.copymap.pop(filename, None)
a69ea5a3c5a5 dirstatemap: move `set_clean` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49103
diff changeset
   603
49107
079aaf996eca dirstatemap: move `set_possibly_dirty` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49105
diff changeset
   604
    def set_possibly_dirty(self, filename):
079aaf996eca dirstatemap: move `set_possibly_dirty` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49105
diff changeset
   605
        """record that the current state of the file on disk is unknown"""
079aaf996eca dirstatemap: move `set_possibly_dirty` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49105
diff changeset
   606
        entry = self[filename]
079aaf996eca dirstatemap: move `set_possibly_dirty` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49105
diff changeset
   607
        entry.set_possibly_dirty()
079aaf996eca dirstatemap: move `set_possibly_dirty` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49105
diff changeset
   608
        self._refresh_entry(filename, entry)
079aaf996eca dirstatemap: move `set_possibly_dirty` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49105
diff changeset
   609
48126
a1a6569b9283 dirstatemap: add a common `_refresh_entry` method for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48125
diff changeset
   610
    def _refresh_entry(self, f, entry):
49117
4c562108384f dirstatemap: move `_refresh_entry` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49116
diff changeset
   611
        """record updated state of an entry"""
48126
a1a6569b9283 dirstatemap: add a common `_refresh_entry` method for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48125
diff changeset
   612
        if not entry.any_tracked:
a1a6569b9283 dirstatemap: add a common `_refresh_entry` method for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48125
diff changeset
   613
            self._map.pop(f, None)
a1a6569b9283 dirstatemap: add a common `_refresh_entry` method for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48125
diff changeset
   614
48132
c057d7c97b72 dirstatemap: add a common `_drop_entry` method for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48131
diff changeset
   615
    def _drop_entry(self, f):
49116
cebb263c865c dirstatemap: move `_drop_entry` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49115
diff changeset
   616
        """remove any entry for file f
cebb263c865c dirstatemap: move `_drop_entry` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49115
diff changeset
   617
cebb263c865c dirstatemap: move `_drop_entry` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49115
diff changeset
   618
        This should also drop associated copy information
cebb263c865c dirstatemap: move `_drop_entry` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49115
diff changeset
   619
cebb263c865c dirstatemap: move `_drop_entry` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49115
diff changeset
   620
        The fact we actually need to drop it is the responsability of the caller"""
48132
c057d7c97b72 dirstatemap: add a common `_drop_entry` method for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48131
diff changeset
   621
        self._map.pop(f, None)
48133
55293938b843 dirstatemap: use a common implement for reset_state
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48132
diff changeset
   622
        self.copymap.pop(f, None)
48132
c057d7c97b72 dirstatemap: add a common `_drop_entry` method for dirstatemap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48131
diff changeset
   623
42755
749ef8c31187 rust-dirstate: call rust dirstatemap from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42747
diff changeset
   624
749ef8c31187 rust-dirstate: call rust dirstatemap from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42747
diff changeset
   625
if rustmod is not None:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42927
diff changeset
   626
48119
aec5b0981c26 dirstatemap: introduce a common base for the dirstatemap class
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48109
diff changeset
   627
    class dirstatemap(_dirstatemapcommon):
42755
749ef8c31187 rust-dirstate: call rust dirstatemap from Python
Raphaël Gomès <rgomes@octobus.net>
parents: 42747
diff changeset
   628
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   629
        ### Core data storage and access
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   630
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   631
        @propertycache
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   632
        def _map(self):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   633
            """
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   634
            Fills the Dirstatemap when called.
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   635
            """
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   636
            # ignore HG_PENDING because identity is used only for writing
50241
342c3c4640b7 dirstate: factor the identity setting code in the dirstate map
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50238
diff changeset
   637
            self._set_identity()
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   638
50228
fc8e37c380d3 dirstate: add a synchronisation point before doing a full dirstate read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50222
diff changeset
   639
            testing.wait_on_cfg(self._ui, b'dirstate.pre-read-file')
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   640
            if self._use_dirstate_v2:
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   641
                try:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   642
                    self.docket
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   643
                except error.CorruptedDirstate as e:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   644
                    # fall back to dirstate-v1 if we fail to read v2
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   645
                    parents = self._v1_map(e)
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   646
                else:
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   647
                    parents = self.docket.parents
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   648
                    inode = (
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   649
                        self.identity.stat.st_ino
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   650
                        if self.identity is not None
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   651
                        and self.identity.stat is not None
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   652
                        else None
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   653
                    )
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   654
                    testing.wait_on_cfg(
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   655
                        self._ui, b'dirstate.post-docket-read-file'
50243
6cce0afc1454 rust-dirstate: remember the data file uuid dirstate was loaded with
Raphaël Gomès <rgomes@octobus.net>
parents: 50242
diff changeset
   656
                    )
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   657
                    if not self.docket.uuid:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   658
                        data = b''
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   659
                        self._map = rustmod.DirstateMap.new_empty()
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   660
                    else:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   661
                        data = self._read_v2_data()
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   662
                        self._map = rustmod.DirstateMap.new_v2(
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   663
                            data,
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   664
                            self.docket.data_size,
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   665
                            self.docket.tree_metadata,
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   666
                            self.docket.uuid,
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   667
                            inode,
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   668
                        )
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   669
                    parents = self.docket.parents
48051
98c0408324e6 dirstate: Pass the final DirstateItem to _rustmap.addfile()
Simon Sapin <simon.sapin@octobus.net>
parents: 48050
diff changeset
   670
            else:
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   671
                parents = self._v1_map()
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   672
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   673
            if parents and not self._dirtyparents:
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   674
                self.setparents(*parents)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   675
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   676
            self.__contains__ = self._map.__contains__
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   677
            self.__getitem__ = self._map.__getitem__
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   678
            self.get = self._map.get
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   679
            return self._map
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   680
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   681
        def _v1_map(self, from_v2_exception=None):
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   682
            self._set_identity()
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   683
            inode = (
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   684
                self.identity.stat.st_ino
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   685
                if self.identity is not None and self.identity.stat is not None
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   686
                else None
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   687
            )
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   688
            try:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   689
                self._map, parents = rustmod.DirstateMap.new_v1(
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   690
                    self._readdirstatefile(), inode
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   691
                )
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   692
            except OSError as e:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   693
                if from_v2_exception is not None:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   694
                    raise e from from_v2_exception
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   695
                raise
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   696
            return parents
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   697
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   698
        @property
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   699
        def copymap(self):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   700
            return self._map.copymap()
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   701
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   702
        def debug_iter(self, all):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   703
            """
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   704
            Return an iterator of (filename, state, mode, size, mtime) tuples
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   705
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   706
            `all`: also include with `state == b' '` dirstate tree nodes that
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   707
            don't have an associated `DirstateItem`.
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   708
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   709
            """
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   710
            return self._map.debug_iter(all)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   711
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   712
        def clear(self):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   713
            self._map.clear()
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   714
            self.setparents(
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   715
                self._nodeconstants.nullid, self._nodeconstants.nullid
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   716
            )
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   717
            util.clearcachedproperty(self, b"_dirs")
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   718
            util.clearcachedproperty(self, b"_alldirs")
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   719
            util.clearcachedproperty(self, b"dirfoldmap")
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   720
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   721
        def items(self):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   722
            return self._map.items()
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   723
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   724
        # forward for python2,3 compat
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   725
        iteritems = items
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   726
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   727
        def keys(self):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   728
            return iter(self._map)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   729
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   730
        ### reading/setting parents
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   731
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   732
        def setparents(self, p1, p2, fold_p2=False):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   733
            self._parents = (p1, p2)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   734
            self._dirtyparents = True
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   735
            copies = {}
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   736
            if fold_p2:
49120
3df46f3a3d6c rust-dirstatemap: implement part of the `setparents` logic
Raphaël Gomès <rgomes@octobus.net>
parents: 49118
diff changeset
   737
                copies = self._map.setparents_fixup()
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   738
            return copies
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   739
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   740
        ### disk interaction
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   741
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   742
        @propertycache
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   743
        def identity(self):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   744
            self._map
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   745
            return self.identity
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   746
48393
1a8a70b4b0ad dirstate: cleanup remaining of "now" during write
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48392
diff changeset
   747
        def write(self, tr, st):
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   748
            if not self._use_dirstate_v2:
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   749
                p1, p2 = self.parents()
48392
434de12918fd dirstate: remove need_delay logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48260
diff changeset
   750
                packed = self._map.write_v1(p1, p2)
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   751
                st.write(packed)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   752
                st.close()
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   753
                self._dirtyparents = False
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   754
                return
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   755
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   756
            write_mode = self._write_mode
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   757
            try:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   758
                docket = self.docket
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   759
            except error.CorruptedDirstate:
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   760
                # fall back to dirstate-v1 if we fail to parse v2
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   761
                docket = None
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   762
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   763
            # We can only append to an existing data file if there is one
50660
bf16ef96defe rust-dirstate: fall back to v1 if reading v2 failed
Raphaël Gomès <rgomes@octobus.net>
parents: 50252
diff changeset
   764
            if docket is None or docket.uuid is None:
50221
1891086f6c7f dirstate: use more than a bool to control append behavior
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50097
diff changeset
   765
                write_mode = WRITE_MODE_FORCE_NEW
1891086f6c7f dirstate: use more than a bool to control append behavior
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50097
diff changeset
   766
            packed, meta, append = self._map.write_v2(write_mode)
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   767
            if append:
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   768
                docket = self.docket
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   769
                data_filename = docket.data_filename()
50081
9a0778bbae6a dirstate: explicitly backup the datafile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49619
diff changeset
   770
                # We mark it for backup to make sure a future `hg rollback` (or
9a0778bbae6a dirstate: explicitly backup the datafile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49619
diff changeset
   771
                # `hg recover`?) call find the data it needs to restore a
9a0778bbae6a dirstate: explicitly backup the datafile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49619
diff changeset
   772
                # working repository.
9a0778bbae6a dirstate: explicitly backup the datafile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49619
diff changeset
   773
                #
9a0778bbae6a dirstate: explicitly backup the datafile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49619
diff changeset
   774
                # The backup can use a hardlink because the format is resistant
9a0778bbae6a dirstate: explicitly backup the datafile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49619
diff changeset
   775
                # to trailing "dead" data.
9a0778bbae6a dirstate: explicitly backup the datafile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49619
diff changeset
   776
                if tr is not None:
9a0778bbae6a dirstate: explicitly backup the datafile
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49619
diff changeset
   777
                    tr.addbackup(data_filename, location=b'plain')
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   778
                with self._opener(data_filename, b'r+b') as fp:
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   779
                    fp.seek(docket.data_size)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   780
                    assert fp.tell() == docket.data_size
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   781
                    written = fp.write(packed)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   782
                    if written is not None:  # py2 may return None
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   783
                        assert written == len(packed), (written, len(packed))
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   784
                docket.data_size += len(packed)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   785
                docket.parents = self.parents()
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   786
                docket.tree_metadata = meta
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   787
                st.write(docket.serialize())
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   788
                st.close()
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   789
            else:
48220
e7b5e8ba7cab dirstate: Move more methods to the _dirstatemapcommon base class
Simon Sapin <simon.sapin@octobus.net>
parents: 48151
diff changeset
   790
                self.write_v2_no_append(tr, st, meta, packed)
48123
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   791
            # Reload from the newly-written file
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   792
            util.clearcachedproperty(self, b"_map")
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   793
            self._dirtyparents = False
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   794
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   795
        ### code related to maintaining and accessing "extra" property
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   796
        # (e.g. "has_dir")
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   797
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   798
        @propertycache
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   799
        def filefoldmap(self):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   800
            """Returns a dictionary mapping normalized case paths to their
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   801
            non-normalized versions.
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   802
            """
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   803
            return self._map.filefoldmapasdict()
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   804
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   805
        def hastrackeddir(self, d):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   806
            return self._map.hastrackeddir(d)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   807
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   808
        def hasdir(self, d):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   809
            return self._map.hasdir(d)
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   810
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   811
        @propertycache
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   812
        def dirfoldmap(self):
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   813
            f = {}
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   814
            normcase = util.normcase
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   815
            for name in self._map.tracked_dirs():
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   816
                f[normcase(name)] = name
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   817
            return f
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   818
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   819
        ### code related to manipulation of entries and copy-sources
771c90807a2b dirstatemap: arrange methods by category
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48122
diff changeset
   820
49098
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   821
        def set_tracked(self, f):
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   822
            return self._map.set_tracked(f)
55c158a33fa5 dirstatemap: move `set_tracked` out of common methods and plug in Rust
Raphaël Gomès <rgomes@octobus.net>
parents: 49040
diff changeset
   823
49109
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   824
        def set_untracked(self, f):
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   825
            return self._map.set_untracked(f)
953b08a2d983 dirstatemap: move `set_untracked` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49107
diff changeset
   826
49105
a69ea5a3c5a5 dirstatemap: move `set_clean` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49103
diff changeset
   827
        def set_clean(self, filename, mode, size, mtime):
a69ea5a3c5a5 dirstatemap: move `set_clean` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49103
diff changeset
   828
            self._map.set_clean(filename, mode, size, mtime)
a69ea5a3c5a5 dirstatemap: move `set_clean` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49103
diff changeset
   829
49107
079aaf996eca dirstatemap: move `set_possibly_dirty` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49105
diff changeset
   830
        def set_possibly_dirty(self, f):
079aaf996eca dirstatemap: move `set_possibly_dirty` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49105
diff changeset
   831
            self._map.set_possibly_dirty(f)
079aaf996eca dirstatemap: move `set_possibly_dirty` out of the common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49105
diff changeset
   832
49102
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   833
        def reset_state(
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   834
            self,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   835
            filename,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   836
            wc_tracked=False,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   837
            p1_tracked=False,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   838
            p2_info=False,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   839
            has_meaningful_mtime=True,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   840
            parentfiledata=None,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   841
        ):
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   842
            return self._map.reset_state(
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   843
                filename,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   844
                wc_tracked,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   845
                p1_tracked,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   846
                p2_info,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   847
                has_meaningful_mtime,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   848
                parentfiledata,
358b1a1e3678 dirstatemap: move `reset_state` out of common methods
Raphaël Gomès <rgomes@octobus.net>
parents: 49099
diff changeset
   849
            )