mercurial/dirstatemap.py
author Raphaël Gomès <rgomes@octobus.net>
Wed, 09 Aug 2023 15:46:35 +0200
changeset 50983 8343947af6a7
parent 50928 d718eddf01d9
child 51690 493034cc3265
permissions -rw-r--r--
rust-config: fix incorrect coercion of null values to false As explained in the previous changeset: Probably being too trigger happy about boolean values, I incorrectly set the transform for a `None` to a `Some(false)`. It would cause for example the `ui.formatted` value to be set to `Some(false)`, which turns off the colors among other things, when `None` would trigger the automatic behavior.
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
            )