##// END OF EJS Templates
interfaces: convert `repository.ifilestorage` to a Protocol class...
Matt Harbison -
r53385:8c89e978 default
parent child Browse files
Show More
@@ -1,2286 +1,2317
1 # repository.py - Interfaces and base classes for repositories and peers.
1 # repository.py - Interfaces and base classes for repositories and peers.
2 # coding: utf-8
2 # coding: utf-8
3 #
3 #
4 # Copyright 2017 Gregory Szorc <gregory.szorc@gmail.com>
4 # Copyright 2017 Gregory Szorc <gregory.szorc@gmail.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 from __future__ import annotations
9 from __future__ import annotations
10
10
11 import abc
11 import abc
12 import typing
12 import typing
13
13
14 from typing import (
14 from typing import (
15 Any,
15 Any,
16 Callable,
16 Callable,
17 Collection,
17 Collection,
18 Iterable,
18 Iterable,
19 Iterator,
19 Iterator,
20 Mapping,
20 Mapping,
21 Protocol,
21 Protocol,
22 )
22 )
23
23
24 from ..i18n import _
24 from ..i18n import _
25 from .. import error
25 from .. import error
26
26
27 if typing.TYPE_CHECKING:
27 if typing.TYPE_CHECKING:
28 # Almost all mercurial modules are only imported in the type checking phase
28 # Almost all mercurial modules are only imported in the type checking phase
29 # to avoid circular imports
29 # to avoid circular imports
30 from .. import (
30 from .. import (
31 util,
31 util,
32 )
32 )
33 from ..utils import (
33 from ..utils import (
34 urlutil,
34 urlutil,
35 )
35 )
36
36
37 from . import dirstate as intdirstate
37 from . import dirstate as intdirstate
38
38
39 # TODO: make a protocol class for this
39 # TODO: make a protocol class for this
40 NodeConstants = Any
40 NodeConstants = Any
41
41
42 # TODO: create a Protocol class, since importing uimod here causes a cycle
42 # TODO: create a Protocol class, since importing uimod here causes a cycle
43 # that confuses pytype.
43 # that confuses pytype.
44 Ui = Any
44 Ui = Any
45
45
46 # TODO: make a protocol class for this
46 # TODO: make a protocol class for this
47 Vfs = Any
47 Vfs = Any
48
48
49 # Local repository feature string.
49 # Local repository feature string.
50
50
51 # Revlogs are being used for file storage.
51 # Revlogs are being used for file storage.
52 REPO_FEATURE_REVLOG_FILE_STORAGE = b'revlogfilestorage'
52 REPO_FEATURE_REVLOG_FILE_STORAGE = b'revlogfilestorage'
53 # The storage part of the repository is shared from an external source.
53 # The storage part of the repository is shared from an external source.
54 REPO_FEATURE_SHARED_STORAGE = b'sharedstore'
54 REPO_FEATURE_SHARED_STORAGE = b'sharedstore'
55 # LFS supported for backing file storage.
55 # LFS supported for backing file storage.
56 REPO_FEATURE_LFS = b'lfs'
56 REPO_FEATURE_LFS = b'lfs'
57 # Repository supports being stream cloned.
57 # Repository supports being stream cloned.
58 REPO_FEATURE_STREAM_CLONE = b'streamclone'
58 REPO_FEATURE_STREAM_CLONE = b'streamclone'
59 # Repository supports (at least) some sidedata to be stored
59 # Repository supports (at least) some sidedata to be stored
60 REPO_FEATURE_SIDE_DATA = b'side-data'
60 REPO_FEATURE_SIDE_DATA = b'side-data'
61 # Files storage may lack data for all ancestors.
61 # Files storage may lack data for all ancestors.
62 REPO_FEATURE_SHALLOW_FILE_STORAGE = b'shallowfilestorage'
62 REPO_FEATURE_SHALLOW_FILE_STORAGE = b'shallowfilestorage'
63
63
64 REVISION_FLAG_CENSORED = 1 << 15
64 REVISION_FLAG_CENSORED = 1 << 15
65 REVISION_FLAG_ELLIPSIS = 1 << 14
65 REVISION_FLAG_ELLIPSIS = 1 << 14
66 REVISION_FLAG_EXTSTORED = 1 << 13
66 REVISION_FLAG_EXTSTORED = 1 << 13
67 REVISION_FLAG_HASCOPIESINFO = 1 << 12
67 REVISION_FLAG_HASCOPIESINFO = 1 << 12
68
68
69 REVISION_FLAGS_KNOWN = (
69 REVISION_FLAGS_KNOWN = (
70 REVISION_FLAG_CENSORED
70 REVISION_FLAG_CENSORED
71 | REVISION_FLAG_ELLIPSIS
71 | REVISION_FLAG_ELLIPSIS
72 | REVISION_FLAG_EXTSTORED
72 | REVISION_FLAG_EXTSTORED
73 | REVISION_FLAG_HASCOPIESINFO
73 | REVISION_FLAG_HASCOPIESINFO
74 )
74 )
75
75
76 CG_DELTAMODE_STD = b'default'
76 CG_DELTAMODE_STD = b'default'
77 CG_DELTAMODE_PREV = b'previous'
77 CG_DELTAMODE_PREV = b'previous'
78 CG_DELTAMODE_FULL = b'fulltext'
78 CG_DELTAMODE_FULL = b'fulltext'
79 CG_DELTAMODE_P1 = b'p1'
79 CG_DELTAMODE_P1 = b'p1'
80
80
81
81
82 ## Cache related constants:
82 ## Cache related constants:
83 #
83 #
84 # Used to control which cache should be warmed in a repo.updatecaches(…) call.
84 # Used to control which cache should be warmed in a repo.updatecaches(…) call.
85
85
86 # Warm branchmaps of all known repoview's filter-level
86 # Warm branchmaps of all known repoview's filter-level
87 CACHE_BRANCHMAP_ALL = b"branchmap-all"
87 CACHE_BRANCHMAP_ALL = b"branchmap-all"
88 # Warm branchmaps of repoview's filter-level used by server
88 # Warm branchmaps of repoview's filter-level used by server
89 CACHE_BRANCHMAP_SERVED = b"branchmap-served"
89 CACHE_BRANCHMAP_SERVED = b"branchmap-served"
90 # Warm internal changelog cache (eg: persistent nodemap)
90 # Warm internal changelog cache (eg: persistent nodemap)
91 CACHE_CHANGELOG_CACHE = b"changelog-cache"
91 CACHE_CHANGELOG_CACHE = b"changelog-cache"
92 # check of a branchmap can use the "pure topo" mode
92 # check of a branchmap can use the "pure topo" mode
93 CACHE_BRANCHMAP_DETECT_PURE_TOPO = b"branchmap-detect-pure-topo"
93 CACHE_BRANCHMAP_DETECT_PURE_TOPO = b"branchmap-detect-pure-topo"
94 # Warm full manifest cache
94 # Warm full manifest cache
95 CACHE_FULL_MANIFEST = b"full-manifest"
95 CACHE_FULL_MANIFEST = b"full-manifest"
96 # Warm file-node-tags cache
96 # Warm file-node-tags cache
97 CACHE_FILE_NODE_TAGS = b"file-node-tags"
97 CACHE_FILE_NODE_TAGS = b"file-node-tags"
98 # Warm internal manifestlog cache (eg: persistent nodemap)
98 # Warm internal manifestlog cache (eg: persistent nodemap)
99 CACHE_MANIFESTLOG_CACHE = b"manifestlog-cache"
99 CACHE_MANIFESTLOG_CACHE = b"manifestlog-cache"
100 # Warn rev branch cache
100 # Warn rev branch cache
101 CACHE_REV_BRANCH = b"rev-branch-cache"
101 CACHE_REV_BRANCH = b"rev-branch-cache"
102 # Warm tags' cache for default repoview'
102 # Warm tags' cache for default repoview'
103 CACHE_TAGS_DEFAULT = b"tags-default"
103 CACHE_TAGS_DEFAULT = b"tags-default"
104 # Warm tags' cache for repoview's filter-level used by server
104 # Warm tags' cache for repoview's filter-level used by server
105 CACHE_TAGS_SERVED = b"tags-served"
105 CACHE_TAGS_SERVED = b"tags-served"
106
106
107 # the cache to warm by default after a simple transaction
107 # the cache to warm by default after a simple transaction
108 # (this is a mutable set to let extension update it)
108 # (this is a mutable set to let extension update it)
109 CACHES_DEFAULT = {
109 CACHES_DEFAULT = {
110 CACHE_BRANCHMAP_SERVED,
110 CACHE_BRANCHMAP_SERVED,
111 }
111 }
112
112
113 # the caches to warm when warming all of them
113 # the caches to warm when warming all of them
114 # (this is a mutable set to let extension update it)
114 # (this is a mutable set to let extension update it)
115 CACHES_ALL = {
115 CACHES_ALL = {
116 CACHE_BRANCHMAP_SERVED,
116 CACHE_BRANCHMAP_SERVED,
117 CACHE_BRANCHMAP_ALL,
117 CACHE_BRANCHMAP_ALL,
118 CACHE_BRANCHMAP_DETECT_PURE_TOPO,
118 CACHE_BRANCHMAP_DETECT_PURE_TOPO,
119 CACHE_REV_BRANCH,
119 CACHE_REV_BRANCH,
120 CACHE_CHANGELOG_CACHE,
120 CACHE_CHANGELOG_CACHE,
121 CACHE_FILE_NODE_TAGS,
121 CACHE_FILE_NODE_TAGS,
122 CACHE_FULL_MANIFEST,
122 CACHE_FULL_MANIFEST,
123 CACHE_MANIFESTLOG_CACHE,
123 CACHE_MANIFESTLOG_CACHE,
124 CACHE_TAGS_DEFAULT,
124 CACHE_TAGS_DEFAULT,
125 CACHE_TAGS_SERVED,
125 CACHE_TAGS_SERVED,
126 }
126 }
127
127
128 # the cache to warm by default on simple call
128 # the cache to warm by default on simple call
129 # (this is a mutable set to let extension update it)
129 # (this is a mutable set to let extension update it)
130 CACHES_POST_CLONE = CACHES_ALL.copy()
130 CACHES_POST_CLONE = CACHES_ALL.copy()
131 CACHES_POST_CLONE.discard(CACHE_FILE_NODE_TAGS)
131 CACHES_POST_CLONE.discard(CACHE_FILE_NODE_TAGS)
132 CACHES_POST_CLONE.discard(CACHE_REV_BRANCH)
132 CACHES_POST_CLONE.discard(CACHE_REV_BRANCH)
133
133
134
134
135 class _ipeerconnection(Protocol):
135 class _ipeerconnection(Protocol):
136 """Represents a "connection" to a repository.
136 """Represents a "connection" to a repository.
137
137
138 This is the base interface for representing a connection to a repository.
138 This is the base interface for representing a connection to a repository.
139 It holds basic properties and methods applicable to all peer types.
139 It holds basic properties and methods applicable to all peer types.
140
140
141 This is not a complete interface definition and should not be used
141 This is not a complete interface definition and should not be used
142 outside of this module.
142 outside of this module.
143 """
143 """
144
144
145 ui: Ui
145 ui: Ui
146 """ui.ui instance"""
146 """ui.ui instance"""
147
147
148 path: urlutil.path | None
148 path: urlutil.path | None
149 """a urlutil.path instance or None"""
149 """a urlutil.path instance or None"""
150
150
151 def url(self):
151 def url(self):
152 """Returns a URL string representing this peer.
152 """Returns a URL string representing this peer.
153
153
154 Currently, implementations expose the raw URL used to construct the
154 Currently, implementations expose the raw URL used to construct the
155 instance. It may contain credentials as part of the URL. The
155 instance. It may contain credentials as part of the URL. The
156 expectations of the value aren't well-defined and this could lead to
156 expectations of the value aren't well-defined and this could lead to
157 data leakage.
157 data leakage.
158
158
159 TODO audit/clean consumers and more clearly define the contents of this
159 TODO audit/clean consumers and more clearly define the contents of this
160 value.
160 value.
161 """
161 """
162
162
163 def local(self):
163 def local(self):
164 """Returns a local repository instance.
164 """Returns a local repository instance.
165
165
166 If the peer represents a local repository, returns an object that
166 If the peer represents a local repository, returns an object that
167 can be used to interface with it. Otherwise returns ``None``.
167 can be used to interface with it. Otherwise returns ``None``.
168 """
168 """
169
169
170 def canpush(self):
170 def canpush(self):
171 """Returns a boolean indicating if this peer can be pushed to."""
171 """Returns a boolean indicating if this peer can be pushed to."""
172
172
173 def close(self):
173 def close(self):
174 """Close the connection to this peer.
174 """Close the connection to this peer.
175
175
176 This is called when the peer will no longer be used. Resources
176 This is called when the peer will no longer be used. Resources
177 associated with the peer should be cleaned up.
177 associated with the peer should be cleaned up.
178 """
178 """
179
179
180
180
181 class ipeercapabilities(Protocol):
181 class ipeercapabilities(Protocol):
182 """Peer sub-interface related to capabilities."""
182 """Peer sub-interface related to capabilities."""
183
183
184 def capable(self, name):
184 def capable(self, name):
185 """Determine support for a named capability.
185 """Determine support for a named capability.
186
186
187 Returns ``False`` if capability not supported.
187 Returns ``False`` if capability not supported.
188
188
189 Returns ``True`` if boolean capability is supported. Returns a string
189 Returns ``True`` if boolean capability is supported. Returns a string
190 if capability support is non-boolean.
190 if capability support is non-boolean.
191
191
192 Capability strings may or may not map to wire protocol capabilities.
192 Capability strings may or may not map to wire protocol capabilities.
193 """
193 """
194
194
195 def requirecap(self, name, purpose):
195 def requirecap(self, name, purpose):
196 """Require a capability to be present.
196 """Require a capability to be present.
197
197
198 Raises a ``CapabilityError`` if the capability isn't present.
198 Raises a ``CapabilityError`` if the capability isn't present.
199 """
199 """
200
200
201
201
202 class ipeercommands(Protocol):
202 class ipeercommands(Protocol):
203 """Client-side interface for communicating over the wire protocol.
203 """Client-side interface for communicating over the wire protocol.
204
204
205 This interface is used as a gateway to the Mercurial wire protocol.
205 This interface is used as a gateway to the Mercurial wire protocol.
206 methods commonly call wire protocol commands of the same name.
206 methods commonly call wire protocol commands of the same name.
207 """
207 """
208
208
209 def branchmap(self):
209 def branchmap(self):
210 """Obtain heads in named branches.
210 """Obtain heads in named branches.
211
211
212 Returns a dict mapping branch name to an iterable of nodes that are
212 Returns a dict mapping branch name to an iterable of nodes that are
213 heads on that branch.
213 heads on that branch.
214 """
214 """
215
215
216 def capabilities(self):
216 def capabilities(self):
217 """Obtain capabilities of the peer.
217 """Obtain capabilities of the peer.
218
218
219 Returns a set of string capabilities.
219 Returns a set of string capabilities.
220 """
220 """
221
221
222 def get_cached_bundle_inline(self, path):
222 def get_cached_bundle_inline(self, path):
223 """Retrieve a clonebundle across the wire.
223 """Retrieve a clonebundle across the wire.
224
224
225 Returns a chunkbuffer
225 Returns a chunkbuffer
226 """
226 """
227
227
228 def clonebundles(self):
228 def clonebundles(self):
229 """Obtains the clone bundles manifest for the repo.
229 """Obtains the clone bundles manifest for the repo.
230
230
231 Returns the manifest as unparsed bytes.
231 Returns the manifest as unparsed bytes.
232 """
232 """
233
233
234 def debugwireargs(self, one, two, three=None, four=None, five=None):
234 def debugwireargs(self, one, two, three=None, four=None, five=None):
235 """Used to facilitate debugging of arguments passed over the wire."""
235 """Used to facilitate debugging of arguments passed over the wire."""
236
236
237 def getbundle(self, source, **kwargs):
237 def getbundle(self, source, **kwargs):
238 """Obtain remote repository data as a bundle.
238 """Obtain remote repository data as a bundle.
239
239
240 This command is how the bulk of repository data is transferred from
240 This command is how the bulk of repository data is transferred from
241 the peer to the local repository
241 the peer to the local repository
242
242
243 Returns a generator of bundle data.
243 Returns a generator of bundle data.
244 """
244 """
245
245
246 def heads(self):
246 def heads(self):
247 """Determine all known head revisions in the peer.
247 """Determine all known head revisions in the peer.
248
248
249 Returns an iterable of binary nodes.
249 Returns an iterable of binary nodes.
250 """
250 """
251
251
252 def known(self, nodes):
252 def known(self, nodes):
253 """Determine whether multiple nodes are known.
253 """Determine whether multiple nodes are known.
254
254
255 Accepts an iterable of nodes whose presence to check for.
255 Accepts an iterable of nodes whose presence to check for.
256
256
257 Returns an iterable of booleans indicating of the corresponding node
257 Returns an iterable of booleans indicating of the corresponding node
258 at that index is known to the peer.
258 at that index is known to the peer.
259 """
259 """
260
260
261 def listkeys(self, namespace):
261 def listkeys(self, namespace):
262 """Obtain all keys in a pushkey namespace.
262 """Obtain all keys in a pushkey namespace.
263
263
264 Returns an iterable of key names.
264 Returns an iterable of key names.
265 """
265 """
266
266
267 def lookup(self, key):
267 def lookup(self, key):
268 """Resolve a value to a known revision.
268 """Resolve a value to a known revision.
269
269
270 Returns a binary node of the resolved revision on success.
270 Returns a binary node of the resolved revision on success.
271 """
271 """
272
272
273 def pushkey(self, namespace, key, old, new):
273 def pushkey(self, namespace, key, old, new):
274 """Set a value using the ``pushkey`` protocol.
274 """Set a value using the ``pushkey`` protocol.
275
275
276 Arguments correspond to the pushkey namespace and key to operate on and
276 Arguments correspond to the pushkey namespace and key to operate on and
277 the old and new values for that key.
277 the old and new values for that key.
278
278
279 Returns a string with the peer result. The value inside varies by the
279 Returns a string with the peer result. The value inside varies by the
280 namespace.
280 namespace.
281 """
281 """
282
282
283 def stream_out(self):
283 def stream_out(self):
284 """Obtain streaming clone data.
284 """Obtain streaming clone data.
285
285
286 Successful result should be a generator of data chunks.
286 Successful result should be a generator of data chunks.
287 """
287 """
288
288
289 def unbundle(self, bundle, heads, url):
289 def unbundle(self, bundle, heads, url):
290 """Transfer repository data to the peer.
290 """Transfer repository data to the peer.
291
291
292 This is how the bulk of data during a push is transferred.
292 This is how the bulk of data during a push is transferred.
293
293
294 Returns the integer number of heads added to the peer.
294 Returns the integer number of heads added to the peer.
295 """
295 """
296
296
297
297
298 class ipeerlegacycommands(Protocol):
298 class ipeerlegacycommands(Protocol):
299 """Interface for implementing support for legacy wire protocol commands.
299 """Interface for implementing support for legacy wire protocol commands.
300
300
301 Wire protocol commands transition to legacy status when they are no longer
301 Wire protocol commands transition to legacy status when they are no longer
302 used by modern clients. To facilitate identifying which commands are
302 used by modern clients. To facilitate identifying which commands are
303 legacy, the interfaces are split.
303 legacy, the interfaces are split.
304 """
304 """
305
305
306 def between(self, pairs):
306 def between(self, pairs):
307 """Obtain nodes between pairs of nodes.
307 """Obtain nodes between pairs of nodes.
308
308
309 ``pairs`` is an iterable of node pairs.
309 ``pairs`` is an iterable of node pairs.
310
310
311 Returns an iterable of iterables of nodes corresponding to each
311 Returns an iterable of iterables of nodes corresponding to each
312 requested pair.
312 requested pair.
313 """
313 """
314
314
315 def branches(self, nodes):
315 def branches(self, nodes):
316 """Obtain ancestor changesets of specific nodes back to a branch point.
316 """Obtain ancestor changesets of specific nodes back to a branch point.
317
317
318 For each requested node, the peer finds the first ancestor node that is
318 For each requested node, the peer finds the first ancestor node that is
319 a DAG root or is a merge.
319 a DAG root or is a merge.
320
320
321 Returns an iterable of iterables with the resolved values for each node.
321 Returns an iterable of iterables with the resolved values for each node.
322 """
322 """
323
323
324 def changegroup(self, nodes, source):
324 def changegroup(self, nodes, source):
325 """Obtain a changegroup with data for descendants of specified nodes."""
325 """Obtain a changegroup with data for descendants of specified nodes."""
326
326
327 def changegroupsubset(self, bases, heads, source):
327 def changegroupsubset(self, bases, heads, source):
328 pass
328 pass
329
329
330
330
331 class ipeercommandexecutor(Protocol):
331 class ipeercommandexecutor(Protocol):
332 """Represents a mechanism to execute remote commands.
332 """Represents a mechanism to execute remote commands.
333
333
334 This is the primary interface for requesting that wire protocol commands
334 This is the primary interface for requesting that wire protocol commands
335 be executed. Instances of this interface are active in a context manager
335 be executed. Instances of this interface are active in a context manager
336 and have a well-defined lifetime. When the context manager exits, all
336 and have a well-defined lifetime. When the context manager exits, all
337 outstanding requests are waited on.
337 outstanding requests are waited on.
338 """
338 """
339
339
340 def callcommand(self, name, args):
340 def callcommand(self, name, args):
341 """Request that a named command be executed.
341 """Request that a named command be executed.
342
342
343 Receives the command name and a dictionary of command arguments.
343 Receives the command name and a dictionary of command arguments.
344
344
345 Returns a ``concurrent.futures.Future`` that will resolve to the
345 Returns a ``concurrent.futures.Future`` that will resolve to the
346 result of that command request. That exact value is left up to
346 result of that command request. That exact value is left up to
347 the implementation and possibly varies by command.
347 the implementation and possibly varies by command.
348
348
349 Not all commands can coexist with other commands in an executor
349 Not all commands can coexist with other commands in an executor
350 instance: it depends on the underlying wire protocol transport being
350 instance: it depends on the underlying wire protocol transport being
351 used and the command itself.
351 used and the command itself.
352
352
353 Implementations MAY call ``sendcommands()`` automatically if the
353 Implementations MAY call ``sendcommands()`` automatically if the
354 requested command can not coexist with other commands in this executor.
354 requested command can not coexist with other commands in this executor.
355
355
356 Implementations MAY call ``sendcommands()`` automatically when the
356 Implementations MAY call ``sendcommands()`` automatically when the
357 future's ``result()`` is called. So, consumers using multiple
357 future's ``result()`` is called. So, consumers using multiple
358 commands with an executor MUST ensure that ``result()`` is not called
358 commands with an executor MUST ensure that ``result()`` is not called
359 until all command requests have been issued.
359 until all command requests have been issued.
360 """
360 """
361
361
362 def sendcommands(self):
362 def sendcommands(self):
363 """Trigger submission of queued command requests.
363 """Trigger submission of queued command requests.
364
364
365 Not all transports submit commands as soon as they are requested to
365 Not all transports submit commands as soon as they are requested to
366 run. When called, this method forces queued command requests to be
366 run. When called, this method forces queued command requests to be
367 issued. It will no-op if all commands have already been sent.
367 issued. It will no-op if all commands have already been sent.
368
368
369 When called, no more new commands may be issued with this executor.
369 When called, no more new commands may be issued with this executor.
370 """
370 """
371
371
372 def close(self):
372 def close(self):
373 """Signal that this command request is finished.
373 """Signal that this command request is finished.
374
374
375 When called, no more new commands may be issued. All outstanding
375 When called, no more new commands may be issued. All outstanding
376 commands that have previously been issued are waited on before
376 commands that have previously been issued are waited on before
377 returning. This not only includes waiting for the futures to resolve,
377 returning. This not only includes waiting for the futures to resolve,
378 but also waiting for all response data to arrive. In other words,
378 but also waiting for all response data to arrive. In other words,
379 calling this waits for all on-wire state for issued command requests
379 calling this waits for all on-wire state for issued command requests
380 to finish.
380 to finish.
381
381
382 When used as a context manager, this method is called when exiting the
382 When used as a context manager, this method is called when exiting the
383 context manager.
383 context manager.
384
384
385 This method may call ``sendcommands()`` if there are buffered commands.
385 This method may call ``sendcommands()`` if there are buffered commands.
386 """
386 """
387
387
388
388
389 class ipeerrequests(Protocol):
389 class ipeerrequests(Protocol):
390 """Interface for executing commands on a peer."""
390 """Interface for executing commands on a peer."""
391
391
392 limitedarguments: bool
392 limitedarguments: bool
393 """True if the peer cannot receive large argument value for commands."""
393 """True if the peer cannot receive large argument value for commands."""
394
394
395 def commandexecutor(self):
395 def commandexecutor(self):
396 """A context manager that resolves to an ipeercommandexecutor.
396 """A context manager that resolves to an ipeercommandexecutor.
397
397
398 The object this resolves to can be used to issue command requests
398 The object this resolves to can be used to issue command requests
399 to the peer.
399 to the peer.
400
400
401 Callers should call its ``callcommand`` method to issue command
401 Callers should call its ``callcommand`` method to issue command
402 requests.
402 requests.
403
403
404 A new executor should be obtained for each distinct set of commands
404 A new executor should be obtained for each distinct set of commands
405 (possibly just a single command) that the consumer wants to execute
405 (possibly just a single command) that the consumer wants to execute
406 as part of a single operation or round trip. This is because some
406 as part of a single operation or round trip. This is because some
407 peers are half-duplex and/or don't support persistent connections.
407 peers are half-duplex and/or don't support persistent connections.
408 e.g. in the case of HTTP peers, commands sent to an executor represent
408 e.g. in the case of HTTP peers, commands sent to an executor represent
409 a single HTTP request. While some peers may support multiple command
409 a single HTTP request. While some peers may support multiple command
410 sends over the wire per executor, consumers need to code to the least
410 sends over the wire per executor, consumers need to code to the least
411 capable peer. So it should be assumed that command executors buffer
411 capable peer. So it should be assumed that command executors buffer
412 called commands until they are told to send them and that each
412 called commands until they are told to send them and that each
413 command executor could result in a new connection or wire-level request
413 command executor could result in a new connection or wire-level request
414 being issued.
414 being issued.
415 """
415 """
416
416
417
417
418 class peer(_ipeerconnection, ipeercapabilities, ipeerrequests, Protocol):
418 class peer(_ipeerconnection, ipeercapabilities, ipeerrequests, Protocol):
419 """Unified interface for peer repositories.
419 """Unified interface for peer repositories.
420
420
421 All peer instances must conform to this interface.
421 All peer instances must conform to this interface.
422 """
422 """
423
423
424 limitedarguments: bool = False
424 limitedarguments: bool = False
425
425
426 def __init__(self, ui, path=None, remotehidden=False):
426 def __init__(self, ui, path=None, remotehidden=False):
427 self.ui = ui
427 self.ui = ui
428 self.path = path
428 self.path = path
429
429
430 def capable(self, name):
430 def capable(self, name):
431 # TODO: this class should maybe subclass ipeercommands too, otherwise it
431 # TODO: this class should maybe subclass ipeercommands too, otherwise it
432 # is assuming whatever uses this as a mixin also has this interface.
432 # is assuming whatever uses this as a mixin also has this interface.
433 caps = self.capabilities() # pytype: disable=attribute-error
433 caps = self.capabilities() # pytype: disable=attribute-error
434 if name in caps:
434 if name in caps:
435 return True
435 return True
436
436
437 name = b'%s=' % name
437 name = b'%s=' % name
438 for cap in caps:
438 for cap in caps:
439 if cap.startswith(name):
439 if cap.startswith(name):
440 return cap[len(name) :]
440 return cap[len(name) :]
441
441
442 return False
442 return False
443
443
444 def requirecap(self, name, purpose):
444 def requirecap(self, name, purpose):
445 if self.capable(name):
445 if self.capable(name):
446 return
446 return
447
447
448 raise error.CapabilityError(
448 raise error.CapabilityError(
449 _(
449 _(
450 b'cannot %s; remote repository does not support the '
450 b'cannot %s; remote repository does not support the '
451 b'\'%s\' capability'
451 b'\'%s\' capability'
452 )
452 )
453 % (purpose, name)
453 % (purpose, name)
454 )
454 )
455
455
456
456
457 class iverifyproblem(Protocol):
457 class iverifyproblem(Protocol):
458 """Represents a problem with the integrity of the repository.
458 """Represents a problem with the integrity of the repository.
459
459
460 Instances of this interface are emitted to describe an integrity issue
460 Instances of this interface are emitted to describe an integrity issue
461 with a repository (e.g. corrupt storage, missing data, etc).
461 with a repository (e.g. corrupt storage, missing data, etc).
462
462
463 Instances are essentially messages associated with severity.
463 Instances are essentially messages associated with severity.
464 """
464 """
465
465
466 warning: bytes | None
466 warning: bytes | None
467 """Message indicating a non-fatal problem."""
467 """Message indicating a non-fatal problem."""
468
468
469 error: bytes | None
469 error: bytes | None
470 """Message indicating a fatal problem."""
470 """Message indicating a fatal problem."""
471
471
472 node: bytes | None
472 node: bytes | None
473 """Revision encountering the problem.
473 """Revision encountering the problem.
474
474
475 ``None`` means the problem doesn't apply to a single revision.
475 ``None`` means the problem doesn't apply to a single revision.
476 """
476 """
477
477
478
478
479 class irevisiondelta(Protocol):
479 class irevisiondelta(Protocol):
480 """Represents a delta between one revision and another.
480 """Represents a delta between one revision and another.
481
481
482 Instances convey enough information to allow a revision to be exchanged
482 Instances convey enough information to allow a revision to be exchanged
483 with another repository.
483 with another repository.
484
484
485 Instances represent the fulltext revision data or a delta against
485 Instances represent the fulltext revision data or a delta against
486 another revision. Therefore the ``revision`` and ``delta`` attributes
486 another revision. Therefore the ``revision`` and ``delta`` attributes
487 are mutually exclusive.
487 are mutually exclusive.
488
488
489 Typically used for changegroup generation.
489 Typically used for changegroup generation.
490 """
490 """
491
491
492 node: bytes
492 node: bytes
493 """20 byte node of this revision."""
493 """20 byte node of this revision."""
494
494
495 p1node: bytes
495 p1node: bytes
496 """20 byte node of 1st parent of this revision."""
496 """20 byte node of 1st parent of this revision."""
497
497
498 p2node: bytes
498 p2node: bytes
499 """20 byte node of 2nd parent of this revision."""
499 """20 byte node of 2nd parent of this revision."""
500
500
501 # TODO: is this really optional? revlog.revlogrevisiondelta defaults to None
501 # TODO: is this really optional? revlog.revlogrevisiondelta defaults to None
502 linknode: bytes | None
502 linknode: bytes | None
503 """20 byte node of the changelog revision this node is linked to."""
503 """20 byte node of the changelog revision this node is linked to."""
504
504
505 flags: int
505 flags: int
506 """2 bytes of integer flags that apply to this revision.
506 """2 bytes of integer flags that apply to this revision.
507
507
508 This is a bitwise composition of the ``REVISION_FLAG_*`` constants.
508 This is a bitwise composition of the ``REVISION_FLAG_*`` constants.
509 """
509 """
510
510
511 basenode: bytes
511 basenode: bytes
512 """20 byte node of the revision this data is a delta against.
512 """20 byte node of the revision this data is a delta against.
513
513
514 ``nullid`` indicates that the revision is a full revision and not
514 ``nullid`` indicates that the revision is a full revision and not
515 a delta.
515 a delta.
516 """
516 """
517
517
518 baserevisionsize: int | None
518 baserevisionsize: int | None
519 """Size of base revision this delta is against.
519 """Size of base revision this delta is against.
520
520
521 May be ``None`` if ``basenode`` is ``nullid``.
521 May be ``None`` if ``basenode`` is ``nullid``.
522 """
522 """
523
523
524 # TODO: is this really optional? (Seems possible in
524 # TODO: is this really optional? (Seems possible in
525 # storageutil.emitrevisions()).
525 # storageutil.emitrevisions()).
526 revision: bytes | None
526 revision: bytes | None
527 """Raw fulltext of revision data for this node."""
527 """Raw fulltext of revision data for this node."""
528
528
529 delta: bytes | None
529 delta: bytes | None
530 """Delta between ``basenode`` and ``node``.
530 """Delta between ``basenode`` and ``node``.
531
531
532 Stored in the bdiff delta format.
532 Stored in the bdiff delta format.
533 """
533 """
534
534
535 sidedata: bytes | None
535 sidedata: bytes | None
536 """Raw sidedata bytes for the given revision."""
536 """Raw sidedata bytes for the given revision."""
537
537
538 protocol_flags: int
538 protocol_flags: int
539 """Single byte of integer flags that can influence the protocol.
539 """Single byte of integer flags that can influence the protocol.
540
540
541 This is a bitwise composition of the ``storageutil.CG_FLAG*`` constants.
541 This is a bitwise composition of the ``storageutil.CG_FLAG*`` constants.
542 """
542 """
543
543
544
544
545 class ifilerevisionssequence(Protocol):
545 class ifilerevisionssequence(Protocol):
546 """Contains index data for all revisions of a file.
546 """Contains index data for all revisions of a file.
547
547
548 Types implementing this behave like lists of tuples. The index
548 Types implementing this behave like lists of tuples. The index
549 in the list corresponds to the revision number. The values contain
549 in the list corresponds to the revision number. The values contain
550 index metadata.
550 index metadata.
551
551
552 The *null* revision (revision number -1) is always the last item
552 The *null* revision (revision number -1) is always the last item
553 in the index.
553 in the index.
554 """
554 """
555
555
556 def __len__(self):
556 def __len__(self):
557 """The total number of revisions."""
557 """The total number of revisions."""
558
558
559 def __getitem__(self, rev):
559 def __getitem__(self, rev):
560 """Returns the object having a specific revision number.
560 """Returns the object having a specific revision number.
561
561
562 Returns an 8-tuple with the following fields:
562 Returns an 8-tuple with the following fields:
563
563
564 offset+flags
564 offset+flags
565 Contains the offset and flags for the revision. 64-bit unsigned
565 Contains the offset and flags for the revision. 64-bit unsigned
566 integer where first 6 bytes are the offset and the next 2 bytes
566 integer where first 6 bytes are the offset and the next 2 bytes
567 are flags. The offset can be 0 if it is not used by the store.
567 are flags. The offset can be 0 if it is not used by the store.
568 compressed size
568 compressed size
569 Size of the revision data in the store. It can be 0 if it isn't
569 Size of the revision data in the store. It can be 0 if it isn't
570 needed by the store.
570 needed by the store.
571 uncompressed size
571 uncompressed size
572 Fulltext size. It can be 0 if it isn't needed by the store.
572 Fulltext size. It can be 0 if it isn't needed by the store.
573 base revision
573 base revision
574 Revision number of revision the delta for storage is encoded
574 Revision number of revision the delta for storage is encoded
575 against. -1 indicates not encoded against a base revision.
575 against. -1 indicates not encoded against a base revision.
576 link revision
576 link revision
577 Revision number of changelog revision this entry is related to.
577 Revision number of changelog revision this entry is related to.
578 p1 revision
578 p1 revision
579 Revision number of 1st parent. -1 if no 1st parent.
579 Revision number of 1st parent. -1 if no 1st parent.
580 p2 revision
580 p2 revision
581 Revision number of 2nd parent. -1 if no 1st parent.
581 Revision number of 2nd parent. -1 if no 1st parent.
582 node
582 node
583 Binary node value for this revision number.
583 Binary node value for this revision number.
584
584
585 Negative values should index off the end of the sequence. ``-1``
585 Negative values should index off the end of the sequence. ``-1``
586 should return the null revision. ``-2`` should return the most
586 should return the null revision. ``-2`` should return the most
587 recent revision.
587 recent revision.
588 """
588 """
589
589
590 def __contains__(self, rev):
590 def __contains__(self, rev):
591 """Whether a revision number exists."""
591 """Whether a revision number exists."""
592
592
593 def insert(self, i, entry):
593 def insert(self, i, entry):
594 """Add an item to the index at specific revision."""
594 """Add an item to the index at specific revision."""
595
595
596
596
597 class ifileindex(Protocol):
597 class ifileindex(Protocol):
598 """Storage interface for index data of a single file.
598 """Storage interface for index data of a single file.
599
599
600 File storage data is divided into index metadata and data storage.
600 File storage data is divided into index metadata and data storage.
601 This interface defines the index portion of the interface.
601 This interface defines the index portion of the interface.
602
602
603 The index logically consists of:
603 The index logically consists of:
604
604
605 * A mapping between revision numbers and nodes.
605 * A mapping between revision numbers and nodes.
606 * DAG data (storing and querying the relationship between nodes).
606 * DAG data (storing and querying the relationship between nodes).
607 * Metadata to facilitate storage.
607 * Metadata to facilitate storage.
608 """
608 """
609
609
610 nullid: bytes
610 nullid: bytes
611 """node for the null revision for use as delta base."""
611 """node for the null revision for use as delta base."""
612
612
613 @abc.abstractmethod
613 def __len__(self) -> int:
614 def __len__(self) -> int:
614 """Obtain the number of revisions stored for this file."""
615 """Obtain the number of revisions stored for this file."""
615
616
617 @abc.abstractmethod
616 def __iter__(self) -> Iterator[int]:
618 def __iter__(self) -> Iterator[int]:
617 """Iterate over revision numbers for this file."""
619 """Iterate over revision numbers for this file."""
618
620
621 @abc.abstractmethod
619 def hasnode(self, node):
622 def hasnode(self, node):
620 """Returns a bool indicating if a node is known to this store.
623 """Returns a bool indicating if a node is known to this store.
621
624
622 Implementations must only return True for full, binary node values:
625 Implementations must only return True for full, binary node values:
623 hex nodes, revision numbers, and partial node matches must be
626 hex nodes, revision numbers, and partial node matches must be
624 rejected.
627 rejected.
625
628
626 The null node is never present.
629 The null node is never present.
627 """
630 """
628
631
632 @abc.abstractmethod
629 def revs(self, start=0, stop=None):
633 def revs(self, start=0, stop=None):
630 """Iterate over revision numbers for this file, with control."""
634 """Iterate over revision numbers for this file, with control."""
631
635
636 @abc.abstractmethod
632 def parents(self, node):
637 def parents(self, node):
633 """Returns a 2-tuple of parent nodes for a revision.
638 """Returns a 2-tuple of parent nodes for a revision.
634
639
635 Values will be ``nullid`` if the parent is empty.
640 Values will be ``nullid`` if the parent is empty.
636 """
641 """
637
642
643 @abc.abstractmethod
638 def parentrevs(self, rev):
644 def parentrevs(self, rev):
639 """Like parents() but operates on revision numbers."""
645 """Like parents() but operates on revision numbers."""
640
646
647 @abc.abstractmethod
641 def rev(self, node):
648 def rev(self, node):
642 """Obtain the revision number given a node.
649 """Obtain the revision number given a node.
643
650
644 Raises ``error.LookupError`` if the node is not known.
651 Raises ``error.LookupError`` if the node is not known.
645 """
652 """
646
653
654 @abc.abstractmethod
647 def node(self, rev):
655 def node(self, rev):
648 """Obtain the node value given a revision number.
656 """Obtain the node value given a revision number.
649
657
650 Raises ``IndexError`` if the node is not known.
658 Raises ``IndexError`` if the node is not known.
651 """
659 """
652
660
661 @abc.abstractmethod
653 def lookup(self, node):
662 def lookup(self, node):
654 """Attempt to resolve a value to a node.
663 """Attempt to resolve a value to a node.
655
664
656 Value can be a binary node, hex node, revision number, or a string
665 Value can be a binary node, hex node, revision number, or a string
657 that can be converted to an integer.
666 that can be converted to an integer.
658
667
659 Raises ``error.LookupError`` if a node could not be resolved.
668 Raises ``error.LookupError`` if a node could not be resolved.
660 """
669 """
661
670
671 @abc.abstractmethod
662 def linkrev(self, rev):
672 def linkrev(self, rev):
663 """Obtain the changeset revision number a revision is linked to."""
673 """Obtain the changeset revision number a revision is linked to."""
664
674
675 @abc.abstractmethod
665 def iscensored(self, rev):
676 def iscensored(self, rev):
666 """Return whether a revision's content has been censored."""
677 """Return whether a revision's content has been censored."""
667
678
679 @abc.abstractmethod
668 def commonancestorsheads(self, node1, node2):
680 def commonancestorsheads(self, node1, node2):
669 """Obtain an iterable of nodes containing heads of common ancestors.
681 """Obtain an iterable of nodes containing heads of common ancestors.
670
682
671 See ``ancestor.commonancestorsheads()``.
683 See ``ancestor.commonancestorsheads()``.
672 """
684 """
673
685
686 @abc.abstractmethod
674 def descendants(self, revs):
687 def descendants(self, revs):
675 """Obtain descendant revision numbers for a set of revision numbers.
688 """Obtain descendant revision numbers for a set of revision numbers.
676
689
677 If ``nullrev`` is in the set, this is equivalent to ``revs()``.
690 If ``nullrev`` is in the set, this is equivalent to ``revs()``.
678 """
691 """
679
692
693 @abc.abstractmethod
680 def heads(self, start=None, stop=None):
694 def heads(self, start=None, stop=None):
681 """Obtain a list of nodes that are DAG heads, with control.
695 """Obtain a list of nodes that are DAG heads, with control.
682
696
683 The set of revisions examined can be limited by specifying
697 The set of revisions examined can be limited by specifying
684 ``start`` and ``stop``. ``start`` is a node. ``stop`` is an
698 ``start`` and ``stop``. ``start`` is a node. ``stop`` is an
685 iterable of nodes. DAG traversal starts at earlier revision
699 iterable of nodes. DAG traversal starts at earlier revision
686 ``start`` and iterates forward until any node in ``stop`` is
700 ``start`` and iterates forward until any node in ``stop`` is
687 encountered.
701 encountered.
688 """
702 """
689
703
704 @abc.abstractmethod
690 def children(self, node):
705 def children(self, node):
691 """Obtain nodes that are children of a node.
706 """Obtain nodes that are children of a node.
692
707
693 Returns a list of nodes.
708 Returns a list of nodes.
694 """
709 """
695
710
696
711
697 class ifiledata(Protocol):
712 class ifiledata(Protocol):
698 """Storage interface for data storage of a specific file.
713 """Storage interface for data storage of a specific file.
699
714
700 This complements ``ifileindex`` and provides an interface for accessing
715 This complements ``ifileindex`` and provides an interface for accessing
701 data for a tracked file.
716 data for a tracked file.
702 """
717 """
703
718
719 @abc.abstractmethod
704 def size(self, rev):
720 def size(self, rev):
705 """Obtain the fulltext size of file data.
721 """Obtain the fulltext size of file data.
706
722
707 Any metadata is excluded from size measurements.
723 Any metadata is excluded from size measurements.
708 """
724 """
709
725
726 @abc.abstractmethod
710 def revision(self, node):
727 def revision(self, node):
711 """Obtain fulltext data for a node.
728 """Obtain fulltext data for a node.
712
729
713 By default, any storage transformations are applied before the data
730 By default, any storage transformations are applied before the data
714 is returned. If ``raw`` is True, non-raw storage transformations
731 is returned. If ``raw`` is True, non-raw storage transformations
715 are not applied.
732 are not applied.
716
733
717 The fulltext data may contain a header containing metadata. Most
734 The fulltext data may contain a header containing metadata. Most
718 consumers should use ``read()`` to obtain the actual file data.
735 consumers should use ``read()`` to obtain the actual file data.
719 """
736 """
720
737
738 @abc.abstractmethod
721 def rawdata(self, node):
739 def rawdata(self, node):
722 """Obtain raw data for a node."""
740 """Obtain raw data for a node."""
723
741
742 @abc.abstractmethod
724 def read(self, node):
743 def read(self, node):
725 """Resolve file fulltext data.
744 """Resolve file fulltext data.
726
745
727 This is similar to ``revision()`` except any metadata in the data
746 This is similar to ``revision()`` except any metadata in the data
728 headers is stripped.
747 headers is stripped.
729 """
748 """
730
749
750 @abc.abstractmethod
731 def renamed(self, node):
751 def renamed(self, node):
732 """Obtain copy metadata for a node.
752 """Obtain copy metadata for a node.
733
753
734 Returns ``False`` if no copy metadata is stored or a 2-tuple of
754 Returns ``False`` if no copy metadata is stored or a 2-tuple of
735 (path, node) from which this revision was copied.
755 (path, node) from which this revision was copied.
736 """
756 """
737
757
758 @abc.abstractmethod
738 def cmp(self, node, fulltext):
759 def cmp(self, node, fulltext):
739 """Compare fulltext to another revision.
760 """Compare fulltext to another revision.
740
761
741 Returns True if the fulltext is different from what is stored.
762 Returns True if the fulltext is different from what is stored.
742
763
743 This takes copy metadata into account.
764 This takes copy metadata into account.
744
765
745 TODO better document the copy metadata and censoring logic.
766 TODO better document the copy metadata and censoring logic.
746 """
767 """
747
768
769 @abc.abstractmethod
748 def emitrevisions(
770 def emitrevisions(
749 self,
771 self,
750 nodes,
772 nodes,
751 nodesorder=None,
773 nodesorder=None,
752 revisiondata=False,
774 revisiondata=False,
753 assumehaveparentrevisions=False,
775 assumehaveparentrevisions=False,
754 deltamode=CG_DELTAMODE_STD,
776 deltamode=CG_DELTAMODE_STD,
755 ):
777 ):
756 """Produce ``irevisiondelta`` for revisions.
778 """Produce ``irevisiondelta`` for revisions.
757
779
758 Given an iterable of nodes, emits objects conforming to the
780 Given an iterable of nodes, emits objects conforming to the
759 ``irevisiondelta`` interface that describe revisions in storage.
781 ``irevisiondelta`` interface that describe revisions in storage.
760
782
761 This method is a generator.
783 This method is a generator.
762
784
763 The input nodes may be unordered. Implementations must ensure that a
785 The input nodes may be unordered. Implementations must ensure that a
764 node's parents are emitted before the node itself. Transitively, this
786 node's parents are emitted before the node itself. Transitively, this
765 means that a node may only be emitted once all its ancestors in
787 means that a node may only be emitted once all its ancestors in
766 ``nodes`` have also been emitted.
788 ``nodes`` have also been emitted.
767
789
768 By default, emits "index" data (the ``node``, ``p1node``, and
790 By default, emits "index" data (the ``node``, ``p1node``, and
769 ``p2node`` attributes). If ``revisiondata`` is set, revision data
791 ``p2node`` attributes). If ``revisiondata`` is set, revision data
770 will also be present on the emitted objects.
792 will also be present on the emitted objects.
771
793
772 With default argument values, implementations can choose to emit
794 With default argument values, implementations can choose to emit
773 either fulltext revision data or a delta. When emitting deltas,
795 either fulltext revision data or a delta. When emitting deltas,
774 implementations must consider whether the delta's base revision
796 implementations must consider whether the delta's base revision
775 fulltext is available to the receiver.
797 fulltext is available to the receiver.
776
798
777 The base revision fulltext is guaranteed to be available if any of
799 The base revision fulltext is guaranteed to be available if any of
778 the following are met:
800 the following are met:
779
801
780 * Its fulltext revision was emitted by this method call.
802 * Its fulltext revision was emitted by this method call.
781 * A delta for that revision was emitted by this method call.
803 * A delta for that revision was emitted by this method call.
782 * ``assumehaveparentrevisions`` is True and the base revision is a
804 * ``assumehaveparentrevisions`` is True and the base revision is a
783 parent of the node.
805 parent of the node.
784
806
785 ``nodesorder`` can be used to control the order that revisions are
807 ``nodesorder`` can be used to control the order that revisions are
786 emitted. By default, revisions can be reordered as long as they are
808 emitted. By default, revisions can be reordered as long as they are
787 in DAG topological order (see above). If the value is ``nodes``,
809 in DAG topological order (see above). If the value is ``nodes``,
788 the iteration order from ``nodes`` should be used. If the value is
810 the iteration order from ``nodes`` should be used. If the value is
789 ``storage``, then the native order from the backing storage layer
811 ``storage``, then the native order from the backing storage layer
790 is used. (Not all storage layers will have strong ordering and behavior
812 is used. (Not all storage layers will have strong ordering and behavior
791 of this mode is storage-dependent.) ``nodes`` ordering can force
813 of this mode is storage-dependent.) ``nodes`` ordering can force
792 revisions to be emitted before their ancestors, so consumers should
814 revisions to be emitted before their ancestors, so consumers should
793 use it with care.
815 use it with care.
794
816
795 The ``linknode`` attribute on the returned ``irevisiondelta`` may not
817 The ``linknode`` attribute on the returned ``irevisiondelta`` may not
796 be set and it is the caller's responsibility to resolve it, if needed.
818 be set and it is the caller's responsibility to resolve it, if needed.
797
819
798 If ``deltamode`` is CG_DELTAMODE_PREV and revision data is requested,
820 If ``deltamode`` is CG_DELTAMODE_PREV and revision data is requested,
799 all revision data should be emitted as deltas against the revision
821 all revision data should be emitted as deltas against the revision
800 emitted just prior. The initial revision should be a delta against its
822 emitted just prior. The initial revision should be a delta against its
801 1st parent.
823 1st parent.
802 """
824 """
803
825
804
826
805 class ifilemutation(Protocol):
827 class ifilemutation(Protocol):
806 """Storage interface for mutation events of a tracked file."""
828 """Storage interface for mutation events of a tracked file."""
807
829
830 @abc.abstractmethod
808 def add(self, filedata, meta, transaction, linkrev, p1, p2):
831 def add(self, filedata, meta, transaction, linkrev, p1, p2):
809 """Add a new revision to the store.
832 """Add a new revision to the store.
810
833
811 Takes file data, dictionary of metadata, a transaction, linkrev,
834 Takes file data, dictionary of metadata, a transaction, linkrev,
812 and parent nodes.
835 and parent nodes.
813
836
814 Returns the node that was added.
837 Returns the node that was added.
815
838
816 May no-op if a revision matching the supplied data is already stored.
839 May no-op if a revision matching the supplied data is already stored.
817 """
840 """
818
841
842 @abc.abstractmethod
819 def addrevision(
843 def addrevision(
820 self,
844 self,
821 revisiondata,
845 revisiondata,
822 transaction,
846 transaction,
823 linkrev,
847 linkrev,
824 p1,
848 p1,
825 p2,
849 p2,
826 node=None,
850 node=None,
827 flags=0,
851 flags=0,
828 cachedelta=None,
852 cachedelta=None,
829 ):
853 ):
830 """Add a new revision to the store and return its number.
854 """Add a new revision to the store and return its number.
831
855
832 This is similar to ``add()`` except it operates at a lower level.
856 This is similar to ``add()`` except it operates at a lower level.
833
857
834 The data passed in already contains a metadata header, if any.
858 The data passed in already contains a metadata header, if any.
835
859
836 ``node`` and ``flags`` can be used to define the expected node and
860 ``node`` and ``flags`` can be used to define the expected node and
837 the flags to use with storage. ``flags`` is a bitwise value composed
861 the flags to use with storage. ``flags`` is a bitwise value composed
838 of the various ``REVISION_FLAG_*`` constants.
862 of the various ``REVISION_FLAG_*`` constants.
839
863
840 ``add()`` is usually called when adding files from e.g. the working
864 ``add()`` is usually called when adding files from e.g. the working
841 directory. ``addrevision()`` is often called by ``add()`` and for
865 directory. ``addrevision()`` is often called by ``add()`` and for
842 scenarios where revision data has already been computed, such as when
866 scenarios where revision data has already been computed, such as when
843 applying raw data from a peer repo.
867 applying raw data from a peer repo.
844 """
868 """
845
869
870 @abc.abstractmethod
846 def addgroup(
871 def addgroup(
847 self,
872 self,
848 deltas,
873 deltas,
849 linkmapper,
874 linkmapper,
850 transaction,
875 transaction,
851 addrevisioncb=None,
876 addrevisioncb=None,
852 duplicaterevisioncb=None,
877 duplicaterevisioncb=None,
853 maybemissingparents=False,
878 maybemissingparents=False,
854 ):
879 ):
855 """Process a series of deltas for storage.
880 """Process a series of deltas for storage.
856
881
857 ``deltas`` is an iterable of 7-tuples of
882 ``deltas`` is an iterable of 7-tuples of
858 (node, p1, p2, linknode, deltabase, delta, flags) defining revisions
883 (node, p1, p2, linknode, deltabase, delta, flags) defining revisions
859 to add.
884 to add.
860
885
861 The ``delta`` field contains ``mpatch`` data to apply to a base
886 The ``delta`` field contains ``mpatch`` data to apply to a base
862 revision, identified by ``deltabase``. The base node can be
887 revision, identified by ``deltabase``. The base node can be
863 ``nullid``, in which case the header from the delta can be ignored
888 ``nullid``, in which case the header from the delta can be ignored
864 and the delta used as the fulltext.
889 and the delta used as the fulltext.
865
890
866 ``alwayscache`` instructs the lower layers to cache the content of the
891 ``alwayscache`` instructs the lower layers to cache the content of the
867 newly added revision, even if it needs to be explicitly computed.
892 newly added revision, even if it needs to be explicitly computed.
868 This used to be the default when ``addrevisioncb`` was provided up to
893 This used to be the default when ``addrevisioncb`` was provided up to
869 Mercurial 5.8.
894 Mercurial 5.8.
870
895
871 ``addrevisioncb`` should be called for each new rev as it is committed.
896 ``addrevisioncb`` should be called for each new rev as it is committed.
872 ``duplicaterevisioncb`` should be called for all revs with a
897 ``duplicaterevisioncb`` should be called for all revs with a
873 pre-existing node.
898 pre-existing node.
874
899
875 ``maybemissingparents`` is a bool indicating whether the incoming
900 ``maybemissingparents`` is a bool indicating whether the incoming
876 data may reference parents/ancestor revisions that aren't present.
901 data may reference parents/ancestor revisions that aren't present.
877 This flag is set when receiving data into a "shallow" store that
902 This flag is set when receiving data into a "shallow" store that
878 doesn't hold all history.
903 doesn't hold all history.
879
904
880 Returns a list of nodes that were processed. A node will be in the list
905 Returns a list of nodes that were processed. A node will be in the list
881 even if it existed in the store previously.
906 even if it existed in the store previously.
882 """
907 """
883
908
909 @abc.abstractmethod
884 def censorrevision(self, tr, node, tombstone=b''):
910 def censorrevision(self, tr, node, tombstone=b''):
885 """Remove the content of a single revision.
911 """Remove the content of a single revision.
886
912
887 The specified ``node`` will have its content purged from storage.
913 The specified ``node`` will have its content purged from storage.
888 Future attempts to access the revision data for this node will
914 Future attempts to access the revision data for this node will
889 result in failure.
915 result in failure.
890
916
891 A ``tombstone`` message can optionally be stored. This message may be
917 A ``tombstone`` message can optionally be stored. This message may be
892 displayed to users when they attempt to access the missing revision
918 displayed to users when they attempt to access the missing revision
893 data.
919 data.
894
920
895 Storage backends may have stored deltas against the previous content
921 Storage backends may have stored deltas against the previous content
896 in this revision. As part of censoring a revision, these storage
922 in this revision. As part of censoring a revision, these storage
897 backends are expected to rewrite any internally stored deltas such
923 backends are expected to rewrite any internally stored deltas such
898 that they no longer reference the deleted content.
924 that they no longer reference the deleted content.
899 """
925 """
900
926
927 @abc.abstractmethod
901 def getstrippoint(self, minlink):
928 def getstrippoint(self, minlink):
902 """Find the minimum revision that must be stripped to strip a linkrev.
929 """Find the minimum revision that must be stripped to strip a linkrev.
903
930
904 Returns a 2-tuple containing the minimum revision number and a set
931 Returns a 2-tuple containing the minimum revision number and a set
905 of all revisions numbers that would be broken by this strip.
932 of all revisions numbers that would be broken by this strip.
906
933
907 TODO this is highly revlog centric and should be abstracted into
934 TODO this is highly revlog centric and should be abstracted into
908 a higher-level deletion API. ``repair.strip()`` relies on this.
935 a higher-level deletion API. ``repair.strip()`` relies on this.
909 """
936 """
910
937
938 @abc.abstractmethod
911 def strip(self, minlink, transaction):
939 def strip(self, minlink, transaction):
912 """Remove storage of items starting at a linkrev.
940 """Remove storage of items starting at a linkrev.
913
941
914 This uses ``getstrippoint()`` to determine the first node to remove.
942 This uses ``getstrippoint()`` to determine the first node to remove.
915 Then it effectively truncates storage for all revisions after that.
943 Then it effectively truncates storage for all revisions after that.
916
944
917 TODO this is highly revlog centric and should be abstracted into a
945 TODO this is highly revlog centric and should be abstracted into a
918 higher-level deletion API.
946 higher-level deletion API.
919 """
947 """
920
948
921
949
922 class ifilestorage(ifileindex, ifiledata, ifilemutation):
950 class ifilestorage(ifileindex, ifiledata, ifilemutation, Protocol):
923 """Complete storage interface for a single tracked file."""
951 """Complete storage interface for a single tracked file."""
924
952
953 @abc.abstractmethod
925 def files(self):
954 def files(self):
926 """Obtain paths that are backing storage for this file.
955 """Obtain paths that are backing storage for this file.
927
956
928 TODO this is used heavily by verify code and there should probably
957 TODO this is used heavily by verify code and there should probably
929 be a better API for that.
958 be a better API for that.
930 """
959 """
931
960
961 @abc.abstractmethod
932 def storageinfo(
962 def storageinfo(
933 self,
963 self,
934 exclusivefiles=False,
964 exclusivefiles=False,
935 sharedfiles=False,
965 sharedfiles=False,
936 revisionscount=False,
966 revisionscount=False,
937 trackedsize=False,
967 trackedsize=False,
938 storedsize=False,
968 storedsize=False,
939 ):
969 ):
940 """Obtain information about storage for this file's data.
970 """Obtain information about storage for this file's data.
941
971
942 Returns a dict describing storage for this tracked path. The keys
972 Returns a dict describing storage for this tracked path. The keys
943 in the dict map to arguments of the same. The arguments are bools
973 in the dict map to arguments of the same. The arguments are bools
944 indicating whether to calculate and obtain that data.
974 indicating whether to calculate and obtain that data.
945
975
946 exclusivefiles
976 exclusivefiles
947 Iterable of (vfs, path) describing files that are exclusively
977 Iterable of (vfs, path) describing files that are exclusively
948 used to back storage for this tracked path.
978 used to back storage for this tracked path.
949
979
950 sharedfiles
980 sharedfiles
951 Iterable of (vfs, path) describing files that are used to back
981 Iterable of (vfs, path) describing files that are used to back
952 storage for this tracked path. Those files may also provide storage
982 storage for this tracked path. Those files may also provide storage
953 for other stored entities.
983 for other stored entities.
954
984
955 revisionscount
985 revisionscount
956 Number of revisions available for retrieval.
986 Number of revisions available for retrieval.
957
987
958 trackedsize
988 trackedsize
959 Total size in bytes of all tracked revisions. This is a sum of the
989 Total size in bytes of all tracked revisions. This is a sum of the
960 length of the fulltext of all revisions.
990 length of the fulltext of all revisions.
961
991
962 storedsize
992 storedsize
963 Total size in bytes used to store data for all tracked revisions.
993 Total size in bytes used to store data for all tracked revisions.
964 This is commonly less than ``trackedsize`` due to internal usage
994 This is commonly less than ``trackedsize`` due to internal usage
965 of deltas rather than fulltext revisions.
995 of deltas rather than fulltext revisions.
966
996
967 Not all storage backends may support all queries are have a reasonable
997 Not all storage backends may support all queries are have a reasonable
968 value to use. In that case, the value should be set to ``None`` and
998 value to use. In that case, the value should be set to ``None`` and
969 callers are expected to handle this special value.
999 callers are expected to handle this special value.
970 """
1000 """
971
1001
1002 @abc.abstractmethod
972 def verifyintegrity(self, state) -> Iterable[iverifyproblem]:
1003 def verifyintegrity(self, state) -> Iterable[iverifyproblem]:
973 """Verifies the integrity of file storage.
1004 """Verifies the integrity of file storage.
974
1005
975 ``state`` is a dict holding state of the verifier process. It can be
1006 ``state`` is a dict holding state of the verifier process. It can be
976 used to communicate data between invocations of multiple storage
1007 used to communicate data between invocations of multiple storage
977 primitives.
1008 primitives.
978
1009
979 If individual revisions cannot have their revision content resolved,
1010 If individual revisions cannot have their revision content resolved,
980 the method is expected to set the ``skipread`` key to a set of nodes
1011 the method is expected to set the ``skipread`` key to a set of nodes
981 that encountered problems. If set, the method can also add the node(s)
1012 that encountered problems. If set, the method can also add the node(s)
982 to ``safe_renamed`` in order to indicate nodes that may perform the
1013 to ``safe_renamed`` in order to indicate nodes that may perform the
983 rename checks with currently accessible data.
1014 rename checks with currently accessible data.
984
1015
985 The method yields objects conforming to the ``iverifyproblem``
1016 The method yields objects conforming to the ``iverifyproblem``
986 interface.
1017 interface.
987 """
1018 """
988
1019
989
1020
990 class idirs(Protocol):
1021 class idirs(Protocol):
991 """Interface representing a collection of directories from paths.
1022 """Interface representing a collection of directories from paths.
992
1023
993 This interface is essentially a derived data structure representing
1024 This interface is essentially a derived data structure representing
994 directories from a collection of paths.
1025 directories from a collection of paths.
995 """
1026 """
996
1027
997 def addpath(self, path):
1028 def addpath(self, path):
998 """Add a path to the collection.
1029 """Add a path to the collection.
999
1030
1000 All directories in the path will be added to the collection.
1031 All directories in the path will be added to the collection.
1001 """
1032 """
1002
1033
1003 def delpath(self, path):
1034 def delpath(self, path):
1004 """Remove a path from the collection.
1035 """Remove a path from the collection.
1005
1036
1006 If the removal was the last path in a particular directory, the
1037 If the removal was the last path in a particular directory, the
1007 directory is removed from the collection.
1038 directory is removed from the collection.
1008 """
1039 """
1009
1040
1010 def __iter__(self):
1041 def __iter__(self):
1011 """Iterate over the directories in this collection of paths."""
1042 """Iterate over the directories in this collection of paths."""
1012
1043
1013 def __contains__(self, path):
1044 def __contains__(self, path):
1014 """Whether a specific directory is in this collection."""
1045 """Whether a specific directory is in this collection."""
1015
1046
1016
1047
1017 class imanifestdict(Protocol):
1048 class imanifestdict(Protocol):
1018 """Interface representing a manifest data structure.
1049 """Interface representing a manifest data structure.
1019
1050
1020 A manifest is effectively a dict mapping paths to entries. Each entry
1051 A manifest is effectively a dict mapping paths to entries. Each entry
1021 consists of a binary node and extra flags affecting that entry.
1052 consists of a binary node and extra flags affecting that entry.
1022 """
1053 """
1023
1054
1024 def __getitem__(self, path):
1055 def __getitem__(self, path):
1025 """Returns the binary node value for a path in the manifest.
1056 """Returns the binary node value for a path in the manifest.
1026
1057
1027 Raises ``KeyError`` if the path does not exist in the manifest.
1058 Raises ``KeyError`` if the path does not exist in the manifest.
1028
1059
1029 Equivalent to ``self.find(path)[0]``.
1060 Equivalent to ``self.find(path)[0]``.
1030 """
1061 """
1031
1062
1032 def find(self, path):
1063 def find(self, path):
1033 """Returns the entry for a path in the manifest.
1064 """Returns the entry for a path in the manifest.
1034
1065
1035 Returns a 2-tuple of (node, flags).
1066 Returns a 2-tuple of (node, flags).
1036
1067
1037 Raises ``KeyError`` if the path does not exist in the manifest.
1068 Raises ``KeyError`` if the path does not exist in the manifest.
1038 """
1069 """
1039
1070
1040 def __len__(self):
1071 def __len__(self):
1041 """Return the number of entries in the manifest."""
1072 """Return the number of entries in the manifest."""
1042
1073
1043 def __nonzero__(self):
1074 def __nonzero__(self):
1044 """Returns True if the manifest has entries, False otherwise."""
1075 """Returns True if the manifest has entries, False otherwise."""
1045
1076
1046 __bool__ = __nonzero__
1077 __bool__ = __nonzero__
1047
1078
1048 def set(self, path, node, flags):
1079 def set(self, path, node, flags):
1049 """Define the node value and flags for a path in the manifest.
1080 """Define the node value and flags for a path in the manifest.
1050
1081
1051 Equivalent to __setitem__ followed by setflag, but can be more efficient.
1082 Equivalent to __setitem__ followed by setflag, but can be more efficient.
1052 """
1083 """
1053
1084
1054 def __setitem__(self, path, node):
1085 def __setitem__(self, path, node):
1055 """Define the node value for a path in the manifest.
1086 """Define the node value for a path in the manifest.
1056
1087
1057 If the path is already in the manifest, its flags will be copied to
1088 If the path is already in the manifest, its flags will be copied to
1058 the new entry.
1089 the new entry.
1059 """
1090 """
1060
1091
1061 def __contains__(self, path):
1092 def __contains__(self, path):
1062 """Whether a path exists in the manifest."""
1093 """Whether a path exists in the manifest."""
1063
1094
1064 def __delitem__(self, path):
1095 def __delitem__(self, path):
1065 """Remove a path from the manifest.
1096 """Remove a path from the manifest.
1066
1097
1067 Raises ``KeyError`` if the path is not in the manifest.
1098 Raises ``KeyError`` if the path is not in the manifest.
1068 """
1099 """
1069
1100
1070 def __iter__(self):
1101 def __iter__(self):
1071 """Iterate over paths in the manifest."""
1102 """Iterate over paths in the manifest."""
1072
1103
1073 def iterkeys(self):
1104 def iterkeys(self):
1074 """Iterate over paths in the manifest."""
1105 """Iterate over paths in the manifest."""
1075
1106
1076 def keys(self):
1107 def keys(self):
1077 """Obtain a list of paths in the manifest."""
1108 """Obtain a list of paths in the manifest."""
1078
1109
1079 def filesnotin(self, other, match=None):
1110 def filesnotin(self, other, match=None):
1080 """Obtain the set of paths in this manifest but not in another.
1111 """Obtain the set of paths in this manifest but not in another.
1081
1112
1082 ``match`` is an optional matcher function to be applied to both
1113 ``match`` is an optional matcher function to be applied to both
1083 manifests.
1114 manifests.
1084
1115
1085 Returns a set of paths.
1116 Returns a set of paths.
1086 """
1117 """
1087
1118
1088 def dirs(self):
1119 def dirs(self):
1089 """Returns an object implementing the ``idirs`` interface."""
1120 """Returns an object implementing the ``idirs`` interface."""
1090
1121
1091 def hasdir(self, dir):
1122 def hasdir(self, dir):
1092 """Returns a bool indicating if a directory is in this manifest."""
1123 """Returns a bool indicating if a directory is in this manifest."""
1093
1124
1094 def walk(self, match):
1125 def walk(self, match):
1095 """Generator of paths in manifest satisfying a matcher.
1126 """Generator of paths in manifest satisfying a matcher.
1096
1127
1097 If the matcher has explicit files listed and they don't exist in
1128 If the matcher has explicit files listed and they don't exist in
1098 the manifest, ``match.bad()`` is called for each missing file.
1129 the manifest, ``match.bad()`` is called for each missing file.
1099 """
1130 """
1100
1131
1101 def diff(self, other, match=None, clean=False):
1132 def diff(self, other, match=None, clean=False):
1102 """Find differences between this manifest and another.
1133 """Find differences between this manifest and another.
1103
1134
1104 This manifest is compared to ``other``.
1135 This manifest is compared to ``other``.
1105
1136
1106 If ``match`` is provided, the two manifests are filtered against this
1137 If ``match`` is provided, the two manifests are filtered against this
1107 matcher and only entries satisfying the matcher are compared.
1138 matcher and only entries satisfying the matcher are compared.
1108
1139
1109 If ``clean`` is True, unchanged files are included in the returned
1140 If ``clean`` is True, unchanged files are included in the returned
1110 object.
1141 object.
1111
1142
1112 Returns a dict with paths as keys and values of 2-tuples of 2-tuples of
1143 Returns a dict with paths as keys and values of 2-tuples of 2-tuples of
1113 the form ``((node1, flag1), (node2, flag2))`` where ``(node1, flag1)``
1144 the form ``((node1, flag1), (node2, flag2))`` where ``(node1, flag1)``
1114 represents the node and flags for this manifest and ``(node2, flag2)``
1145 represents the node and flags for this manifest and ``(node2, flag2)``
1115 are the same for the other manifest.
1146 are the same for the other manifest.
1116 """
1147 """
1117
1148
1118 def setflag(self, path, flag):
1149 def setflag(self, path, flag):
1119 """Set the flag value for a given path.
1150 """Set the flag value for a given path.
1120
1151
1121 Raises ``KeyError`` if the path is not already in the manifest.
1152 Raises ``KeyError`` if the path is not already in the manifest.
1122 """
1153 """
1123
1154
1124 def get(self, path, default=None):
1155 def get(self, path, default=None):
1125 """Obtain the node value for a path or a default value if missing."""
1156 """Obtain the node value for a path or a default value if missing."""
1126
1157
1127 def flags(self, path):
1158 def flags(self, path):
1128 """Return the flags value for a path (default: empty bytestring)."""
1159 """Return the flags value for a path (default: empty bytestring)."""
1129
1160
1130 def copy(self):
1161 def copy(self):
1131 """Return a copy of this manifest."""
1162 """Return a copy of this manifest."""
1132
1163
1133 def items(self):
1164 def items(self):
1134 """Returns an iterable of (path, node) for items in this manifest."""
1165 """Returns an iterable of (path, node) for items in this manifest."""
1135
1166
1136 def iteritems(self):
1167 def iteritems(self):
1137 """Identical to items()."""
1168 """Identical to items()."""
1138
1169
1139 def iterentries(self):
1170 def iterentries(self):
1140 """Returns an iterable of (path, node, flags) for this manifest.
1171 """Returns an iterable of (path, node, flags) for this manifest.
1141
1172
1142 Similar to ``iteritems()`` except items are a 3-tuple and include
1173 Similar to ``iteritems()`` except items are a 3-tuple and include
1143 flags.
1174 flags.
1144 """
1175 """
1145
1176
1146 def text(self):
1177 def text(self):
1147 """Obtain the raw data representation for this manifest.
1178 """Obtain the raw data representation for this manifest.
1148
1179
1149 Result is used to create a manifest revision.
1180 Result is used to create a manifest revision.
1150 """
1181 """
1151
1182
1152 def fastdelta(self, base, changes):
1183 def fastdelta(self, base, changes):
1153 """Obtain a delta between this manifest and another given changes.
1184 """Obtain a delta between this manifest and another given changes.
1154
1185
1155 ``base`` in the raw data representation for another manifest.
1186 ``base`` in the raw data representation for another manifest.
1156
1187
1157 ``changes`` is an iterable of ``(path, to_delete)``.
1188 ``changes`` is an iterable of ``(path, to_delete)``.
1158
1189
1159 Returns a 2-tuple containing ``bytearray(self.text())`` and the
1190 Returns a 2-tuple containing ``bytearray(self.text())`` and the
1160 delta between ``base`` and this manifest.
1191 delta between ``base`` and this manifest.
1161
1192
1162 If this manifest implementation can't support ``fastdelta()``,
1193 If this manifest implementation can't support ``fastdelta()``,
1163 raise ``mercurial.manifest.FastdeltaUnavailable``.
1194 raise ``mercurial.manifest.FastdeltaUnavailable``.
1164 """
1195 """
1165
1196
1166
1197
1167 class imanifestrevisionbase(Protocol):
1198 class imanifestrevisionbase(Protocol):
1168 """Base interface representing a single revision of a manifest.
1199 """Base interface representing a single revision of a manifest.
1169
1200
1170 Should not be used as a primary interface: should always be inherited
1201 Should not be used as a primary interface: should always be inherited
1171 as part of a larger interface.
1202 as part of a larger interface.
1172 """
1203 """
1173
1204
1174 def copy(self):
1205 def copy(self):
1175 """Obtain a copy of this manifest instance.
1206 """Obtain a copy of this manifest instance.
1176
1207
1177 Returns an object conforming to the ``imanifestrevisionwritable``
1208 Returns an object conforming to the ``imanifestrevisionwritable``
1178 interface. The instance will be associated with the same
1209 interface. The instance will be associated with the same
1179 ``imanifestlog`` collection as this instance.
1210 ``imanifestlog`` collection as this instance.
1180 """
1211 """
1181
1212
1182 def read(self):
1213 def read(self):
1183 """Obtain the parsed manifest data structure.
1214 """Obtain the parsed manifest data structure.
1184
1215
1185 The returned object conforms to the ``imanifestdict`` interface.
1216 The returned object conforms to the ``imanifestdict`` interface.
1186 """
1217 """
1187
1218
1188
1219
1189 class imanifestrevisionstored(imanifestrevisionbase, Protocol):
1220 class imanifestrevisionstored(imanifestrevisionbase, Protocol):
1190 """Interface representing a manifest revision committed to storage."""
1221 """Interface representing a manifest revision committed to storage."""
1191
1222
1192 @abc.abstractmethod
1223 @abc.abstractmethod
1193 def node(self) -> bytes:
1224 def node(self) -> bytes:
1194 """The binary node for this manifest."""
1225 """The binary node for this manifest."""
1195
1226
1196 parents: list[bytes]
1227 parents: list[bytes]
1197 """List of binary nodes that are parents for this manifest revision."""
1228 """List of binary nodes that are parents for this manifest revision."""
1198
1229
1199 @abc.abstractmethod
1230 @abc.abstractmethod
1200 def readdelta(self, shallow: bool = False):
1231 def readdelta(self, shallow: bool = False):
1201 """Obtain the manifest data structure representing changes from parent.
1232 """Obtain the manifest data structure representing changes from parent.
1202
1233
1203 This manifest is compared to its 1st parent. A new manifest
1234 This manifest is compared to its 1st parent. A new manifest
1204 representing those differences is constructed.
1235 representing those differences is constructed.
1205
1236
1206 If `shallow` is True, this will read the delta for this directory,
1237 If `shallow` is True, this will read the delta for this directory,
1207 without recursively reading subdirectory manifests. Instead, any
1238 without recursively reading subdirectory manifests. Instead, any
1208 subdirectory entry will be reported as it appears in the manifest, i.e.
1239 subdirectory entry will be reported as it appears in the manifest, i.e.
1209 the subdirectory will be reported among files and distinguished only by
1240 the subdirectory will be reported among files and distinguished only by
1210 its 't' flag. This only apply if the underlying manifest support it.
1241 its 't' flag. This only apply if the underlying manifest support it.
1211
1242
1212 The returned object conforms to the ``imanifestdict`` interface.
1243 The returned object conforms to the ``imanifestdict`` interface.
1213 """
1244 """
1214
1245
1215 @abc.abstractmethod
1246 @abc.abstractmethod
1216 def read_any_fast_delta(
1247 def read_any_fast_delta(
1217 self,
1248 self,
1218 valid_bases: Collection[int] | None = None,
1249 valid_bases: Collection[int] | None = None,
1219 *,
1250 *,
1220 shallow: bool = False,
1251 shallow: bool = False,
1221 ):
1252 ):
1222 """read some manifest information as fast if possible
1253 """read some manifest information as fast if possible
1223
1254
1224 This might return a "delta", a manifest object containing only file
1255 This might return a "delta", a manifest object containing only file
1225 changed compared to another revisions. The `valid_bases` argument
1256 changed compared to another revisions. The `valid_bases` argument
1226 control the set of revision that might be used as a base.
1257 control the set of revision that might be used as a base.
1227
1258
1228 If no delta can be retrieved quickly, a full read of the manifest will
1259 If no delta can be retrieved quickly, a full read of the manifest will
1229 be performed instead.
1260 be performed instead.
1230
1261
1231 The function return a tuple with two elements. The first one is the
1262 The function return a tuple with two elements. The first one is the
1232 delta base used (or None if we did a full read), the second one is the
1263 delta base used (or None if we did a full read), the second one is the
1233 manifest information.
1264 manifest information.
1234
1265
1235 If `shallow` is True, this will read the delta for this directory,
1266 If `shallow` is True, this will read the delta for this directory,
1236 without recursively reading subdirectory manifests. Instead, any
1267 without recursively reading subdirectory manifests. Instead, any
1237 subdirectory entry will be reported as it appears in the manifest, i.e.
1268 subdirectory entry will be reported as it appears in the manifest, i.e.
1238 the subdirectory will be reported among files and distinguished only by
1269 the subdirectory will be reported among files and distinguished only by
1239 its 't' flag. This only apply if the underlying manifest support it.
1270 its 't' flag. This only apply if the underlying manifest support it.
1240
1271
1241 The returned object conforms to the ``imanifestdict`` interface.
1272 The returned object conforms to the ``imanifestdict`` interface.
1242 """
1273 """
1243
1274
1244 @abc.abstractmethod
1275 @abc.abstractmethod
1245 def read_delta_parents(self, *, shallow: bool = False, exact: bool = True):
1276 def read_delta_parents(self, *, shallow: bool = False, exact: bool = True):
1246 """return a diff from this revision against both parents.
1277 """return a diff from this revision against both parents.
1247
1278
1248 If `exact` is False, this might return a superset of the diff, containing
1279 If `exact` is False, this might return a superset of the diff, containing
1249 files that are actually present as is in one of the parents.
1280 files that are actually present as is in one of the parents.
1250
1281
1251 If `shallow` is True, this will read the delta for this directory,
1282 If `shallow` is True, this will read the delta for this directory,
1252 without recursively reading subdirectory manifests. Instead, any
1283 without recursively reading subdirectory manifests. Instead, any
1253 subdirectory entry will be reported as it appears in the manifest, i.e.
1284 subdirectory entry will be reported as it appears in the manifest, i.e.
1254 the subdirectory will be reported among files and distinguished only by
1285 the subdirectory will be reported among files and distinguished only by
1255 its 't' flag. This only apply if the underlying manifest support it.
1286 its 't' flag. This only apply if the underlying manifest support it.
1256
1287
1257 The returned object conforms to the ``imanifestdict`` interface."""
1288 The returned object conforms to the ``imanifestdict`` interface."""
1258
1289
1259 @abc.abstractmethod
1290 @abc.abstractmethod
1260 def read_delta_new_entries(self, *, shallow: bool = False):
1291 def read_delta_new_entries(self, *, shallow: bool = False):
1261 """Return a manifest containing just the entries that might be new to
1292 """Return a manifest containing just the entries that might be new to
1262 the repository.
1293 the repository.
1263
1294
1264 This is often equivalent to a diff against both parents, but without
1295 This is often equivalent to a diff against both parents, but without
1265 garantee. For performance reason, It might contains more files in some cases.
1296 garantee. For performance reason, It might contains more files in some cases.
1266
1297
1267 If `shallow` is True, this will read the delta for this directory,
1298 If `shallow` is True, this will read the delta for this directory,
1268 without recursively reading subdirectory manifests. Instead, any
1299 without recursively reading subdirectory manifests. Instead, any
1269 subdirectory entry will be reported as it appears in the manifest, i.e.
1300 subdirectory entry will be reported as it appears in the manifest, i.e.
1270 the subdirectory will be reported among files and distinguished only by
1301 the subdirectory will be reported among files and distinguished only by
1271 its 't' flag. This only apply if the underlying manifest support it.
1302 its 't' flag. This only apply if the underlying manifest support it.
1272
1303
1273 The returned object conforms to the ``imanifestdict`` interface."""
1304 The returned object conforms to the ``imanifestdict`` interface."""
1274
1305
1275 @abc.abstractmethod
1306 @abc.abstractmethod
1276 def readfast(self, shallow: bool = False):
1307 def readfast(self, shallow: bool = False):
1277 """Calls either ``read()`` or ``readdelta()``.
1308 """Calls either ``read()`` or ``readdelta()``.
1278
1309
1279 The faster of the two options is called.
1310 The faster of the two options is called.
1280 """
1311 """
1281
1312
1282 @abc.abstractmethod
1313 @abc.abstractmethod
1283 def find(self, key: bytes) -> tuple[bytes, bytes]:
1314 def find(self, key: bytes) -> tuple[bytes, bytes]:
1284 """Calls ``self.read().find(key)``.
1315 """Calls ``self.read().find(key)``.
1285
1316
1286 Returns a 2-tuple of ``(node, flags)`` or raises ``KeyError``.
1317 Returns a 2-tuple of ``(node, flags)`` or raises ``KeyError``.
1287 """
1318 """
1288
1319
1289
1320
1290 class imanifestrevisionwritable(imanifestrevisionbase, Protocol):
1321 class imanifestrevisionwritable(imanifestrevisionbase, Protocol):
1291 """Interface representing a manifest revision that can be committed."""
1322 """Interface representing a manifest revision that can be committed."""
1292
1323
1293 @abc.abstractmethod
1324 @abc.abstractmethod
1294 def write(
1325 def write(
1295 self, transaction, linkrev, p1node, p2node, added, removed, match=None
1326 self, transaction, linkrev, p1node, p2node, added, removed, match=None
1296 ):
1327 ):
1297 """Add this revision to storage.
1328 """Add this revision to storage.
1298
1329
1299 Takes a transaction object, the changeset revision number it will
1330 Takes a transaction object, the changeset revision number it will
1300 be associated with, its parent nodes, and lists of added and
1331 be associated with, its parent nodes, and lists of added and
1301 removed paths.
1332 removed paths.
1302
1333
1303 If match is provided, storage can choose not to inspect or write out
1334 If match is provided, storage can choose not to inspect or write out
1304 items that do not match. Storage is still required to be able to provide
1335 items that do not match. Storage is still required to be able to provide
1305 the full manifest in the future for any directories written (these
1336 the full manifest in the future for any directories written (these
1306 manifests should not be "narrowed on disk").
1337 manifests should not be "narrowed on disk").
1307
1338
1308 Returns the binary node of the created revision.
1339 Returns the binary node of the created revision.
1309 """
1340 """
1310
1341
1311
1342
1312 class imanifeststorage(Protocol):
1343 class imanifeststorage(Protocol):
1313 """Storage interface for manifest data."""
1344 """Storage interface for manifest data."""
1314
1345
1315 nodeconstants: NodeConstants
1346 nodeconstants: NodeConstants
1316 """nodeconstants used by the current repository."""
1347 """nodeconstants used by the current repository."""
1317
1348
1318 tree: bytes
1349 tree: bytes
1319 """The path to the directory this manifest tracks.
1350 """The path to the directory this manifest tracks.
1320
1351
1321 The empty bytestring represents the root manifest.
1352 The empty bytestring represents the root manifest.
1322 """
1353 """
1323
1354
1324 index: ifilerevisionssequence
1355 index: ifilerevisionssequence
1325 """An ``ifilerevisionssequence`` instance."""
1356 """An ``ifilerevisionssequence`` instance."""
1326
1357
1327 opener: Vfs
1358 opener: Vfs
1328 """VFS opener to use to access underlying files used for storage.
1359 """VFS opener to use to access underlying files used for storage.
1329
1360
1330 TODO this is revlog specific and should not be exposed.
1361 TODO this is revlog specific and should not be exposed.
1331 """
1362 """
1332
1363
1333 # TODO: finish type hints
1364 # TODO: finish type hints
1334 fulltextcache: dict
1365 fulltextcache: dict
1335 """Dict with cache of fulltexts.
1366 """Dict with cache of fulltexts.
1336
1367
1337 TODO this doesn't feel appropriate for the storage interface.
1368 TODO this doesn't feel appropriate for the storage interface.
1338 """
1369 """
1339
1370
1340 @abc.abstractmethod
1371 @abc.abstractmethod
1341 def __len__(self):
1372 def __len__(self):
1342 """Obtain the number of revisions stored for this manifest."""
1373 """Obtain the number of revisions stored for this manifest."""
1343
1374
1344 @abc.abstractmethod
1375 @abc.abstractmethod
1345 def __iter__(self):
1376 def __iter__(self):
1346 """Iterate over revision numbers for this manifest."""
1377 """Iterate over revision numbers for this manifest."""
1347
1378
1348 @abc.abstractmethod
1379 @abc.abstractmethod
1349 def rev(self, node):
1380 def rev(self, node):
1350 """Obtain the revision number given a binary node.
1381 """Obtain the revision number given a binary node.
1351
1382
1352 Raises ``error.LookupError`` if the node is not known.
1383 Raises ``error.LookupError`` if the node is not known.
1353 """
1384 """
1354
1385
1355 @abc.abstractmethod
1386 @abc.abstractmethod
1356 def node(self, rev):
1387 def node(self, rev):
1357 """Obtain the node value given a revision number.
1388 """Obtain the node value given a revision number.
1358
1389
1359 Raises ``error.LookupError`` if the revision is not known.
1390 Raises ``error.LookupError`` if the revision is not known.
1360 """
1391 """
1361
1392
1362 @abc.abstractmethod
1393 @abc.abstractmethod
1363 def lookup(self, value):
1394 def lookup(self, value):
1364 """Attempt to resolve a value to a node.
1395 """Attempt to resolve a value to a node.
1365
1396
1366 Value can be a binary node, hex node, revision number, or a bytes
1397 Value can be a binary node, hex node, revision number, or a bytes
1367 that can be converted to an integer.
1398 that can be converted to an integer.
1368
1399
1369 Raises ``error.LookupError`` if a ndoe could not be resolved.
1400 Raises ``error.LookupError`` if a ndoe could not be resolved.
1370 """
1401 """
1371
1402
1372 @abc.abstractmethod
1403 @abc.abstractmethod
1373 def parents(self, node):
1404 def parents(self, node):
1374 """Returns a 2-tuple of parent nodes for a node.
1405 """Returns a 2-tuple of parent nodes for a node.
1375
1406
1376 Values will be ``nullid`` if the parent is empty.
1407 Values will be ``nullid`` if the parent is empty.
1377 """
1408 """
1378
1409
1379 @abc.abstractmethod
1410 @abc.abstractmethod
1380 def parentrevs(self, rev):
1411 def parentrevs(self, rev):
1381 """Like parents() but operates on revision numbers."""
1412 """Like parents() but operates on revision numbers."""
1382
1413
1383 @abc.abstractmethod
1414 @abc.abstractmethod
1384 def linkrev(self, rev):
1415 def linkrev(self, rev):
1385 """Obtain the changeset revision number a revision is linked to."""
1416 """Obtain the changeset revision number a revision is linked to."""
1386
1417
1387 @abc.abstractmethod
1418 @abc.abstractmethod
1388 def revision(self, node):
1419 def revision(self, node):
1389 """Obtain fulltext data for a node."""
1420 """Obtain fulltext data for a node."""
1390
1421
1391 @abc.abstractmethod
1422 @abc.abstractmethod
1392 def rawdata(self, node):
1423 def rawdata(self, node):
1393 """Obtain raw data for a node."""
1424 """Obtain raw data for a node."""
1394
1425
1395 @abc.abstractmethod
1426 @abc.abstractmethod
1396 def revdiff(self, rev1, rev2):
1427 def revdiff(self, rev1, rev2):
1397 """Obtain a delta between two revision numbers.
1428 """Obtain a delta between two revision numbers.
1398
1429
1399 The returned data is the result of ``bdiff.bdiff()`` on the raw
1430 The returned data is the result of ``bdiff.bdiff()`` on the raw
1400 revision data.
1431 revision data.
1401 """
1432 """
1402
1433
1403 @abc.abstractmethod
1434 @abc.abstractmethod
1404 def cmp(self, node, fulltext):
1435 def cmp(self, node, fulltext):
1405 """Compare fulltext to another revision.
1436 """Compare fulltext to another revision.
1406
1437
1407 Returns True if the fulltext is different from what is stored.
1438 Returns True if the fulltext is different from what is stored.
1408 """
1439 """
1409
1440
1410 @abc.abstractmethod
1441 @abc.abstractmethod
1411 def emitrevisions(
1442 def emitrevisions(
1412 self,
1443 self,
1413 nodes,
1444 nodes,
1414 nodesorder=None,
1445 nodesorder=None,
1415 revisiondata=False,
1446 revisiondata=False,
1416 assumehaveparentrevisions=False,
1447 assumehaveparentrevisions=False,
1417 ):
1448 ):
1418 """Produce ``irevisiondelta`` describing revisions.
1449 """Produce ``irevisiondelta`` describing revisions.
1419
1450
1420 See the documentation for ``ifiledata`` for more.
1451 See the documentation for ``ifiledata`` for more.
1421 """
1452 """
1422
1453
1423 @abc.abstractmethod
1454 @abc.abstractmethod
1424 def addgroup(
1455 def addgroup(
1425 self,
1456 self,
1426 deltas,
1457 deltas,
1427 linkmapper,
1458 linkmapper,
1428 transaction,
1459 transaction,
1429 addrevisioncb=None,
1460 addrevisioncb=None,
1430 duplicaterevisioncb=None,
1461 duplicaterevisioncb=None,
1431 ):
1462 ):
1432 """Process a series of deltas for storage.
1463 """Process a series of deltas for storage.
1433
1464
1434 See the documentation in ``ifilemutation`` for more.
1465 See the documentation in ``ifilemutation`` for more.
1435 """
1466 """
1436
1467
1437 @abc.abstractmethod
1468 @abc.abstractmethod
1438 def rawsize(self, rev):
1469 def rawsize(self, rev):
1439 """Obtain the size of tracked data.
1470 """Obtain the size of tracked data.
1440
1471
1441 Is equivalent to ``len(m.rawdata(node))``.
1472 Is equivalent to ``len(m.rawdata(node))``.
1442
1473
1443 TODO this method is only used by upgrade code and may be removed.
1474 TODO this method is only used by upgrade code and may be removed.
1444 """
1475 """
1445
1476
1446 @abc.abstractmethod
1477 @abc.abstractmethod
1447 def getstrippoint(self, minlink):
1478 def getstrippoint(self, minlink):
1448 """Find minimum revision that must be stripped to strip a linkrev.
1479 """Find minimum revision that must be stripped to strip a linkrev.
1449
1480
1450 See the documentation in ``ifilemutation`` for more.
1481 See the documentation in ``ifilemutation`` for more.
1451 """
1482 """
1452
1483
1453 @abc.abstractmethod
1484 @abc.abstractmethod
1454 def strip(self, minlink, transaction):
1485 def strip(self, minlink, transaction):
1455 """Remove storage of items starting at a linkrev.
1486 """Remove storage of items starting at a linkrev.
1456
1487
1457 See the documentation in ``ifilemutation`` for more.
1488 See the documentation in ``ifilemutation`` for more.
1458 """
1489 """
1459
1490
1460 @abc.abstractmethod
1491 @abc.abstractmethod
1461 def checksize(self):
1492 def checksize(self):
1462 """Obtain the expected sizes of backing files.
1493 """Obtain the expected sizes of backing files.
1463
1494
1464 TODO this is used by verify and it should not be part of the interface.
1495 TODO this is used by verify and it should not be part of the interface.
1465 """
1496 """
1466
1497
1467 @abc.abstractmethod
1498 @abc.abstractmethod
1468 def files(self):
1499 def files(self):
1469 """Obtain paths that are backing storage for this manifest.
1500 """Obtain paths that are backing storage for this manifest.
1470
1501
1471 TODO this is used by verify and there should probably be a better API
1502 TODO this is used by verify and there should probably be a better API
1472 for this functionality.
1503 for this functionality.
1473 """
1504 """
1474
1505
1475 @abc.abstractmethod
1506 @abc.abstractmethod
1476 def deltaparent(self, rev):
1507 def deltaparent(self, rev):
1477 """Obtain the revision that a revision is delta'd against.
1508 """Obtain the revision that a revision is delta'd against.
1478
1509
1479 TODO delta encoding is an implementation detail of storage and should
1510 TODO delta encoding is an implementation detail of storage and should
1480 not be exposed to the storage interface.
1511 not be exposed to the storage interface.
1481 """
1512 """
1482
1513
1483 @abc.abstractmethod
1514 @abc.abstractmethod
1484 def clone(self, tr, dest, **kwargs):
1515 def clone(self, tr, dest, **kwargs):
1485 """Clone this instance to another."""
1516 """Clone this instance to another."""
1486
1517
1487 @abc.abstractmethod
1518 @abc.abstractmethod
1488 def clearcaches(self, clear_persisted_data=False):
1519 def clearcaches(self, clear_persisted_data=False):
1489 """Clear any caches associated with this instance."""
1520 """Clear any caches associated with this instance."""
1490
1521
1491 @abc.abstractmethod
1522 @abc.abstractmethod
1492 def dirlog(self, d):
1523 def dirlog(self, d):
1493 """Obtain a manifest storage instance for a tree."""
1524 """Obtain a manifest storage instance for a tree."""
1494
1525
1495 @abc.abstractmethod
1526 @abc.abstractmethod
1496 def add(
1527 def add(
1497 self,
1528 self,
1498 m,
1529 m,
1499 transaction,
1530 transaction,
1500 link,
1531 link,
1501 p1,
1532 p1,
1502 p2,
1533 p2,
1503 added,
1534 added,
1504 removed,
1535 removed,
1505 readtree=None,
1536 readtree=None,
1506 match=None,
1537 match=None,
1507 ):
1538 ):
1508 """Add a revision to storage.
1539 """Add a revision to storage.
1509
1540
1510 ``m`` is an object conforming to ``imanifestdict``.
1541 ``m`` is an object conforming to ``imanifestdict``.
1511
1542
1512 ``link`` is the linkrev revision number.
1543 ``link`` is the linkrev revision number.
1513
1544
1514 ``p1`` and ``p2`` are the parent revision numbers.
1545 ``p1`` and ``p2`` are the parent revision numbers.
1515
1546
1516 ``added`` and ``removed`` are iterables of added and removed paths,
1547 ``added`` and ``removed`` are iterables of added and removed paths,
1517 respectively.
1548 respectively.
1518
1549
1519 ``readtree`` is a function that can be used to read the child tree(s)
1550 ``readtree`` is a function that can be used to read the child tree(s)
1520 when recursively writing the full tree structure when using
1551 when recursively writing the full tree structure when using
1521 treemanifets.
1552 treemanifets.
1522
1553
1523 ``match`` is a matcher that can be used to hint to storage that not all
1554 ``match`` is a matcher that can be used to hint to storage that not all
1524 paths must be inspected; this is an optimization and can be safely
1555 paths must be inspected; this is an optimization and can be safely
1525 ignored. Note that the storage must still be able to reproduce a full
1556 ignored. Note that the storage must still be able to reproduce a full
1526 manifest including files that did not match.
1557 manifest including files that did not match.
1527 """
1558 """
1528
1559
1529 @abc.abstractmethod
1560 @abc.abstractmethod
1530 def storageinfo(
1561 def storageinfo(
1531 self,
1562 self,
1532 exclusivefiles=False,
1563 exclusivefiles=False,
1533 sharedfiles=False,
1564 sharedfiles=False,
1534 revisionscount=False,
1565 revisionscount=False,
1535 trackedsize=False,
1566 trackedsize=False,
1536 storedsize=False,
1567 storedsize=False,
1537 ):
1568 ):
1538 """Obtain information about storage for this manifest's data.
1569 """Obtain information about storage for this manifest's data.
1539
1570
1540 See ``ifilestorage.storageinfo()`` for a description of this method.
1571 See ``ifilestorage.storageinfo()`` for a description of this method.
1541 This one behaves the same way, except for manifest data.
1572 This one behaves the same way, except for manifest data.
1542 """
1573 """
1543
1574
1544 @abc.abstractmethod
1575 @abc.abstractmethod
1545 def get_revlog(self):
1576 def get_revlog(self):
1546 """return an actual revlog instance if any
1577 """return an actual revlog instance if any
1547
1578
1548 This exist because a lot of code leverage the fact the underlying
1579 This exist because a lot of code leverage the fact the underlying
1549 storage is a revlog for optimization, so giving simple way to access
1580 storage is a revlog for optimization, so giving simple way to access
1550 the revlog instance helps such code.
1581 the revlog instance helps such code.
1551 """
1582 """
1552
1583
1553
1584
1554 class imanifestlog(Protocol):
1585 class imanifestlog(Protocol):
1555 """Interface representing a collection of manifest snapshots.
1586 """Interface representing a collection of manifest snapshots.
1556
1587
1557 Represents the root manifest in a repository.
1588 Represents the root manifest in a repository.
1558
1589
1559 Also serves as a means to access nested tree manifests and to cache
1590 Also serves as a means to access nested tree manifests and to cache
1560 tree manifests.
1591 tree manifests.
1561 """
1592 """
1562
1593
1563 nodeconstants: NodeConstants
1594 nodeconstants: NodeConstants
1564 """nodeconstants used by the current repository."""
1595 """nodeconstants used by the current repository."""
1565
1596
1566 narrowed: bool
1597 narrowed: bool
1567 """True, is the manifest is narrowed by a matcher"""
1598 """True, is the manifest is narrowed by a matcher"""
1568
1599
1569 @abc.abstractmethod
1600 @abc.abstractmethod
1570 def __getitem__(self, node):
1601 def __getitem__(self, node):
1571 """Obtain a manifest instance for a given binary node.
1602 """Obtain a manifest instance for a given binary node.
1572
1603
1573 Equivalent to calling ``self.get('', node)``.
1604 Equivalent to calling ``self.get('', node)``.
1574
1605
1575 The returned object conforms to the ``imanifestrevisionstored``
1606 The returned object conforms to the ``imanifestrevisionstored``
1576 interface.
1607 interface.
1577 """
1608 """
1578
1609
1579 @abc.abstractmethod
1610 @abc.abstractmethod
1580 def get(self, tree, node, verify=True):
1611 def get(self, tree, node, verify=True):
1581 """Retrieve the manifest instance for a given directory and binary node.
1612 """Retrieve the manifest instance for a given directory and binary node.
1582
1613
1583 ``node`` always refers to the node of the root manifest (which will be
1614 ``node`` always refers to the node of the root manifest (which will be
1584 the only manifest if flat manifests are being used).
1615 the only manifest if flat manifests are being used).
1585
1616
1586 If ``tree`` is the empty string, the root manifest is returned.
1617 If ``tree`` is the empty string, the root manifest is returned.
1587 Otherwise the manifest for the specified directory will be returned
1618 Otherwise the manifest for the specified directory will be returned
1588 (requires tree manifests).
1619 (requires tree manifests).
1589
1620
1590 If ``verify`` is True, ``LookupError`` is raised if the node is not
1621 If ``verify`` is True, ``LookupError`` is raised if the node is not
1591 known.
1622 known.
1592
1623
1593 The returned object conforms to the ``imanifestrevisionstored``
1624 The returned object conforms to the ``imanifestrevisionstored``
1594 interface.
1625 interface.
1595 """
1626 """
1596
1627
1597 @abc.abstractmethod
1628 @abc.abstractmethod
1598 def getstorage(self, tree):
1629 def getstorage(self, tree):
1599 """Retrieve an interface to storage for a particular tree.
1630 """Retrieve an interface to storage for a particular tree.
1600
1631
1601 If ``tree`` is the empty bytestring, storage for the root manifest will
1632 If ``tree`` is the empty bytestring, storage for the root manifest will
1602 be returned. Otherwise storage for a tree manifest is returned.
1633 be returned. Otherwise storage for a tree manifest is returned.
1603
1634
1604 TODO formalize interface for returned object.
1635 TODO formalize interface for returned object.
1605 """
1636 """
1606
1637
1607 @abc.abstractmethod
1638 @abc.abstractmethod
1608 def clearcaches(self, clear_persisted_data: bool = False) -> None:
1639 def clearcaches(self, clear_persisted_data: bool = False) -> None:
1609 """Clear caches associated with this collection."""
1640 """Clear caches associated with this collection."""
1610
1641
1611 @abc.abstractmethod
1642 @abc.abstractmethod
1612 def rev(self, node):
1643 def rev(self, node):
1613 """Obtain the revision number for a binary node.
1644 """Obtain the revision number for a binary node.
1614
1645
1615 Raises ``error.LookupError`` if the node is not known.
1646 Raises ``error.LookupError`` if the node is not known.
1616 """
1647 """
1617
1648
1618 @abc.abstractmethod
1649 @abc.abstractmethod
1619 def update_caches(self, transaction):
1650 def update_caches(self, transaction):
1620 """update whatever cache are relevant for the used storage."""
1651 """update whatever cache are relevant for the used storage."""
1621
1652
1622
1653
1623 class ilocalrepositoryfilestorage(Protocol):
1654 class ilocalrepositoryfilestorage(Protocol):
1624 """Local repository sub-interface providing access to tracked file storage.
1655 """Local repository sub-interface providing access to tracked file storage.
1625
1656
1626 This interface defines how a repository accesses storage for a single
1657 This interface defines how a repository accesses storage for a single
1627 tracked file path.
1658 tracked file path.
1628 """
1659 """
1629
1660
1630 def file(self, f):
1661 def file(self, f):
1631 """Obtain a filelog for a tracked path.
1662 """Obtain a filelog for a tracked path.
1632
1663
1633 The returned type conforms to the ``ifilestorage`` interface.
1664 The returned type conforms to the ``ifilestorage`` interface.
1634 """
1665 """
1635
1666
1636
1667
1637 class ilocalrepositorymain(Protocol):
1668 class ilocalrepositorymain(Protocol):
1638 """Main interface for local repositories.
1669 """Main interface for local repositories.
1639
1670
1640 This currently captures the reality of things - not how things should be.
1671 This currently captures the reality of things - not how things should be.
1641 """
1672 """
1642
1673
1643 nodeconstants: NodeConstants
1674 nodeconstants: NodeConstants
1644 """Constant nodes matching the hash function used by the repository."""
1675 """Constant nodes matching the hash function used by the repository."""
1645
1676
1646 nullid: bytes
1677 nullid: bytes
1647 """null revision for the hash function used by the repository."""
1678 """null revision for the hash function used by the repository."""
1648
1679
1649 supported: set[bytes]
1680 supported: set[bytes]
1650 """Set of requirements that this repo is capable of opening."""
1681 """Set of requirements that this repo is capable of opening."""
1651
1682
1652 requirements: set[bytes]
1683 requirements: set[bytes]
1653 """Set of requirements this repo uses."""
1684 """Set of requirements this repo uses."""
1654
1685
1655 features: set[bytes]
1686 features: set[bytes]
1656 """Set of "features" this repository supports.
1687 """Set of "features" this repository supports.
1657
1688
1658 A "feature" is a loosely-defined term. It can refer to a feature
1689 A "feature" is a loosely-defined term. It can refer to a feature
1659 in the classical sense or can describe an implementation detail
1690 in the classical sense or can describe an implementation detail
1660 of the repository. For example, a ``readonly`` feature may denote
1691 of the repository. For example, a ``readonly`` feature may denote
1661 the repository as read-only. Or a ``revlogfilestore`` feature may
1692 the repository as read-only. Or a ``revlogfilestore`` feature may
1662 denote that the repository is using revlogs for file storage.
1693 denote that the repository is using revlogs for file storage.
1663
1694
1664 The intent of features is to provide a machine-queryable mechanism
1695 The intent of features is to provide a machine-queryable mechanism
1665 for repo consumers to test for various repository characteristics.
1696 for repo consumers to test for various repository characteristics.
1666
1697
1667 Features are similar to ``requirements``. The main difference is that
1698 Features are similar to ``requirements``. The main difference is that
1668 requirements are stored on-disk and represent requirements to open the
1699 requirements are stored on-disk and represent requirements to open the
1669 repository. Features are more run-time capabilities of the repository
1700 repository. Features are more run-time capabilities of the repository
1670 and more granular capabilities (which may be derived from requirements).
1701 and more granular capabilities (which may be derived from requirements).
1671 """
1702 """
1672
1703
1673 filtername: bytes
1704 filtername: bytes
1674 """Name of the repoview that is active on this repo."""
1705 """Name of the repoview that is active on this repo."""
1675
1706
1676 vfs_map: Mapping[bytes, Vfs]
1707 vfs_map: Mapping[bytes, Vfs]
1677 """a bytes-key β†’ vfs mapping used by transaction and others"""
1708 """a bytes-key β†’ vfs mapping used by transaction and others"""
1678
1709
1679 wvfs: Vfs
1710 wvfs: Vfs
1680 """VFS used to access the working directory."""
1711 """VFS used to access the working directory."""
1681
1712
1682 vfs: Vfs
1713 vfs: Vfs
1683 """VFS rooted at the .hg directory.
1714 """VFS rooted at the .hg directory.
1684
1715
1685 Used to access repository data not in the store.
1716 Used to access repository data not in the store.
1686 """
1717 """
1687
1718
1688 svfs: Vfs
1719 svfs: Vfs
1689 """VFS rooted at the store.
1720 """VFS rooted at the store.
1690
1721
1691 Used to access repository data in the store. Typically .hg/store.
1722 Used to access repository data in the store. Typically .hg/store.
1692 But can point elsewhere if the store is shared.
1723 But can point elsewhere if the store is shared.
1693 """
1724 """
1694
1725
1695 root: bytes
1726 root: bytes
1696 """Path to the root of the working directory."""
1727 """Path to the root of the working directory."""
1697
1728
1698 path: bytes
1729 path: bytes
1699 """Path to the .hg directory."""
1730 """Path to the .hg directory."""
1700
1731
1701 origroot: bytes
1732 origroot: bytes
1702 """The filesystem path that was used to construct the repo."""
1733 """The filesystem path that was used to construct the repo."""
1703
1734
1704 auditor: Any
1735 auditor: Any
1705 """A pathauditor for the working directory.
1736 """A pathauditor for the working directory.
1706
1737
1707 This checks if a path refers to a nested repository.
1738 This checks if a path refers to a nested repository.
1708
1739
1709 Operates on the filesystem.
1740 Operates on the filesystem.
1710 """
1741 """
1711
1742
1712 nofsauditor: Any # TODO: add type hints
1743 nofsauditor: Any # TODO: add type hints
1713 """A pathauditor for the working directory.
1744 """A pathauditor for the working directory.
1714
1745
1715 This is like ``auditor`` except it doesn't do filesystem checks.
1746 This is like ``auditor`` except it doesn't do filesystem checks.
1716 """
1747 """
1717
1748
1718 baseui: Ui
1749 baseui: Ui
1719 """Original ui instance passed into constructor."""
1750 """Original ui instance passed into constructor."""
1720
1751
1721 ui: Ui
1752 ui: Ui
1722 """Main ui instance for this instance."""
1753 """Main ui instance for this instance."""
1723
1754
1724 sharedpath: bytes
1755 sharedpath: bytes
1725 """Path to the .hg directory of the repo this repo was shared from."""
1756 """Path to the .hg directory of the repo this repo was shared from."""
1726
1757
1727 store: Any # TODO: add type hints
1758 store: Any # TODO: add type hints
1728 """A store instance."""
1759 """A store instance."""
1729
1760
1730 spath: bytes
1761 spath: bytes
1731 """Path to the store."""
1762 """Path to the store."""
1732
1763
1733 sjoin: Callable # TODO: add type hints
1764 sjoin: Callable # TODO: add type hints
1734 """Alias to self.store.join."""
1765 """Alias to self.store.join."""
1735
1766
1736 cachevfs: Vfs
1767 cachevfs: Vfs
1737 """A VFS used to access the cache directory.
1768 """A VFS used to access the cache directory.
1738
1769
1739 Typically .hg/cache.
1770 Typically .hg/cache.
1740 """
1771 """
1741
1772
1742 wcachevfs: Vfs
1773 wcachevfs: Vfs
1743 """A VFS used to access the cache directory dedicated to working copy
1774 """A VFS used to access the cache directory dedicated to working copy
1744
1775
1745 Typically .hg/wcache.
1776 Typically .hg/wcache.
1746 """
1777 """
1747
1778
1748 filteredrevcache: Any # TODO: add type hints
1779 filteredrevcache: Any # TODO: add type hints
1749 """Holds sets of revisions to be filtered."""
1780 """Holds sets of revisions to be filtered."""
1750
1781
1751 names: Any # TODO: add type hints
1782 names: Any # TODO: add type hints
1752 """A ``namespaces`` instance."""
1783 """A ``namespaces`` instance."""
1753
1784
1754 filecopiesmode: Any # TODO: add type hints
1785 filecopiesmode: Any # TODO: add type hints
1755 """The way files copies should be dealt with in this repo."""
1786 """The way files copies should be dealt with in this repo."""
1756
1787
1757 @abc.abstractmethod
1788 @abc.abstractmethod
1758 def close(self):
1789 def close(self):
1759 """Close the handle on this repository."""
1790 """Close the handle on this repository."""
1760
1791
1761 @abc.abstractmethod
1792 @abc.abstractmethod
1762 def peer(self, path=None):
1793 def peer(self, path=None):
1763 """Obtain an object conforming to the ``peer`` interface."""
1794 """Obtain an object conforming to the ``peer`` interface."""
1764
1795
1765 @abc.abstractmethod
1796 @abc.abstractmethod
1766 def unfiltered(self):
1797 def unfiltered(self):
1767 """Obtain an unfiltered/raw view of this repo."""
1798 """Obtain an unfiltered/raw view of this repo."""
1768
1799
1769 @abc.abstractmethod
1800 @abc.abstractmethod
1770 def filtered(self, name, visibilityexceptions=None):
1801 def filtered(self, name, visibilityexceptions=None):
1771 """Obtain a named view of this repository."""
1802 """Obtain a named view of this repository."""
1772
1803
1773 obsstore: Any # TODO: add type hints
1804 obsstore: Any # TODO: add type hints
1774 """A store of obsolescence data."""
1805 """A store of obsolescence data."""
1775
1806
1776 changelog: Any # TODO: add type hints
1807 changelog: Any # TODO: add type hints
1777 """A handle on the changelog revlog."""
1808 """A handle on the changelog revlog."""
1778
1809
1779 manifestlog: imanifestlog
1810 manifestlog: imanifestlog
1780 """An instance conforming to the ``imanifestlog`` interface.
1811 """An instance conforming to the ``imanifestlog`` interface.
1781
1812
1782 Provides access to manifests for the repository.
1813 Provides access to manifests for the repository.
1783 """
1814 """
1784
1815
1785 dirstate: intdirstate.idirstate
1816 dirstate: intdirstate.idirstate
1786 """Working directory state."""
1817 """Working directory state."""
1787
1818
1788 narrowpats: Any # TODO: add type hints
1819 narrowpats: Any # TODO: add type hints
1789 """Matcher patterns for this repository's narrowspec."""
1820 """Matcher patterns for this repository's narrowspec."""
1790
1821
1791 @abc.abstractmethod
1822 @abc.abstractmethod
1792 def narrowmatch(self, match=None, includeexact=False):
1823 def narrowmatch(self, match=None, includeexact=False):
1793 """Obtain a matcher for the narrowspec."""
1824 """Obtain a matcher for the narrowspec."""
1794
1825
1795 @abc.abstractmethod
1826 @abc.abstractmethod
1796 def setnarrowpats(self, newincludes, newexcludes):
1827 def setnarrowpats(self, newincludes, newexcludes):
1797 """Define the narrowspec for this repository."""
1828 """Define the narrowspec for this repository."""
1798
1829
1799 @abc.abstractmethod
1830 @abc.abstractmethod
1800 def __getitem__(self, changeid):
1831 def __getitem__(self, changeid):
1801 """Try to resolve a changectx."""
1832 """Try to resolve a changectx."""
1802
1833
1803 @abc.abstractmethod
1834 @abc.abstractmethod
1804 def __contains__(self, changeid):
1835 def __contains__(self, changeid):
1805 """Whether a changeset exists."""
1836 """Whether a changeset exists."""
1806
1837
1807 @abc.abstractmethod
1838 @abc.abstractmethod
1808 def __nonzero__(self):
1839 def __nonzero__(self):
1809 """Always returns True."""
1840 """Always returns True."""
1810 return True
1841 return True
1811
1842
1812 __bool__ = __nonzero__
1843 __bool__ = __nonzero__
1813
1844
1814 @abc.abstractmethod
1845 @abc.abstractmethod
1815 def __len__(self):
1846 def __len__(self):
1816 """Returns the number of changesets in the repo."""
1847 """Returns the number of changesets in the repo."""
1817
1848
1818 @abc.abstractmethod
1849 @abc.abstractmethod
1819 def __iter__(self):
1850 def __iter__(self):
1820 """Iterate over revisions in the changelog."""
1851 """Iterate over revisions in the changelog."""
1821
1852
1822 @abc.abstractmethod
1853 @abc.abstractmethod
1823 def revs(self, expr, *args):
1854 def revs(self, expr, *args):
1824 """Evaluate a revset.
1855 """Evaluate a revset.
1825
1856
1826 Emits revisions.
1857 Emits revisions.
1827 """
1858 """
1828
1859
1829 @abc.abstractmethod
1860 @abc.abstractmethod
1830 def set(self, expr, *args):
1861 def set(self, expr, *args):
1831 """Evaluate a revset.
1862 """Evaluate a revset.
1832
1863
1833 Emits changectx instances.
1864 Emits changectx instances.
1834 """
1865 """
1835
1866
1836 @abc.abstractmethod
1867 @abc.abstractmethod
1837 def anyrevs(self, specs, user=False, localalias=None):
1868 def anyrevs(self, specs, user=False, localalias=None):
1838 """Find revisions matching one of the given revsets."""
1869 """Find revisions matching one of the given revsets."""
1839
1870
1840 @abc.abstractmethod
1871 @abc.abstractmethod
1841 def url(self):
1872 def url(self):
1842 """Returns a string representing the location of this repo."""
1873 """Returns a string representing the location of this repo."""
1843
1874
1844 @abc.abstractmethod
1875 @abc.abstractmethod
1845 def hook(self, name, throw=False, **args):
1876 def hook(self, name, throw=False, **args):
1846 """Call a hook."""
1877 """Call a hook."""
1847
1878
1848 @abc.abstractmethod
1879 @abc.abstractmethod
1849 def tags(self):
1880 def tags(self):
1850 """Return a mapping of tag to node."""
1881 """Return a mapping of tag to node."""
1851
1882
1852 @abc.abstractmethod
1883 @abc.abstractmethod
1853 def tagtype(self, tagname):
1884 def tagtype(self, tagname):
1854 """Return the type of a given tag."""
1885 """Return the type of a given tag."""
1855
1886
1856 @abc.abstractmethod
1887 @abc.abstractmethod
1857 def tagslist(self):
1888 def tagslist(self):
1858 """Return a list of tags ordered by revision."""
1889 """Return a list of tags ordered by revision."""
1859
1890
1860 @abc.abstractmethod
1891 @abc.abstractmethod
1861 def nodetags(self, node):
1892 def nodetags(self, node):
1862 """Return the tags associated with a node."""
1893 """Return the tags associated with a node."""
1863
1894
1864 @abc.abstractmethod
1895 @abc.abstractmethod
1865 def nodebookmarks(self, node):
1896 def nodebookmarks(self, node):
1866 """Return the list of bookmarks pointing to the specified node."""
1897 """Return the list of bookmarks pointing to the specified node."""
1867
1898
1868 @abc.abstractmethod
1899 @abc.abstractmethod
1869 def branchmap(self):
1900 def branchmap(self):
1870 """Return a mapping of branch to heads in that branch."""
1901 """Return a mapping of branch to heads in that branch."""
1871
1902
1872 @abc.abstractmethod
1903 @abc.abstractmethod
1873 def revbranchcache(self):
1904 def revbranchcache(self):
1874 pass
1905 pass
1875
1906
1876 @abc.abstractmethod
1907 @abc.abstractmethod
1877 def register_changeset(self, rev, changelogrevision):
1908 def register_changeset(self, rev, changelogrevision):
1878 """Extension point for caches for new nodes.
1909 """Extension point for caches for new nodes.
1879
1910
1880 Multiple consumers are expected to need parts of the changelogrevision,
1911 Multiple consumers are expected to need parts of the changelogrevision,
1881 so it is provided as optimization to avoid duplicate lookups. A simple
1912 so it is provided as optimization to avoid duplicate lookups. A simple
1882 cache would be fragile when other revisions are accessed, too."""
1913 cache would be fragile when other revisions are accessed, too."""
1883 pass
1914 pass
1884
1915
1885 @abc.abstractmethod
1916 @abc.abstractmethod
1886 def branchtip(self, branchtip, ignoremissing=False):
1917 def branchtip(self, branchtip, ignoremissing=False):
1887 """Return the tip node for a given branch."""
1918 """Return the tip node for a given branch."""
1888
1919
1889 @abc.abstractmethod
1920 @abc.abstractmethod
1890 def lookup(self, key):
1921 def lookup(self, key):
1891 """Resolve the node for a revision."""
1922 """Resolve the node for a revision."""
1892
1923
1893 @abc.abstractmethod
1924 @abc.abstractmethod
1894 def lookupbranch(self, key):
1925 def lookupbranch(self, key):
1895 """Look up the branch name of the given revision or branch name."""
1926 """Look up the branch name of the given revision or branch name."""
1896
1927
1897 @abc.abstractmethod
1928 @abc.abstractmethod
1898 def known(self, nodes):
1929 def known(self, nodes):
1899 """Determine whether a series of nodes is known.
1930 """Determine whether a series of nodes is known.
1900
1931
1901 Returns a list of bools.
1932 Returns a list of bools.
1902 """
1933 """
1903
1934
1904 @abc.abstractmethod
1935 @abc.abstractmethod
1905 def local(self):
1936 def local(self):
1906 """Whether the repository is local."""
1937 """Whether the repository is local."""
1907 return True
1938 return True
1908
1939
1909 @abc.abstractmethod
1940 @abc.abstractmethod
1910 def publishing(self):
1941 def publishing(self):
1911 """Whether the repository is a publishing repository."""
1942 """Whether the repository is a publishing repository."""
1912
1943
1913 @abc.abstractmethod
1944 @abc.abstractmethod
1914 def cancopy(self):
1945 def cancopy(self):
1915 pass
1946 pass
1916
1947
1917 @abc.abstractmethod
1948 @abc.abstractmethod
1918 def shared(self):
1949 def shared(self):
1919 """The type of shared repository or None."""
1950 """The type of shared repository or None."""
1920
1951
1921 @abc.abstractmethod
1952 @abc.abstractmethod
1922 def wjoin(self, f, *insidef):
1953 def wjoin(self, f, *insidef):
1923 """Calls self.vfs.reljoin(self.root, f, *insidef)"""
1954 """Calls self.vfs.reljoin(self.root, f, *insidef)"""
1924
1955
1925 @abc.abstractmethod
1956 @abc.abstractmethod
1926 def setparents(self, p1, p2):
1957 def setparents(self, p1, p2):
1927 """Set the parent nodes of the working directory."""
1958 """Set the parent nodes of the working directory."""
1928
1959
1929 @abc.abstractmethod
1960 @abc.abstractmethod
1930 def filectx(self, path, changeid=None, fileid=None):
1961 def filectx(self, path, changeid=None, fileid=None):
1931 """Obtain a filectx for the given file revision."""
1962 """Obtain a filectx for the given file revision."""
1932
1963
1933 @abc.abstractmethod
1964 @abc.abstractmethod
1934 def getcwd(self):
1965 def getcwd(self):
1935 """Obtain the current working directory from the dirstate."""
1966 """Obtain the current working directory from the dirstate."""
1936
1967
1937 @abc.abstractmethod
1968 @abc.abstractmethod
1938 def pathto(self, f, cwd=None):
1969 def pathto(self, f, cwd=None):
1939 """Obtain the relative path to a file."""
1970 """Obtain the relative path to a file."""
1940
1971
1941 @abc.abstractmethod
1972 @abc.abstractmethod
1942 def adddatafilter(self, name, fltr):
1973 def adddatafilter(self, name, fltr):
1943 pass
1974 pass
1944
1975
1945 @abc.abstractmethod
1976 @abc.abstractmethod
1946 def wread(self, filename):
1977 def wread(self, filename):
1947 """Read a file from wvfs, using data filters."""
1978 """Read a file from wvfs, using data filters."""
1948
1979
1949 @abc.abstractmethod
1980 @abc.abstractmethod
1950 def wwrite(self, filename, data, flags, backgroundclose=False, **kwargs):
1981 def wwrite(self, filename, data, flags, backgroundclose=False, **kwargs):
1951 """Write data to a file in the wvfs, using data filters."""
1982 """Write data to a file in the wvfs, using data filters."""
1952
1983
1953 @abc.abstractmethod
1984 @abc.abstractmethod
1954 def wwritedata(self, filename, data):
1985 def wwritedata(self, filename, data):
1955 """Resolve data for writing to the wvfs, using data filters."""
1986 """Resolve data for writing to the wvfs, using data filters."""
1956
1987
1957 @abc.abstractmethod
1988 @abc.abstractmethod
1958 def currenttransaction(self):
1989 def currenttransaction(self):
1959 """Obtain the current transaction instance or None."""
1990 """Obtain the current transaction instance or None."""
1960
1991
1961 @abc.abstractmethod
1992 @abc.abstractmethod
1962 def transaction(self, desc, report=None):
1993 def transaction(self, desc, report=None):
1963 """Open a new transaction to write to the repository."""
1994 """Open a new transaction to write to the repository."""
1964
1995
1965 @abc.abstractmethod
1996 @abc.abstractmethod
1966 def undofiles(self):
1997 def undofiles(self):
1967 """Returns a list of (vfs, path) for files to undo transactions."""
1998 """Returns a list of (vfs, path) for files to undo transactions."""
1968
1999
1969 @abc.abstractmethod
2000 @abc.abstractmethod
1970 def recover(self):
2001 def recover(self):
1971 """Roll back an interrupted transaction."""
2002 """Roll back an interrupted transaction."""
1972
2003
1973 @abc.abstractmethod
2004 @abc.abstractmethod
1974 def rollback(self, dryrun=False, force=False):
2005 def rollback(self, dryrun=False, force=False):
1975 """Undo the last transaction.
2006 """Undo the last transaction.
1976
2007
1977 DANGEROUS.
2008 DANGEROUS.
1978 """
2009 """
1979
2010
1980 @abc.abstractmethod
2011 @abc.abstractmethod
1981 def updatecaches(self, tr=None, full=False, caches=None):
2012 def updatecaches(self, tr=None, full=False, caches=None):
1982 """Warm repo caches."""
2013 """Warm repo caches."""
1983
2014
1984 @abc.abstractmethod
2015 @abc.abstractmethod
1985 def invalidatecaches(self):
2016 def invalidatecaches(self):
1986 """Invalidate cached data due to the repository mutating."""
2017 """Invalidate cached data due to the repository mutating."""
1987
2018
1988 @abc.abstractmethod
2019 @abc.abstractmethod
1989 def invalidatevolatilesets(self):
2020 def invalidatevolatilesets(self):
1990 pass
2021 pass
1991
2022
1992 @abc.abstractmethod
2023 @abc.abstractmethod
1993 def invalidatedirstate(self):
2024 def invalidatedirstate(self):
1994 """Invalidate the dirstate."""
2025 """Invalidate the dirstate."""
1995
2026
1996 @abc.abstractmethod
2027 @abc.abstractmethod
1997 def invalidate(self, clearfilecache=False):
2028 def invalidate(self, clearfilecache=False):
1998 pass
2029 pass
1999
2030
2000 @abc.abstractmethod
2031 @abc.abstractmethod
2001 def invalidateall(self):
2032 def invalidateall(self):
2002 pass
2033 pass
2003
2034
2004 @abc.abstractmethod
2035 @abc.abstractmethod
2005 def lock(self, wait=True):
2036 def lock(self, wait=True):
2006 """Lock the repository store and return a lock instance."""
2037 """Lock the repository store and return a lock instance."""
2007
2038
2008 @abc.abstractmethod
2039 @abc.abstractmethod
2009 def currentlock(self):
2040 def currentlock(self):
2010 """Return the lock if it's held or None."""
2041 """Return the lock if it's held or None."""
2011
2042
2012 @abc.abstractmethod
2043 @abc.abstractmethod
2013 def wlock(self, wait=True):
2044 def wlock(self, wait=True):
2014 """Lock the non-store parts of the repository."""
2045 """Lock the non-store parts of the repository."""
2015
2046
2016 @abc.abstractmethod
2047 @abc.abstractmethod
2017 def currentwlock(self):
2048 def currentwlock(self):
2018 """Return the wlock if it's held or None."""
2049 """Return the wlock if it's held or None."""
2019
2050
2020 @abc.abstractmethod
2051 @abc.abstractmethod
2021 def checkcommitpatterns(self, wctx, match, status, fail):
2052 def checkcommitpatterns(self, wctx, match, status, fail):
2022 pass
2053 pass
2023
2054
2024 @abc.abstractmethod
2055 @abc.abstractmethod
2025 def commit(
2056 def commit(
2026 self,
2057 self,
2027 text=b'',
2058 text=b'',
2028 user=None,
2059 user=None,
2029 date=None,
2060 date=None,
2030 match=None,
2061 match=None,
2031 force=False,
2062 force=False,
2032 editor=False,
2063 editor=False,
2033 extra=None,
2064 extra=None,
2034 ):
2065 ):
2035 """Add a new revision to the repository."""
2066 """Add a new revision to the repository."""
2036
2067
2037 @abc.abstractmethod
2068 @abc.abstractmethod
2038 def commitctx(self, ctx, error=False, origctx=None):
2069 def commitctx(self, ctx, error=False, origctx=None):
2039 """Commit a commitctx instance to the repository."""
2070 """Commit a commitctx instance to the repository."""
2040
2071
2041 @abc.abstractmethod
2072 @abc.abstractmethod
2042 def destroying(self):
2073 def destroying(self):
2043 """Inform the repository that nodes are about to be destroyed."""
2074 """Inform the repository that nodes are about to be destroyed."""
2044
2075
2045 @abc.abstractmethod
2076 @abc.abstractmethod
2046 def destroyed(self):
2077 def destroyed(self):
2047 """Inform the repository that nodes have been destroyed."""
2078 """Inform the repository that nodes have been destroyed."""
2048
2079
2049 @abc.abstractmethod
2080 @abc.abstractmethod
2050 def status(
2081 def status(
2051 self,
2082 self,
2052 node1=b'.',
2083 node1=b'.',
2053 node2=None,
2084 node2=None,
2054 match=None,
2085 match=None,
2055 ignored=False,
2086 ignored=False,
2056 clean=False,
2087 clean=False,
2057 unknown=False,
2088 unknown=False,
2058 listsubrepos=False,
2089 listsubrepos=False,
2059 ):
2090 ):
2060 """Convenience method to call repo[x].status()."""
2091 """Convenience method to call repo[x].status()."""
2061
2092
2062 @abc.abstractmethod
2093 @abc.abstractmethod
2063 def addpostdsstatus(self, ps):
2094 def addpostdsstatus(self, ps):
2064 pass
2095 pass
2065
2096
2066 @abc.abstractmethod
2097 @abc.abstractmethod
2067 def postdsstatus(self):
2098 def postdsstatus(self):
2068 pass
2099 pass
2069
2100
2070 @abc.abstractmethod
2101 @abc.abstractmethod
2071 def clearpostdsstatus(self):
2102 def clearpostdsstatus(self):
2072 pass
2103 pass
2073
2104
2074 @abc.abstractmethod
2105 @abc.abstractmethod
2075 def heads(self, start=None):
2106 def heads(self, start=None):
2076 """Obtain list of nodes that are DAG heads."""
2107 """Obtain list of nodes that are DAG heads."""
2077
2108
2078 @abc.abstractmethod
2109 @abc.abstractmethod
2079 def branchheads(self, branch=None, start=None, closed=False):
2110 def branchheads(self, branch=None, start=None, closed=False):
2080 pass
2111 pass
2081
2112
2082 @abc.abstractmethod
2113 @abc.abstractmethod
2083 def branches(self, nodes):
2114 def branches(self, nodes):
2084 pass
2115 pass
2085
2116
2086 @abc.abstractmethod
2117 @abc.abstractmethod
2087 def between(self, pairs):
2118 def between(self, pairs):
2088 pass
2119 pass
2089
2120
2090 @abc.abstractmethod
2121 @abc.abstractmethod
2091 def checkpush(self, pushop):
2122 def checkpush(self, pushop):
2092 pass
2123 pass
2093
2124
2094 prepushoutgoinghooks: util.hooks
2125 prepushoutgoinghooks: util.hooks
2095 """util.hooks instance."""
2126 """util.hooks instance."""
2096
2127
2097 @abc.abstractmethod
2128 @abc.abstractmethod
2098 def pushkey(self, namespace, key, old, new):
2129 def pushkey(self, namespace, key, old, new):
2099 pass
2130 pass
2100
2131
2101 @abc.abstractmethod
2132 @abc.abstractmethod
2102 def listkeys(self, namespace):
2133 def listkeys(self, namespace):
2103 pass
2134 pass
2104
2135
2105 @abc.abstractmethod
2136 @abc.abstractmethod
2106 def debugwireargs(self, one, two, three=None, four=None, five=None):
2137 def debugwireargs(self, one, two, three=None, four=None, five=None):
2107 pass
2138 pass
2108
2139
2109 @abc.abstractmethod
2140 @abc.abstractmethod
2110 def savecommitmessage(self, text):
2141 def savecommitmessage(self, text):
2111 pass
2142 pass
2112
2143
2113 @abc.abstractmethod
2144 @abc.abstractmethod
2114 def register_sidedata_computer(
2145 def register_sidedata_computer(
2115 self, kind, category, keys, computer, flags, replace=False
2146 self, kind, category, keys, computer, flags, replace=False
2116 ):
2147 ):
2117 pass
2148 pass
2118
2149
2119 @abc.abstractmethod
2150 @abc.abstractmethod
2120 def register_wanted_sidedata(self, category):
2151 def register_wanted_sidedata(self, category):
2121 pass
2152 pass
2122
2153
2123
2154
2124 class completelocalrepository(
2155 class completelocalrepository(
2125 ilocalrepositorymain, ilocalrepositoryfilestorage
2156 ilocalrepositorymain, ilocalrepositoryfilestorage
2126 ):
2157 ):
2127 """Complete interface for a local repository."""
2158 """Complete interface for a local repository."""
2128
2159
2129
2160
2130 class iwireprotocolcommandcacher(Protocol):
2161 class iwireprotocolcommandcacher(Protocol):
2131 """Represents a caching backend for wire protocol commands.
2162 """Represents a caching backend for wire protocol commands.
2132
2163
2133 Wire protocol version 2 supports transparent caching of many commands.
2164 Wire protocol version 2 supports transparent caching of many commands.
2134 To leverage this caching, servers can activate objects that cache
2165 To leverage this caching, servers can activate objects that cache
2135 command responses. Objects handle both cache writing and reading.
2166 command responses. Objects handle both cache writing and reading.
2136 This interface defines how that response caching mechanism works.
2167 This interface defines how that response caching mechanism works.
2137
2168
2138 Wire protocol version 2 commands emit a series of objects that are
2169 Wire protocol version 2 commands emit a series of objects that are
2139 serialized and sent to the client. The caching layer exists between
2170 serialized and sent to the client. The caching layer exists between
2140 the invocation of the command function and the sending of its output
2171 the invocation of the command function and the sending of its output
2141 objects to an output layer.
2172 objects to an output layer.
2142
2173
2143 Instances of this interface represent a binding to a cache that
2174 Instances of this interface represent a binding to a cache that
2144 can serve a response (in place of calling a command function) and/or
2175 can serve a response (in place of calling a command function) and/or
2145 write responses to a cache for subsequent use.
2176 write responses to a cache for subsequent use.
2146
2177
2147 When a command request arrives, the following happens with regards
2178 When a command request arrives, the following happens with regards
2148 to this interface:
2179 to this interface:
2149
2180
2150 1. The server determines whether the command request is cacheable.
2181 1. The server determines whether the command request is cacheable.
2151 2. If it is, an instance of this interface is spawned.
2182 2. If it is, an instance of this interface is spawned.
2152 3. The cacher is activated in a context manager (``__enter__`` is called).
2183 3. The cacher is activated in a context manager (``__enter__`` is called).
2153 4. A cache *key* for that request is derived. This will call the
2184 4. A cache *key* for that request is derived. This will call the
2154 instance's ``adjustcachekeystate()`` method so the derivation
2185 instance's ``adjustcachekeystate()`` method so the derivation
2155 can be influenced.
2186 can be influenced.
2156 5. The cacher is informed of the derived cache key via a call to
2187 5. The cacher is informed of the derived cache key via a call to
2157 ``setcachekey()``.
2188 ``setcachekey()``.
2158 6. The cacher's ``lookup()`` method is called to test for presence of
2189 6. The cacher's ``lookup()`` method is called to test for presence of
2159 the derived key in the cache.
2190 the derived key in the cache.
2160 7. If ``lookup()`` returns a hit, that cached result is used in place
2191 7. If ``lookup()`` returns a hit, that cached result is used in place
2161 of invoking the command function. ``__exit__`` is called and the instance
2192 of invoking the command function. ``__exit__`` is called and the instance
2162 is discarded.
2193 is discarded.
2163 8. The command function is invoked.
2194 8. The command function is invoked.
2164 9. ``onobject()`` is called for each object emitted by the command
2195 9. ``onobject()`` is called for each object emitted by the command
2165 function.
2196 function.
2166 10. After the final object is seen, ``onfinished()`` is called.
2197 10. After the final object is seen, ``onfinished()`` is called.
2167 11. ``__exit__`` is called to signal the end of use of the instance.
2198 11. ``__exit__`` is called to signal the end of use of the instance.
2168
2199
2169 Cache *key* derivation can be influenced by the instance.
2200 Cache *key* derivation can be influenced by the instance.
2170
2201
2171 Cache keys are initially derived by a deterministic representation of
2202 Cache keys are initially derived by a deterministic representation of
2172 the command request. This includes the command name, arguments, protocol
2203 the command request. This includes the command name, arguments, protocol
2173 version, etc. This initial key derivation is performed by CBOR-encoding a
2204 version, etc. This initial key derivation is performed by CBOR-encoding a
2174 data structure and feeding that output into a hasher.
2205 data structure and feeding that output into a hasher.
2175
2206
2176 Instances of this interface can influence this initial key derivation
2207 Instances of this interface can influence this initial key derivation
2177 via ``adjustcachekeystate()``.
2208 via ``adjustcachekeystate()``.
2178
2209
2179 The instance is informed of the derived cache key via a call to
2210 The instance is informed of the derived cache key via a call to
2180 ``setcachekey()``. The instance must store the key locally so it can
2211 ``setcachekey()``. The instance must store the key locally so it can
2181 be consulted on subsequent operations that may require it.
2212 be consulted on subsequent operations that may require it.
2182
2213
2183 When constructed, the instance has access to a callable that can be used
2214 When constructed, the instance has access to a callable that can be used
2184 for encoding response objects. This callable receives as its single
2215 for encoding response objects. This callable receives as its single
2185 argument an object emitted by a command function. It returns an iterable
2216 argument an object emitted by a command function. It returns an iterable
2186 of bytes chunks representing the encoded object. Unless the cacher is
2217 of bytes chunks representing the encoded object. Unless the cacher is
2187 caching native Python objects in memory or has a way of reconstructing
2218 caching native Python objects in memory or has a way of reconstructing
2188 the original Python objects, implementations typically call this function
2219 the original Python objects, implementations typically call this function
2189 to produce bytes from the output objects and then store those bytes in
2220 to produce bytes from the output objects and then store those bytes in
2190 the cache. When it comes time to re-emit those bytes, they are wrapped
2221 the cache. When it comes time to re-emit those bytes, they are wrapped
2191 in a ``wireprototypes.encodedresponse`` instance to tell the output
2222 in a ``wireprototypes.encodedresponse`` instance to tell the output
2192 layer that they are pre-encoded.
2223 layer that they are pre-encoded.
2193
2224
2194 When receiving the objects emitted by the command function, instances
2225 When receiving the objects emitted by the command function, instances
2195 can choose what to do with those objects. The simplest thing to do is
2226 can choose what to do with those objects. The simplest thing to do is
2196 re-emit the original objects. They will be forwarded to the output
2227 re-emit the original objects. They will be forwarded to the output
2197 layer and will be processed as if the cacher did not exist.
2228 layer and will be processed as if the cacher did not exist.
2198
2229
2199 Implementations could also choose to not emit objects - instead locally
2230 Implementations could also choose to not emit objects - instead locally
2200 buffering objects or their encoded representation. They could then emit
2231 buffering objects or their encoded representation. They could then emit
2201 a single "coalesced" object when ``onfinished()`` is called. In
2232 a single "coalesced" object when ``onfinished()`` is called. In
2202 this way, the implementation would function as a filtering layer of
2233 this way, the implementation would function as a filtering layer of
2203 sorts.
2234 sorts.
2204
2235
2205 When caching objects, typically the encoded form of the object will
2236 When caching objects, typically the encoded form of the object will
2206 be stored. Keep in mind that if the original object is forwarded to
2237 be stored. Keep in mind that if the original object is forwarded to
2207 the output layer, it will need to be encoded there as well. For large
2238 the output layer, it will need to be encoded there as well. For large
2208 output, this redundant encoding could add overhead. Implementations
2239 output, this redundant encoding could add overhead. Implementations
2209 could wrap the encoded object data in ``wireprototypes.encodedresponse``
2240 could wrap the encoded object data in ``wireprototypes.encodedresponse``
2210 instances to avoid this overhead.
2241 instances to avoid this overhead.
2211 """
2242 """
2212
2243
2213 def __enter__(self):
2244 def __enter__(self):
2214 """Marks the instance as active.
2245 """Marks the instance as active.
2215
2246
2216 Should return self.
2247 Should return self.
2217 """
2248 """
2218
2249
2219 def __exit__(self, exctype, excvalue, exctb):
2250 def __exit__(self, exctype, excvalue, exctb):
2220 """Called when cacher is no longer used.
2251 """Called when cacher is no longer used.
2221
2252
2222 This can be used by implementations to perform cleanup actions (e.g.
2253 This can be used by implementations to perform cleanup actions (e.g.
2223 disconnecting network sockets, aborting a partially cached response.
2254 disconnecting network sockets, aborting a partially cached response.
2224 """
2255 """
2225
2256
2226 def adjustcachekeystate(self, state):
2257 def adjustcachekeystate(self, state):
2227 """Influences cache key derivation by adjusting state to derive key.
2258 """Influences cache key derivation by adjusting state to derive key.
2228
2259
2229 A dict defining the state used to derive the cache key is passed.
2260 A dict defining the state used to derive the cache key is passed.
2230
2261
2231 Implementations can modify this dict to record additional state that
2262 Implementations can modify this dict to record additional state that
2232 is wanted to influence key derivation.
2263 is wanted to influence key derivation.
2233
2264
2234 Implementations are *highly* encouraged to not modify or delete
2265 Implementations are *highly* encouraged to not modify or delete
2235 existing keys.
2266 existing keys.
2236 """
2267 """
2237
2268
2238 def setcachekey(self, key):
2269 def setcachekey(self, key):
2239 """Record the derived cache key for this request.
2270 """Record the derived cache key for this request.
2240
2271
2241 Instances may mutate the key for internal usage, as desired. e.g.
2272 Instances may mutate the key for internal usage, as desired. e.g.
2242 instances may wish to prepend the repo name, introduce path
2273 instances may wish to prepend the repo name, introduce path
2243 components for filesystem or URL addressing, etc. Behavior is up to
2274 components for filesystem or URL addressing, etc. Behavior is up to
2244 the cache.
2275 the cache.
2245
2276
2246 Returns a bool indicating if the request is cacheable by this
2277 Returns a bool indicating if the request is cacheable by this
2247 instance.
2278 instance.
2248 """
2279 """
2249
2280
2250 def lookup(self):
2281 def lookup(self):
2251 """Attempt to resolve an entry in the cache.
2282 """Attempt to resolve an entry in the cache.
2252
2283
2253 The instance is instructed to look for the cache key that it was
2284 The instance is instructed to look for the cache key that it was
2254 informed about via the call to ``setcachekey()``.
2285 informed about via the call to ``setcachekey()``.
2255
2286
2256 If there's no cache hit or the cacher doesn't wish to use the cached
2287 If there's no cache hit or the cacher doesn't wish to use the cached
2257 entry, ``None`` should be returned.
2288 entry, ``None`` should be returned.
2258
2289
2259 Else, a dict defining the cached result should be returned. The
2290 Else, a dict defining the cached result should be returned. The
2260 dict may have the following keys:
2291 dict may have the following keys:
2261
2292
2262 objs
2293 objs
2263 An iterable of objects that should be sent to the client. That
2294 An iterable of objects that should be sent to the client. That
2264 iterable of objects is expected to be what the command function
2295 iterable of objects is expected to be what the command function
2265 would return if invoked or an equivalent representation thereof.
2296 would return if invoked or an equivalent representation thereof.
2266 """
2297 """
2267
2298
2268 def onobject(self, obj):
2299 def onobject(self, obj):
2269 """Called when a new object is emitted from the command function.
2300 """Called when a new object is emitted from the command function.
2270
2301
2271 Receives as its argument the object that was emitted from the
2302 Receives as its argument the object that was emitted from the
2272 command function.
2303 command function.
2273
2304
2274 This method returns an iterator of objects to forward to the output
2305 This method returns an iterator of objects to forward to the output
2275 layer. The easiest implementation is a generator that just
2306 layer. The easiest implementation is a generator that just
2276 ``yield obj``.
2307 ``yield obj``.
2277 """
2308 """
2278
2309
2279 def onfinished(self):
2310 def onfinished(self):
2280 """Called after all objects have been emitted from the command function.
2311 """Called after all objects have been emitted from the command function.
2281
2312
2282 Implementations should return an iterator of objects to forward to
2313 Implementations should return an iterator of objects to forward to
2283 the output layer.
2314 the output layer.
2284
2315
2285 This method can be a generator.
2316 This method can be a generator.
2286 """
2317 """
General Comments 0
You need to be logged in to leave comments. Login now