Show More
@@ -233,10 +233,61 b' class InlinedIndexObject(BaseIndexObject' | |||
|
233 | 233 | return self._offsets[i] |
|
234 | 234 | |
|
235 | 235 | |
|
236 | def parse_index2(data, inline): | |
|
236 | def parse_index2(data, inline, revlogv2=False): | |
|
237 | 237 | if not inline: |
|
238 | return IndexObject(data), None | |
|
239 | return InlinedIndexObject(data, inline), (0, data) | |
|
238 | cls = IndexObject2 if revlogv2 else IndexObject | |
|
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 | 293 | def parse_index_devel_nodemap(data, inline): |
@@ -30,7 +30,7 b" REVLOGV1_REQUIREMENT = b'revlogv1'" | |||
|
30 | 30 | |
|
31 | 31 | # Increment the sub-version when the revlog v2 format changes to lock out old |
|
32 | 32 | # clients. |
|
33 |
REVLOGV2_REQUIREMENT = b'exp-revlogv2. |
|
|
33 | REVLOGV2_REQUIREMENT = b'exp-revlogv2.2' | |
|
34 | 34 | |
|
35 | 35 | # A repository with the sparserevlog feature will have delta chains that |
|
36 | 36 | # can spread over a larger span. Sparse reading cuts these large spans into |
@@ -83,6 +83,7 b' from .utils import (' | |||
|
83 | 83 | storageutil, |
|
84 | 84 | stringutil, |
|
85 | 85 | ) |
|
86 | from .pure import parsers as pureparsers | |
|
86 | 87 | |
|
87 | 88 | # blanked usage of all the name to prevent pyflakes constraints |
|
88 | 89 | # We need these name available in the module for extensions. |
@@ -364,6 +365,25 b' class revlogio(object):' | |||
|
364 | 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 | 387 | NodemapRevlogIO = None |
|
368 | 388 | |
|
369 | 389 | if util.safehasattr(parsers, 'parse_index_devel_nodemap'): |
@@ -650,6 +670,8 b' class revlog(object):' | |||
|
650 | 670 | self._io = revlogio() |
|
651 | 671 | if self.version == REVLOGV0: |
|
652 | 672 | self._io = revlogoldio() |
|
673 | elif fmt == REVLOGV2: | |
|
674 | self._io = revlogv2io() | |
|
653 | 675 | elif devel_nodemap: |
|
654 | 676 | self._io = NodemapRevlogIO() |
|
655 | 677 | elif use_rust_index: |
@@ -2337,7 +2359,13 b' class revlog(object):' | |||
|
2337 | 2359 | p1r, |
|
2338 | 2360 | p2r, |
|
2339 | 2361 | node, |
|
2362 | 0, | |
|
2363 | 0, | |
|
2340 | 2364 | ) |
|
2365 | ||
|
2366 | if self.version & 0xFFFF != REVLOGV2: | |
|
2367 | e = e[:8] | |
|
2368 | ||
|
2341 | 2369 | self.index.append(e) |
|
2342 | 2370 | |
|
2343 | 2371 | entry = self._io.packentry(e, self.node, self.version, curr) |
@@ -15,7 +15,6 b' from ..interfaces import repository' | |||
|
15 | 15 | REVLOGV0 = 0 |
|
16 | 16 | REVLOGV1 = 1 |
|
17 | 17 | # Dummy value until file format is finalized. |
|
18 | # Reminder: change the bounds check in revlog.__init__ when this is changed. | |
|
19 | 18 | REVLOGV2 = 0xDEAD |
|
20 | 19 | # Shared across v1 and v2. |
|
21 | 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): | |
|
121 | index, chunkcache = parsers.parse_index2(data, inline) | |
|
120 | def parse_index2(data, inline, revlogv2=False): | |
|
121 | index, chunkcache = parsers.parse_index2(data, inline, revlogv2=revlogv2) | |
|
122 | 122 | return list(index), chunkcache |
|
123 | 123 | |
|
124 | 124 |
@@ -22,7 +22,7 b' Can create and open repo with revlog v2 ' | |||
|
22 | 22 | $ cd empty-repo |
|
23 | 23 | $ cat .hg/requires |
|
24 | 24 | dotencode |
|
25 |
exp-revlogv2. |
|
|
25 | exp-revlogv2.2 | |
|
26 | 26 | fncache |
|
27 | 27 | sparserevlog |
|
28 | 28 | store |
@@ -22,10 +22,10 b' Unknown flags on revlog version 1 are re' | |||
|
22 | 22 | Unknown version is rejected |
|
23 | 23 | |
|
24 | 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 | 27 | $ hg log |
|
28 |
abort: unknown version ( |
|
|
28 | abort: unknown version (48879) in revlog 00changelog.i | |
|
29 | 29 | [50] |
|
30 | 30 | |
|
31 | 31 | $ cd .. |
General Comments 0
You need to be logged in to leave comments.
Login now