##// END OF EJS Templates
typing: make the filelog class known to pytype...
Matt Harbison -
r52715:e78b75f3 default
parent child Browse files
Show More
@@ -1,312 +1,319
1 1 # filelog.py - file history class for mercurial
2 2 #
3 3 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8
9 import typing
10
9 11 from .i18n import _
10 12 from .node import nullrev
11 13 from . import (
12 14 error,
13 15 revlog,
14 16 )
15 17 from .interfaces import (
16 18 repository,
17 19 util as interfaceutil,
18 20 )
19 21 from .utils import storageutil
20 22 from .revlogutils import (
21 23 constants as revlog_constants,
22 24 rewrite,
23 25 )
24 26
25 27
26 @interfaceutil.implementer(repository.ifilestorage)
27 class filelog:
28 class FileLog:
28 29 def __init__(self, opener, path, try_split=False):
29 30 self._revlog = revlog.revlog(
30 31 opener,
31 32 # XXX should use the unencoded path
32 33 target=(revlog_constants.KIND_FILELOG, path),
33 34 radix=b'/'.join((b'data', path)),
34 35 censorable=True,
35 36 canonical_parent_order=False, # see comment in revlog.py
36 37 try_split=try_split,
37 38 )
38 39 # Full name of the user visible file, relative to the repository root.
39 40 # Used by LFS.
40 41 self._revlog.filename = path
41 42 self.nullid = self._revlog.nullid
42 43 opts = opener.options
43 44 self._fix_issue6528 = opts.get(b'issue6528.fix-incoming', True)
44 45
45 46 def get_revlog(self):
46 47 """return an actual revlog instance if any
47 48
48 49 This exist because a lot of code leverage the fact the underlying
49 50 storage is a revlog for optimization, so giving simple way to access
50 51 the revlog instance helps such code.
51 52 """
52 53 return self._revlog
53 54
54 55 def __len__(self):
55 56 return len(self._revlog)
56 57
57 58 def __iter__(self):
58 59 return self._revlog.__iter__()
59 60
60 61 def hasnode(self, node):
61 62 if node in (self.nullid, nullrev):
62 63 return False
63 64
64 65 try:
65 66 self._revlog.rev(node)
66 67 return True
67 68 except (TypeError, ValueError, IndexError, error.LookupError):
68 69 return False
69 70
70 71 def revs(self, start=0, stop=None):
71 72 return self._revlog.revs(start=start, stop=stop)
72 73
73 74 def parents(self, node):
74 75 return self._revlog.parents(node)
75 76
76 77 def parentrevs(self, rev):
77 78 return self._revlog.parentrevs(rev)
78 79
79 80 def rev(self, node):
80 81 return self._revlog.rev(node)
81 82
82 83 def node(self, rev):
83 84 return self._revlog.node(rev)
84 85
85 86 def lookup(self, node):
86 87 return storageutil.fileidlookup(
87 88 self._revlog, node, self._revlog.display_id
88 89 )
89 90
90 91 def linkrev(self, rev):
91 92 return self._revlog.linkrev(rev)
92 93
93 94 def commonancestorsheads(self, node1, node2):
94 95 return self._revlog.commonancestorsheads(node1, node2)
95 96
96 97 # Used by dagop.blockdescendants().
97 98 def descendants(self, revs):
98 99 return self._revlog.descendants(revs)
99 100
100 101 def heads(self, start=None, stop=None):
101 102 return self._revlog.heads(start, stop)
102 103
103 104 # Used by hgweb, children extension.
104 105 def children(self, node):
105 106 return self._revlog.children(node)
106 107
107 108 def iscensored(self, rev):
108 109 return self._revlog.iscensored(rev)
109 110
110 111 def revision(self, node):
111 112 return self._revlog.revision(node)
112 113
113 114 def rawdata(self, node):
114 115 return self._revlog.rawdata(node)
115 116
116 117 def emitrevisions(
117 118 self,
118 119 nodes,
119 120 nodesorder=None,
120 121 revisiondata=False,
121 122 assumehaveparentrevisions=False,
122 123 deltamode=repository.CG_DELTAMODE_STD,
123 124 sidedata_helpers=None,
124 125 debug_info=None,
125 126 ):
126 127 return self._revlog.emitrevisions(
127 128 nodes,
128 129 nodesorder=nodesorder,
129 130 revisiondata=revisiondata,
130 131 assumehaveparentrevisions=assumehaveparentrevisions,
131 132 deltamode=deltamode,
132 133 sidedata_helpers=sidedata_helpers,
133 134 debug_info=debug_info,
134 135 )
135 136
136 137 def addrevision(
137 138 self,
138 139 revisiondata,
139 140 transaction,
140 141 linkrev,
141 142 p1,
142 143 p2,
143 144 node=None,
144 145 flags=revlog.REVIDX_DEFAULT_FLAGS,
145 146 cachedelta=None,
146 147 ):
147 148 return self._revlog.addrevision(
148 149 revisiondata,
149 150 transaction,
150 151 linkrev,
151 152 p1,
152 153 p2,
153 154 node=node,
154 155 flags=flags,
155 156 cachedelta=cachedelta,
156 157 )
157 158
158 159 def addgroup(
159 160 self,
160 161 deltas,
161 162 linkmapper,
162 163 transaction,
163 164 addrevisioncb=None,
164 165 duplicaterevisioncb=None,
165 166 maybemissingparents=False,
166 167 debug_info=None,
167 168 delta_base_reuse_policy=None,
168 169 ):
169 170 if maybemissingparents:
170 171 raise error.Abort(
171 172 _(
172 173 b'revlog storage does not support missing '
173 174 b'parents write mode'
174 175 )
175 176 )
176 177
177 178 with self._revlog._writing(transaction):
178 179 if self._fix_issue6528:
179 180 deltas = rewrite.filter_delta_issue6528(self._revlog, deltas)
180 181
181 182 return self._revlog.addgroup(
182 183 deltas,
183 184 linkmapper,
184 185 transaction,
185 186 addrevisioncb=addrevisioncb,
186 187 duplicaterevisioncb=duplicaterevisioncb,
187 188 debug_info=debug_info,
188 189 delta_base_reuse_policy=delta_base_reuse_policy,
189 190 )
190 191
191 192 def getstrippoint(self, minlink):
192 193 return self._revlog.getstrippoint(minlink)
193 194
194 195 def strip(self, minlink, transaction):
195 196 return self._revlog.strip(minlink, transaction)
196 197
197 198 def censorrevision(self, tr, node, tombstone=b''):
198 199 return self._revlog.censorrevision(tr, node, tombstone=tombstone)
199 200
200 201 def files(self):
201 202 return self._revlog.files()
202 203
203 204 def read(self, node):
204 205 return storageutil.filtermetadata(self.revision(node))
205 206
206 207 def add(self, text, meta, transaction, link, p1=None, p2=None):
207 208 if meta or text.startswith(b'\1\n'):
208 209 text = storageutil.packmeta(meta, text)
209 210 rev = self.addrevision(text, transaction, link, p1, p2)
210 211 return self.node(rev)
211 212
212 213 def renamed(self, node):
213 214 return storageutil.filerevisioncopied(self, node)
214 215
215 216 def size(self, rev):
216 217 """return the size of a given revision"""
217 218
218 219 # for revisions with renames, we have to go the slow way
219 220 node = self.node(rev)
220 221 if self.iscensored(rev):
221 222 return 0
222 223 if self.renamed(node):
223 224 return len(self.read(node))
224 225
225 226 # XXX if self.read(node).startswith("\1\n"), this returns (size+4)
226 227 # XXX See also basefilectx.cmp.
227 228 return self._revlog.size(rev)
228 229
229 230 def cmp(self, node, text):
230 231 """compare text with a given file revision
231 232
232 233 returns True if text is different than what is stored.
233 234 """
234 235 return not storageutil.filedataequivalent(self, node, text)
235 236
236 237 def verifyintegrity(self, state):
237 238 return self._revlog.verifyintegrity(state)
238 239
239 240 def storageinfo(
240 241 self,
241 242 exclusivefiles=False,
242 243 sharedfiles=False,
243 244 revisionscount=False,
244 245 trackedsize=False,
245 246 storedsize=False,
246 247 ):
247 248 return self._revlog.storageinfo(
248 249 exclusivefiles=exclusivefiles,
249 250 sharedfiles=sharedfiles,
250 251 revisionscount=revisionscount,
251 252 trackedsize=trackedsize,
252 253 storedsize=storedsize,
253 254 )
254 255
255 256 # Used by repo upgrade.
256 257 def clone(self, tr, destrevlog, **kwargs):
257 258 if not isinstance(destrevlog, filelog):
258 259 msg = b'expected filelog to clone(), not %r'
259 260 msg %= destrevlog
260 261 raise error.ProgrammingError(msg)
261 262
262 263 return self._revlog.clone(tr, destrevlog._revlog, **kwargs)
263 264
264 265
266 filelog = interfaceutil.implementer(repository.ifilestorage)(FileLog)
267
268 if typing.TYPE_CHECKING:
269 filelog = FileLog
270
271
265 272 class narrowfilelog(filelog):
266 273 """Filelog variation to be used with narrow stores."""
267 274
268 275 def __init__(self, opener, path, narrowmatch, try_split=False):
269 276 super(narrowfilelog, self).__init__(opener, path, try_split=try_split)
270 277 self._narrowmatch = narrowmatch
271 278
272 279 def renamed(self, node):
273 280 res = super(narrowfilelog, self).renamed(node)
274 281
275 282 # Renames that come from outside the narrowspec are problematic
276 283 # because we may lack the base text for the rename. This can result
277 284 # in code attempting to walk the ancestry or compute a diff
278 285 # encountering a missing revision. We address this by silently
279 286 # removing rename metadata if the source file is outside the
280 287 # narrow spec.
281 288 #
282 289 # A better solution would be to see if the base revision is available,
283 290 # rather than assuming it isn't.
284 291 #
285 292 # An even better solution would be to teach all consumers of rename
286 293 # metadata that the base revision may not be available.
287 294 #
288 295 # TODO consider better ways of doing this.
289 296 if res and not self._narrowmatch(res[0]):
290 297 return None
291 298
292 299 return res
293 300
294 301 def size(self, rev):
295 302 # Because we have a custom renamed() that may lie, we need to call
296 303 # the base renamed() to report accurate results.
297 304 node = self.node(rev)
298 305 if super(narrowfilelog, self).renamed(node):
299 306 return len(self.read(node))
300 307 else:
301 308 return super(narrowfilelog, self).size(rev)
302 309
303 310 def cmp(self, node, text):
304 311 # We don't call `super` because narrow parents can be buggy in case of a
305 312 # ambiguous dirstate. Always take the slow path until there is a better
306 313 # fix, see issue6150.
307 314
308 315 # Censored files compare against the empty file.
309 316 if self.iscensored(self.rev(node)):
310 317 return text != b''
311 318
312 319 return self.read(node) != text
General Comments 0
You need to be logged in to leave comments. Login now