Show More
@@ -233,10 +233,61 b' class InlinedIndexObject(BaseIndexObject' | |||||
233 | return self._offsets[i] |
|
233 | return self._offsets[i] | |
234 |
|
234 | |||
235 |
|
235 | |||
236 | def parse_index2(data, inline): |
|
236 | def parse_index2(data, inline, revlogv2=False): | |
237 | if not inline: |
|
237 | if not inline: | |
238 | return IndexObject(data), None |
|
238 | cls = IndexObject2 if revlogv2 else IndexObject | |
239 | return InlinedIndexObject(data, inline), (0, data) |
|
239 | return cls(data), None | |
|
240 | cls = InlinedIndexObject2 if revlogv2 else InlinedIndexObject | |||
|
241 | return cls(data, inline), (0, data) | |||
|
242 | ||||
|
243 | ||||
|
244 | class Index2Mixin(object): | |||
|
245 | # 6 bytes: offset | |||
|
246 | # 2 bytes: flags | |||
|
247 | # 4 bytes: compressed length | |||
|
248 | # 4 bytes: uncompressed length | |||
|
249 | # 4 bytes: base rev | |||
|
250 | # 4 bytes: link rev | |||
|
251 | # 4 bytes: parent 1 rev | |||
|
252 | # 4 bytes: parent 2 rev | |||
|
253 | # 32 bytes: nodeid | |||
|
254 | # 8 bytes: sidedata offset | |||
|
255 | # 4 bytes: sidedata compressed length | |||
|
256 | # 20 bytes: Padding to align to 96 bytes (see RevlogV2Plan wiki page) | |||
|
257 | index_format = b">Qiiiiii20s12xQi20x" | |||
|
258 | index_size = struct.calcsize(index_format) | |||
|
259 | assert index_size == 96, index_size | |||
|
260 | null_item = (0, 0, 0, -1, -1, -1, -1, nullid, 0, 0) | |||
|
261 | ||||
|
262 | ||||
|
263 | class IndexObject2(Index2Mixin, IndexObject): | |||
|
264 | pass | |||
|
265 | ||||
|
266 | ||||
|
267 | class InlinedIndexObject2(Index2Mixin, InlinedIndexObject): | |||
|
268 | def _inline_scan(self, lgt): | |||
|
269 | sidedata_length_pos = 72 | |||
|
270 | off = 0 | |||
|
271 | if lgt is not None: | |||
|
272 | self._offsets = [0] * lgt | |||
|
273 | count = 0 | |||
|
274 | while off <= len(self._data) - self.index_size: | |||
|
275 | start = off + self.big_int_size | |||
|
276 | (data_size,) = struct.unpack( | |||
|
277 | b'>i', | |||
|
278 | self._data[start : start + self.int_size], | |||
|
279 | ) | |||
|
280 | start = off + sidedata_length_pos | |||
|
281 | (side_data_size,) = struct.unpack( | |||
|
282 | b'>i', self._data[start : start + self.int_size] | |||
|
283 | ) | |||
|
284 | if lgt is not None: | |||
|
285 | self._offsets[count] = off | |||
|
286 | count += 1 | |||
|
287 | off += self.index_size + data_size + side_data_size | |||
|
288 | if off != len(self._data): | |||
|
289 | raise ValueError(b"corrupted data") | |||
|
290 | return count | |||
240 |
|
291 | |||
241 |
|
292 | |||
242 | def parse_index_devel_nodemap(data, inline): |
|
293 | def parse_index_devel_nodemap(data, inline): |
@@ -30,7 +30,7 b" REVLOGV1_REQUIREMENT = b'revlogv1'" | |||||
30 |
|
30 | |||
31 | # Increment the sub-version when the revlog v2 format changes to lock out old |
|
31 | # Increment the sub-version when the revlog v2 format changes to lock out old | |
32 | # clients. |
|
32 | # clients. | |
33 |
REVLOGV2_REQUIREMENT = b'exp-revlogv2. |
|
33 | REVLOGV2_REQUIREMENT = b'exp-revlogv2.2' | |
34 |
|
34 | |||
35 | # A repository with the sparserevlog feature will have delta chains that |
|
35 | # A repository with the sparserevlog feature will have delta chains that | |
36 | # can spread over a larger span. Sparse reading cuts these large spans into |
|
36 | # can spread over a larger span. Sparse reading cuts these large spans into |
@@ -83,6 +83,7 b' from .utils import (' | |||||
83 | storageutil, |
|
83 | storageutil, | |
84 | stringutil, |
|
84 | stringutil, | |
85 | ) |
|
85 | ) | |
|
86 | from .pure import parsers as pureparsers | |||
86 |
|
87 | |||
87 | # blanked usage of all the name to prevent pyflakes constraints |
|
88 | # blanked usage of all the name to prevent pyflakes constraints | |
88 | # We need these name available in the module for extensions. |
|
89 | # We need these name available in the module for extensions. | |
@@ -364,6 +365,25 b' class revlogio(object):' | |||||
364 | return p |
|
365 | return p | |
365 |
|
366 | |||
366 |
|
367 | |||
|
368 | indexformatv2 = struct.Struct(pureparsers.Index2Mixin.index_format) | |||
|
369 | indexformatv2_pack = indexformatv2.pack | |||
|
370 | ||||
|
371 | ||||
|
372 | class revlogv2io(object): | |||
|
373 | def __init__(self): | |||
|
374 | self.size = indexformatv2.size | |||
|
375 | ||||
|
376 | def parseindex(self, data, inline): | |||
|
377 | index, cache = parsers.parse_index2(data, inline, revlogv2=True) | |||
|
378 | return index, cache | |||
|
379 | ||||
|
380 | def packentry(self, entry, node, version, rev): | |||
|
381 | p = indexformatv2_pack(*entry) | |||
|
382 | if rev == 0: | |||
|
383 | p = versionformat_pack(version) + p[4:] | |||
|
384 | return p | |||
|
385 | ||||
|
386 | ||||
367 | NodemapRevlogIO = None |
|
387 | NodemapRevlogIO = None | |
368 |
|
388 | |||
369 | if util.safehasattr(parsers, 'parse_index_devel_nodemap'): |
|
389 | if util.safehasattr(parsers, 'parse_index_devel_nodemap'): | |
@@ -650,6 +670,8 b' class revlog(object):' | |||||
650 | self._io = revlogio() |
|
670 | self._io = revlogio() | |
651 | if self.version == REVLOGV0: |
|
671 | if self.version == REVLOGV0: | |
652 | self._io = revlogoldio() |
|
672 | self._io = revlogoldio() | |
|
673 | elif fmt == REVLOGV2: | |||
|
674 | self._io = revlogv2io() | |||
653 | elif devel_nodemap: |
|
675 | elif devel_nodemap: | |
654 | self._io = NodemapRevlogIO() |
|
676 | self._io = NodemapRevlogIO() | |
655 | elif use_rust_index: |
|
677 | elif use_rust_index: | |
@@ -2337,7 +2359,13 b' class revlog(object):' | |||||
2337 | p1r, |
|
2359 | p1r, | |
2338 | p2r, |
|
2360 | p2r, | |
2339 | node, |
|
2361 | node, | |
|
2362 | 0, | |||
|
2363 | 0, | |||
2340 | ) |
|
2364 | ) | |
|
2365 | ||||
|
2366 | if self.version & 0xFFFF != REVLOGV2: | |||
|
2367 | e = e[:8] | |||
|
2368 | ||||
2341 | self.index.append(e) |
|
2369 | self.index.append(e) | |
2342 |
|
2370 | |||
2343 | entry = self._io.packentry(e, self.node, self.version, curr) |
|
2371 | entry = self._io.packentry(e, self.node, self.version, curr) |
@@ -15,7 +15,6 b' from ..interfaces import repository' | |||||
15 | REVLOGV0 = 0 |
|
15 | REVLOGV0 = 0 | |
16 | REVLOGV1 = 1 |
|
16 | REVLOGV1 = 1 | |
17 | # Dummy value until file format is finalized. |
|
17 | # Dummy value until file format is finalized. | |
18 | # Reminder: change the bounds check in revlog.__init__ when this is changed. |
|
|||
19 | REVLOGV2 = 0xDEAD |
|
18 | REVLOGV2 = 0xDEAD | |
20 | # Shared across v1 and v2. |
|
19 | # Shared across v1 and v2. | |
21 | FLAG_INLINE_DATA = 1 << 16 |
|
20 | FLAG_INLINE_DATA = 1 << 16 |
@@ -117,8 +117,8 b' data_non_inlined = (' | |||||
117 | ) |
|
117 | ) | |
118 |
|
118 | |||
119 |
|
119 | |||
120 | def parse_index2(data, inline): |
|
120 | def parse_index2(data, inline, revlogv2=False): | |
121 | index, chunkcache = parsers.parse_index2(data, inline) |
|
121 | index, chunkcache = parsers.parse_index2(data, inline, revlogv2=revlogv2) | |
122 | return list(index), chunkcache |
|
122 | return list(index), chunkcache | |
123 |
|
123 | |||
124 |
|
124 |
@@ -22,7 +22,7 b' Can create and open repo with revlog v2 ' | |||||
22 | $ cd empty-repo |
|
22 | $ cd empty-repo | |
23 | $ cat .hg/requires |
|
23 | $ cat .hg/requires | |
24 | dotencode |
|
24 | dotencode | |
25 |
exp-revlogv2. |
|
25 | exp-revlogv2.2 | |
26 | fncache |
|
26 | fncache | |
27 | sparserevlog |
|
27 | sparserevlog | |
28 | store |
|
28 | store |
@@ -22,10 +22,10 b' Unknown flags on revlog version 1 are re' | |||||
22 | Unknown version is rejected |
|
22 | Unknown version is rejected | |
23 |
|
23 | |||
24 | >>> with open('.hg/store/00changelog.i', 'wb') as fh: |
|
24 | >>> with open('.hg/store/00changelog.i', 'wb') as fh: | |
25 |
... fh.write(b'\x00\x00\x |
|
25 | ... fh.write(b'\x00\x00\xbe\xef') and None | |
26 |
|
26 | |||
27 | $ hg log |
|
27 | $ hg log | |
28 |
abort: unknown version ( |
|
28 | abort: unknown version (48879) in revlog 00changelog.i | |
29 | [50] |
|
29 | [50] | |
30 |
|
30 | |||
31 | $ cd .. |
|
31 | $ cd .. |
General Comments 0
You need to be logged in to leave comments.
Login now