comparison mercurial/revlog.py @ 43077:687b865b95ad

formatting: byteify all mercurial/ and hgext/ string literals Done with python3.7 contrib/byteify-strings.py -i $(hg files 'set:mercurial/**.py - mercurial/thirdparty/** + hgext/**.py - hgext/fsmonitor/pywatchman/** - mercurial/__init__.py') black -l 80 -t py33 -S $(hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**" - hgext/fsmonitor/pywatchman/**') # skip-blame mass-reformatting only Differential Revision: https://phab.mercurial-scm.org/D6972
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:48:39 -0400
parents 2372284d9457
children c59eb1560c44
comparison
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
140 return int(q & 0xFFFF) 140 return int(q & 0xFFFF)
141 141
142 142
143 def offset_type(offset, type): 143 def offset_type(offset, type):
144 if (type & ~flagutil.REVIDX_KNOWN_FLAGS) != 0: 144 if (type & ~flagutil.REVIDX_KNOWN_FLAGS) != 0:
145 raise ValueError('unknown revlog index flags') 145 raise ValueError(b'unknown revlog index flags')
146 return int(int(offset) << 16 | type) 146 return int(int(offset) << 16 | type)
147 147
148 148
149 @attr.s(slots=True, frozen=True) 149 @attr.s(slots=True, frozen=True)
150 class _revisioninfo(object): 150 class _revisioninfo(object):
195 # 4 bytes: base rev 195 # 4 bytes: base rev
196 # 4 bytes: link rev 196 # 4 bytes: link rev
197 # 20 bytes: parent 1 nodeid 197 # 20 bytes: parent 1 nodeid
198 # 20 bytes: parent 2 nodeid 198 # 20 bytes: parent 2 nodeid
199 # 20 bytes: nodeid 199 # 20 bytes: nodeid
200 indexformatv0 = struct.Struct(">4l20s20s20s") 200 indexformatv0 = struct.Struct(b">4l20s20s20s")
201 indexformatv0_pack = indexformatv0.pack 201 indexformatv0_pack = indexformatv0.pack
202 indexformatv0_unpack = indexformatv0.unpack 202 indexformatv0_unpack = indexformatv0.unpack
203 203
204 204
205 class revlogoldindex(list): 205 class revlogoldindex(list):
241 return revlogoldindex(index), nodemap, None 241 return revlogoldindex(index), nodemap, None
242 242
243 def packentry(self, entry, node, version, rev): 243 def packentry(self, entry, node, version, rev):
244 if gettype(entry[0]): 244 if gettype(entry[0]):
245 raise error.RevlogError( 245 raise error.RevlogError(
246 _('index entry flags need revlog ' 'version 1') 246 _(b'index entry flags need revlog ' b'version 1')
247 ) 247 )
248 e2 = ( 248 e2 = (
249 getoffset(entry[0]), 249 getoffset(entry[0]),
250 entry[1], 250 entry[1],
251 entry[3], 251 entry[3],
265 # 4 bytes: base rev 265 # 4 bytes: base rev
266 # 4 bytes: link rev 266 # 4 bytes: link rev
267 # 4 bytes: parent 1 rev 267 # 4 bytes: parent 1 rev
268 # 4 bytes: parent 2 rev 268 # 4 bytes: parent 2 rev
269 # 32 bytes: nodeid 269 # 32 bytes: nodeid
270 indexformatng = struct.Struct(">Qiiiiii20s12x") 270 indexformatng = struct.Struct(b">Qiiiiii20s12x")
271 indexformatng_pack = indexformatng.pack 271 indexformatng_pack = indexformatng.pack
272 versionformat = struct.Struct(">I") 272 versionformat = struct.Struct(b">I")
273 versionformat_pack = versionformat.pack 273 versionformat_pack = versionformat.pack
274 versionformat_unpack = versionformat.unpack 274 versionformat_unpack = versionformat.unpack
275 275
276 # corresponds to uncompressed length of indexformatng (2 gigs, 4-byte 276 # corresponds to uncompressed length of indexformatng (2 gigs, 4-byte
277 # signed integer) 277 # signed integer)
351 and can be used to implement COW semantics or the like. 351 and can be used to implement COW semantics or the like.
352 352
353 """ 353 """
354 self.upperboundcomp = upperboundcomp 354 self.upperboundcomp = upperboundcomp
355 self.indexfile = indexfile 355 self.indexfile = indexfile
356 self.datafile = datafile or (indexfile[:-2] + ".d") 356 self.datafile = datafile or (indexfile[:-2] + b".d")
357 self.opener = opener 357 self.opener = opener
358 # When True, indexfile is opened with checkambig=True at writing, to 358 # When True, indexfile is opened with checkambig=True at writing, to
359 # avoid file stat ambiguity. 359 # avoid file stat ambiguity.
360 self._checkambig = checkambig 360 self._checkambig = checkambig
361 self._mmaplargeindex = mmaplargeindex 361 self._mmaplargeindex = mmaplargeindex
363 # 3-tuple of (node, rev, text) for a raw revision. 363 # 3-tuple of (node, rev, text) for a raw revision.
364 self._revisioncache = None 364 self._revisioncache = None
365 # Maps rev to chain base rev. 365 # Maps rev to chain base rev.
366 self._chainbasecache = util.lrucachedict(100) 366 self._chainbasecache = util.lrucachedict(100)
367 # 2-tuple of (offset, data) of raw data from the revlog at an offset. 367 # 2-tuple of (offset, data) of raw data from the revlog at an offset.
368 self._chunkcache = (0, '') 368 self._chunkcache = (0, b'')
369 # How much data to read and cache into the raw revlog data cache. 369 # How much data to read and cache into the raw revlog data cache.
370 self._chunkcachesize = 65536 370 self._chunkcachesize = 65536
371 self._maxchainlen = None 371 self._maxchainlen = None
372 self._deltabothparents = True 372 self._deltabothparents = True
373 self.index = [] 373 self.index = []
374 # Mapping of partial identifiers to full nodes. 374 # Mapping of partial identifiers to full nodes.
375 self._pcache = {} 375 self._pcache = {}
376 # Mapping of revision integer to full node. 376 # Mapping of revision integer to full node.
377 self._nodecache = {nullid: nullrev} 377 self._nodecache = {nullid: nullrev}
378 self._nodepos = None 378 self._nodepos = None
379 self._compengine = 'zlib' 379 self._compengine = b'zlib'
380 self._compengineopts = {} 380 self._compengineopts = {}
381 self._maxdeltachainspan = -1 381 self._maxdeltachainspan = -1
382 self._withsparseread = False 382 self._withsparseread = False
383 self._sparserevlog = False 383 self._sparserevlog = False
384 self._srdensitythreshold = 0.50 384 self._srdensitythreshold = 0.50
395 395
396 def _loadindex(self): 396 def _loadindex(self):
397 mmapindexthreshold = None 397 mmapindexthreshold = None
398 opts = self.opener.options 398 opts = self.opener.options
399 399
400 if 'revlogv2' in opts: 400 if b'revlogv2' in opts:
401 newversionflags = REVLOGV2 | FLAG_INLINE_DATA 401 newversionflags = REVLOGV2 | FLAG_INLINE_DATA
402 elif 'revlogv1' in opts: 402 elif b'revlogv1' in opts:
403 newversionflags = REVLOGV1 | FLAG_INLINE_DATA 403 newversionflags = REVLOGV1 | FLAG_INLINE_DATA
404 if 'generaldelta' in opts: 404 if b'generaldelta' in opts:
405 newversionflags |= FLAG_GENERALDELTA 405 newversionflags |= FLAG_GENERALDELTA
406 elif 'revlogv0' in self.opener.options: 406 elif b'revlogv0' in self.opener.options:
407 newversionflags = REVLOGV0 407 newversionflags = REVLOGV0
408 else: 408 else:
409 newversionflags = REVLOG_DEFAULT_VERSION 409 newversionflags = REVLOG_DEFAULT_VERSION
410 410
411 if 'chunkcachesize' in opts: 411 if b'chunkcachesize' in opts:
412 self._chunkcachesize = opts['chunkcachesize'] 412 self._chunkcachesize = opts[b'chunkcachesize']
413 if 'maxchainlen' in opts: 413 if b'maxchainlen' in opts:
414 self._maxchainlen = opts['maxchainlen'] 414 self._maxchainlen = opts[b'maxchainlen']
415 if 'deltabothparents' in opts: 415 if b'deltabothparents' in opts:
416 self._deltabothparents = opts['deltabothparents'] 416 self._deltabothparents = opts[b'deltabothparents']
417 self._lazydelta = bool(opts.get('lazydelta', True)) 417 self._lazydelta = bool(opts.get(b'lazydelta', True))
418 self._lazydeltabase = False 418 self._lazydeltabase = False
419 if self._lazydelta: 419 if self._lazydelta:
420 self._lazydeltabase = bool(opts.get('lazydeltabase', False)) 420 self._lazydeltabase = bool(opts.get(b'lazydeltabase', False))
421 if 'compengine' in opts: 421 if b'compengine' in opts:
422 self._compengine = opts['compengine'] 422 self._compengine = opts[b'compengine']
423 if 'zlib.level' in opts: 423 if b'zlib.level' in opts:
424 self._compengineopts['zlib.level'] = opts['zlib.level'] 424 self._compengineopts[b'zlib.level'] = opts[b'zlib.level']
425 if 'zstd.level' in opts: 425 if b'zstd.level' in opts:
426 self._compengineopts['zstd.level'] = opts['zstd.level'] 426 self._compengineopts[b'zstd.level'] = opts[b'zstd.level']
427 if 'maxdeltachainspan' in opts: 427 if b'maxdeltachainspan' in opts:
428 self._maxdeltachainspan = opts['maxdeltachainspan'] 428 self._maxdeltachainspan = opts[b'maxdeltachainspan']
429 if self._mmaplargeindex and 'mmapindexthreshold' in opts: 429 if self._mmaplargeindex and b'mmapindexthreshold' in opts:
430 mmapindexthreshold = opts['mmapindexthreshold'] 430 mmapindexthreshold = opts[b'mmapindexthreshold']
431 self.hassidedata = bool(opts.get('side-data', False)) 431 self.hassidedata = bool(opts.get(b'side-data', False))
432 if self.hassidedata: 432 if self.hassidedata:
433 self._flagprocessors[REVIDX_SIDEDATA] = sidedatautil.processors 433 self._flagprocessors[REVIDX_SIDEDATA] = sidedatautil.processors
434 self._sparserevlog = bool(opts.get('sparse-revlog', False)) 434 self._sparserevlog = bool(opts.get(b'sparse-revlog', False))
435 withsparseread = bool(opts.get('with-sparse-read', False)) 435 withsparseread = bool(opts.get(b'with-sparse-read', False))
436 # sparse-revlog forces sparse-read 436 # sparse-revlog forces sparse-read
437 self._withsparseread = self._sparserevlog or withsparseread 437 self._withsparseread = self._sparserevlog or withsparseread
438 if 'sparse-read-density-threshold' in opts: 438 if b'sparse-read-density-threshold' in opts:
439 self._srdensitythreshold = opts['sparse-read-density-threshold'] 439 self._srdensitythreshold = opts[b'sparse-read-density-threshold']
440 if 'sparse-read-min-gap-size' in opts: 440 if b'sparse-read-min-gap-size' in opts:
441 self._srmingapsize = opts['sparse-read-min-gap-size'] 441 self._srmingapsize = opts[b'sparse-read-min-gap-size']
442 if opts.get('enableellipsis'): 442 if opts.get(b'enableellipsis'):
443 self._flagprocessors[REVIDX_ELLIPSIS] = ellipsisprocessor 443 self._flagprocessors[REVIDX_ELLIPSIS] = ellipsisprocessor
444 444
445 # revlog v0 doesn't have flag processors 445 # revlog v0 doesn't have flag processors
446 for flag, processor in opts.get(b'flagprocessors', {}).iteritems(): 446 for flag, processor in opts.get(b'flagprocessors', {}).iteritems():
447 flagutil.insertflagprocessor(flag, processor, self._flagprocessors) 447 flagutil.insertflagprocessor(flag, processor, self._flagprocessors)
448 448
449 if self._chunkcachesize <= 0: 449 if self._chunkcachesize <= 0:
450 raise error.RevlogError( 450 raise error.RevlogError(
451 _('revlog chunk cache size %r is not ' 'greater than 0') 451 _(b'revlog chunk cache size %r is not ' b'greater than 0')
452 % self._chunkcachesize 452 % self._chunkcachesize
453 ) 453 )
454 elif self._chunkcachesize & (self._chunkcachesize - 1): 454 elif self._chunkcachesize & (self._chunkcachesize - 1):
455 raise error.RevlogError( 455 raise error.RevlogError(
456 _('revlog chunk cache size %r is not a ' 'power of 2') 456 _(b'revlog chunk cache size %r is not a ' b'power of 2')
457 % self._chunkcachesize 457 % self._chunkcachesize
458 ) 458 )
459 459
460 indexdata = '' 460 indexdata = b''
461 self._initempty = True 461 self._initempty = True
462 try: 462 try:
463 with self._indexfp() as f: 463 with self._indexfp() as f:
464 if ( 464 if (
465 mmapindexthreshold is not None 465 mmapindexthreshold is not None
487 fmt = versionflags & 0xFFFF 487 fmt = versionflags & 0xFFFF
488 488
489 if fmt == REVLOGV0: 489 if fmt == REVLOGV0:
490 if flags: 490 if flags:
491 raise error.RevlogError( 491 raise error.RevlogError(
492 _('unknown flags (%#04x) in version %d ' 'revlog %s') 492 _(b'unknown flags (%#04x) in version %d ' b'revlog %s')
493 % (flags >> 16, fmt, self.indexfile) 493 % (flags >> 16, fmt, self.indexfile)
494 ) 494 )
495 495
496 self._inline = False 496 self._inline = False
497 self._generaldelta = False 497 self._generaldelta = False
498 498
499 elif fmt == REVLOGV1: 499 elif fmt == REVLOGV1:
500 if flags & ~REVLOGV1_FLAGS: 500 if flags & ~REVLOGV1_FLAGS:
501 raise error.RevlogError( 501 raise error.RevlogError(
502 _('unknown flags (%#04x) in version %d ' 'revlog %s') 502 _(b'unknown flags (%#04x) in version %d ' b'revlog %s')
503 % (flags >> 16, fmt, self.indexfile) 503 % (flags >> 16, fmt, self.indexfile)
504 ) 504 )
505 505
506 self._inline = versionflags & FLAG_INLINE_DATA 506 self._inline = versionflags & FLAG_INLINE_DATA
507 self._generaldelta = versionflags & FLAG_GENERALDELTA 507 self._generaldelta = versionflags & FLAG_GENERALDELTA
508 508
509 elif fmt == REVLOGV2: 509 elif fmt == REVLOGV2:
510 if flags & ~REVLOGV2_FLAGS: 510 if flags & ~REVLOGV2_FLAGS:
511 raise error.RevlogError( 511 raise error.RevlogError(
512 _('unknown flags (%#04x) in version %d ' 'revlog %s') 512 _(b'unknown flags (%#04x) in version %d ' b'revlog %s')
513 % (flags >> 16, fmt, self.indexfile) 513 % (flags >> 16, fmt, self.indexfile)
514 ) 514 )
515 515
516 self._inline = versionflags & FLAG_INLINE_DATA 516 self._inline = versionflags & FLAG_INLINE_DATA
517 # generaldelta implied by version 2 revlogs. 517 # generaldelta implied by version 2 revlogs.
518 self._generaldelta = True 518 self._generaldelta = True
519 519
520 else: 520 else:
521 raise error.RevlogError( 521 raise error.RevlogError(
522 _('unknown version (%d) in revlog %s') % (fmt, self.indexfile) 522 _(b'unknown version (%d) in revlog %s') % (fmt, self.indexfile)
523 ) 523 )
524 # sparse-revlog can't be on without general-delta (issue6056) 524 # sparse-revlog can't be on without general-delta (issue6056)
525 if not self._generaldelta: 525 if not self._generaldelta:
526 self._sparserevlog = False 526 self._sparserevlog = False
527 527
531 if self.version == REVLOGV0: 531 if self.version == REVLOGV0:
532 self._io = revlogoldio() 532 self._io = revlogoldio()
533 try: 533 try:
534 d = self._io.parseindex(indexdata, self._inline) 534 d = self._io.parseindex(indexdata, self._inline)
535 except (ValueError, IndexError): 535 except (ValueError, IndexError):
536 raise error.RevlogError(_("index %s is corrupted") % self.indexfile) 536 raise error.RevlogError(
537 _(b"index %s is corrupted") % self.indexfile
538 )
537 self.index, nodemap, self._chunkcache = d 539 self.index, nodemap, self._chunkcache = d
538 if nodemap is not None: 540 if nodemap is not None:
539 self.nodemap = self._nodecache = nodemap 541 self.nodemap = self._nodecache = nodemap
540 if not self._chunkcache: 542 if not self._chunkcache:
541 self._chunkclear() 543 self._chunkclear()
547 @util.propertycache 549 @util.propertycache
548 def _compressor(self): 550 def _compressor(self):
549 engine = util.compengines[self._compengine] 551 engine = util.compengines[self._compengine]
550 return engine.revlogcompressor(self._compengineopts) 552 return engine.revlogcompressor(self._compengineopts)
551 553
552 def _indexfp(self, mode='r'): 554 def _indexfp(self, mode=b'r'):
553 """file object for the revlog's index file""" 555 """file object for the revlog's index file"""
554 args = {r'mode': mode} 556 args = {r'mode': mode}
555 if mode != 'r': 557 if mode != b'r':
556 args[r'checkambig'] = self._checkambig 558 args[r'checkambig'] = self._checkambig
557 if mode == 'w': 559 if mode == b'w':
558 args[r'atomictemp'] = True 560 args[r'atomictemp'] = True
559 return self.opener(self.indexfile, **args) 561 return self.opener(self.indexfile, **args)
560 562
561 def _datafp(self, mode='r'): 563 def _datafp(self, mode=b'r'):
562 """file object for the revlog's data file""" 564 """file object for the revlog's data file"""
563 return self.opener(self.datafile, mode=mode) 565 return self.opener(self.datafile, mode=mode)
564 566
565 @contextlib.contextmanager 567 @contextlib.contextmanager
566 def _datareadfp(self, existingfp=None): 568 def _datareadfp(self, existingfp=None):
633 return True 635 return True
634 636
635 def clearcaches(self): 637 def clearcaches(self):
636 self._revisioncache = None 638 self._revisioncache = None
637 self._chainbasecache.clear() 639 self._chainbasecache.clear()
638 self._chunkcache = (0, '') 640 self._chunkcache = (0, b'')
639 self._pcache = {} 641 self._pcache = {}
640 642
641 try: 643 try:
642 # If we are using the native C version, you are in a fun case 644 # If we are using the native C version, you are in a fun case
643 # where self.index, self.nodemap and self._nodecaches is the same 645 # where self.index, self.nodemap and self._nodecaches is the same
654 raise 656 raise
655 except error.RevlogError: 657 except error.RevlogError:
656 # parsers.c radix tree lookup failed 658 # parsers.c radix tree lookup failed
657 if node == wdirid or node in wdirfilenodeids: 659 if node == wdirid or node in wdirfilenodeids:
658 raise error.WdirUnsupported 660 raise error.WdirUnsupported
659 raise error.LookupError(node, self.indexfile, _('no node')) 661 raise error.LookupError(node, self.indexfile, _(b'no node'))
660 except KeyError: 662 except KeyError:
661 # pure python cache lookup failed 663 # pure python cache lookup failed
662 n = self._nodecache 664 n = self._nodecache
663 i = self.index 665 i = self.index
664 p = self._nodepos 666 p = self._nodepos
672 if v == node: 674 if v == node:
673 self._nodepos = r - 1 675 self._nodepos = r - 1
674 return r 676 return r
675 if node == wdirid or node in wdirfilenodeids: 677 if node == wdirid or node in wdirfilenodeids:
676 raise error.WdirUnsupported 678 raise error.WdirUnsupported
677 raise error.LookupError(node, self.indexfile, _('no node')) 679 raise error.LookupError(node, self.indexfile, _(b'no node'))
678 680
679 # Accessors for index entries. 681 # Accessors for index entries.
680 682
681 # First tuple entry is 8 bytes. First 6 bytes are offset. Last 2 bytes 683 # First tuple entry is 8 bytes. First 6 bytes are offset. Last 2 bytes
682 # are flags. 684 # are flags.
846 # and we're sure ancestors aren't filtered as well 848 # and we're sure ancestors aren't filtered as well
847 849
848 if rustancestor is not None: 850 if rustancestor is not None:
849 lazyancestors = rustancestor.LazyAncestors 851 lazyancestors = rustancestor.LazyAncestors
850 arg = self.index 852 arg = self.index
851 elif util.safehasattr(parsers, 'rustlazyancestors'): 853 elif util.safehasattr(parsers, b'rustlazyancestors'):
852 lazyancestors = ancestor.rustlazyancestors 854 lazyancestors = ancestor.rustlazyancestors
853 arg = self.index 855 arg = self.index
854 else: 856 else:
855 lazyancestors = ancestor.lazyancestors 857 lazyancestors = ancestor.lazyancestors
856 arg = self._uncheckedparentrevs 858 arg = self._uncheckedparentrevs
1287 except error.LookupError: 1289 except error.LookupError:
1288 pass # may be partial hex id 1290 pass # may be partial hex id
1289 try: 1291 try:
1290 # str(rev) 1292 # str(rev)
1291 rev = int(id) 1293 rev = int(id)
1292 if "%d" % rev != id: 1294 if b"%d" % rev != id:
1293 raise ValueError 1295 raise ValueError
1294 if rev < 0: 1296 if rev < 0:
1295 rev = len(self) + rev 1297 rev = len(self) + rev
1296 if rev < 0 or rev >= len(self): 1298 if rev < 0 or rev >= len(self):
1297 raise ValueError 1299 raise ValueError
1324 except error.RevlogError: 1326 except error.RevlogError:
1325 # parsers.c radix tree lookup gave multiple matches 1327 # parsers.c radix tree lookup gave multiple matches
1326 # fast path: for unfiltered changelog, radix tree is accurate 1328 # fast path: for unfiltered changelog, radix tree is accurate
1327 if not getattr(self, 'filteredrevs', None): 1329 if not getattr(self, 'filteredrevs', None):
1328 raise error.AmbiguousPrefixLookupError( 1330 raise error.AmbiguousPrefixLookupError(
1329 id, self.indexfile, _('ambiguous identifier') 1331 id, self.indexfile, _(b'ambiguous identifier')
1330 ) 1332 )
1331 # fall through to slow path that filters hidden revisions 1333 # fall through to slow path that filters hidden revisions
1332 except (AttributeError, ValueError): 1334 except (AttributeError, ValueError):
1333 # we are pure python, or key was too short to search radix tree 1335 # we are pure python, or key was too short to search radix tree
1334 pass 1336 pass
1350 if len(nl) > 0: 1352 if len(nl) > 0:
1351 if len(nl) == 1 and not maybewdir: 1353 if len(nl) == 1 and not maybewdir:
1352 self._pcache[id] = nl[0] 1354 self._pcache[id] = nl[0]
1353 return nl[0] 1355 return nl[0]
1354 raise error.AmbiguousPrefixLookupError( 1356 raise error.AmbiguousPrefixLookupError(
1355 id, self.indexfile, _('ambiguous identifier') 1357 id, self.indexfile, _(b'ambiguous identifier')
1356 ) 1358 )
1357 if maybewdir: 1359 if maybewdir:
1358 raise error.WdirUnsupported 1360 raise error.WdirUnsupported
1359 return None 1361 return None
1360 except TypeError: 1362 except TypeError:
1370 return n 1372 return n
1371 n = self._partialmatch(id) 1373 n = self._partialmatch(id)
1372 if n: 1374 if n:
1373 return n 1375 return n
1374 1376
1375 raise error.LookupError(id, self.indexfile, _('no match found')) 1377 raise error.LookupError(id, self.indexfile, _(b'no match found'))
1376 1378
1377 def shortest(self, node, minlength=1): 1379 def shortest(self, node, minlength=1):
1378 """Find the shortest unambiguous prefix that matches node.""" 1380 """Find the shortest unambiguous prefix that matches node."""
1379 1381
1380 def isvalid(prefix): 1382 def isvalid(prefix):
1384 return False 1386 return False
1385 except error.WdirUnsupported: 1387 except error.WdirUnsupported:
1386 # single 'ff...' match 1388 # single 'ff...' match
1387 return True 1389 return True
1388 if matchednode is None: 1390 if matchednode is None:
1389 raise error.LookupError(node, self.indexfile, _('no node')) 1391 raise error.LookupError(node, self.indexfile, _(b'no node'))
1390 return True 1392 return True
1391 1393
1392 def maybewdir(prefix): 1394 def maybewdir(prefix):
1393 return all(c == 'f' for c in pycompat.iterbytestr(prefix)) 1395 return all(c == b'f' for c in pycompat.iterbytestr(prefix))
1394 1396
1395 hexnode = hex(node) 1397 hexnode = hex(node)
1396 1398
1397 def disambiguate(hexnode, minlength): 1399 def disambiguate(hexnode, minlength):
1398 """Disambiguate against wdirid.""" 1400 """Disambiguate against wdirid."""
1405 try: 1407 try:
1406 length = max(self.index.shortest(node), minlength) 1408 length = max(self.index.shortest(node), minlength)
1407 return disambiguate(hexnode, length) 1409 return disambiguate(hexnode, length)
1408 except error.RevlogError: 1410 except error.RevlogError:
1409 if node != wdirid: 1411 if node != wdirid:
1410 raise error.LookupError(node, self.indexfile, _('no node')) 1412 raise error.LookupError(node, self.indexfile, _(b'no node'))
1411 except AttributeError: 1413 except AttributeError:
1412 # Fall through to pure code 1414 # Fall through to pure code
1413 pass 1415 pass
1414 1416
1415 if node == wdirid: 1417 if node == wdirid:
1472 if offset != realoffset or reallength != length: 1474 if offset != realoffset or reallength != length:
1473 startoffset = offset - realoffset 1475 startoffset = offset - realoffset
1474 if len(d) - startoffset < length: 1476 if len(d) - startoffset < length:
1475 raise error.RevlogError( 1477 raise error.RevlogError(
1476 _( 1478 _(
1477 'partial read of revlog %s; expected %d bytes from ' 1479 b'partial read of revlog %s; expected %d bytes from '
1478 'offset %d, got %d' 1480 b'offset %d, got %d'
1479 ) 1481 )
1480 % ( 1482 % (
1481 self.indexfile if self._inline else self.datafile, 1483 self.indexfile if self._inline else self.datafile,
1482 length, 1484 length,
1483 realoffset, 1485 realoffset,
1488 return util.buffer(d, startoffset, length) 1490 return util.buffer(d, startoffset, length)
1489 1491
1490 if len(d) < length: 1492 if len(d) < length:
1491 raise error.RevlogError( 1493 raise error.RevlogError(
1492 _( 1494 _(
1493 'partial read of revlog %s; expected %d bytes from offset ' 1495 b'partial read of revlog %s; expected %d bytes from offset '
1494 '%d, got %d' 1496 b'%d, got %d'
1495 ) 1497 )
1496 % ( 1498 % (
1497 self.indexfile if self._inline else self.datafile, 1499 self.indexfile if self._inline else self.datafile,
1498 length, 1500 length,
1499 offset, 1501 offset,
1627 1629
1628 return l 1630 return l
1629 1631
1630 def _chunkclear(self): 1632 def _chunkclear(self):
1631 """Clear the raw chunk cache.""" 1633 """Clear the raw chunk cache."""
1632 self._chunkcache = (0, '') 1634 self._chunkcache = (0, b'')
1633 1635
1634 def deltaparent(self, rev): 1636 def deltaparent(self, rev):
1635 """return deltaparent of the given revision""" 1637 """return deltaparent of the given revision"""
1636 base = self.index[rev][3] 1638 base = self.index[rev][3]
1637 if base == rev: 1639 if base == rev:
1644 def issnapshot(self, rev): 1646 def issnapshot(self, rev):
1645 """tells whether rev is a snapshot 1647 """tells whether rev is a snapshot
1646 """ 1648 """
1647 if not self._sparserevlog: 1649 if not self._sparserevlog:
1648 return self.deltaparent(rev) == nullrev 1650 return self.deltaparent(rev) == nullrev
1649 elif util.safehasattr(self.index, 'issnapshot'): 1651 elif util.safehasattr(self.index, b'issnapshot'):
1650 # directly assign the method to cache the testing and access 1652 # directly assign the method to cache the testing and access
1651 self.issnapshot = self.index.issnapshot 1653 self.issnapshot = self.index.issnapshot
1652 return self.issnapshot(rev) 1654 return self.issnapshot(rev)
1653 if rev == nullrev: 1655 if rev == nullrev:
1654 return True 1656 return True
1665 return self.issnapshot(base) 1667 return self.issnapshot(base)
1666 1668
1667 def snapshotdepth(self, rev): 1669 def snapshotdepth(self, rev):
1668 """number of snapshot in the chain before this one""" 1670 """number of snapshot in the chain before this one"""
1669 if not self.issnapshot(rev): 1671 if not self.issnapshot(rev):
1670 raise error.ProgrammingError('revision %d not a snapshot') 1672 raise error.ProgrammingError(b'revision %d not a snapshot')
1671 return len(self._deltachain(rev)[0]) - 1 1673 return len(self._deltachain(rev)[0]) - 1
1672 1674
1673 def revdiff(self, rev1, rev2): 1675 def revdiff(self, rev1, rev2):
1674 """return or calculate a delta between two revisions 1676 """return or calculate a delta between two revisions
1675 1677
1681 1683
1682 return mdiff.textdiff(self.rawdata(rev1), self.rawdata(rev2)) 1684 return mdiff.textdiff(self.rawdata(rev1), self.rawdata(rev2))
1683 1685
1684 def _processflags(self, text, flags, operation, raw=False): 1686 def _processflags(self, text, flags, operation, raw=False):
1685 """deprecated entry point to access flag processors""" 1687 """deprecated entry point to access flag processors"""
1686 msg = '_processflag(...) use the specialized variant' 1688 msg = b'_processflag(...) use the specialized variant'
1687 util.nouideprecwarn(msg, '5.2', stacklevel=2) 1689 util.nouideprecwarn(msg, b'5.2', stacklevel=2)
1688 if raw: 1690 if raw:
1689 return text, flagutil.processflagsraw(self, text, flags) 1691 return text, flagutil.processflagsraw(self, text, flags)
1690 elif operation == 'read': 1692 elif operation == b'read':
1691 return flagutil.processflagsread(self, text, flags) 1693 return flagutil.processflagsread(self, text, flags)
1692 else: # write operation 1694 else: # write operation
1693 return flagutil.processflagswrite(self, text, flags) 1695 return flagutil.processflagswrite(self, text, flags)
1694 1696
1695 def revision(self, nodeorrev, _df=None, raw=False): 1697 def revision(self, nodeorrev, _df=None, raw=False):
1701 treated as raw data when applying flag transforms. 'raw' should be set 1703 treated as raw data when applying flag transforms. 'raw' should be set
1702 to True when generating changegroups or in debug commands. 1704 to True when generating changegroups or in debug commands.
1703 """ 1705 """
1704 if raw: 1706 if raw:
1705 msg = ( 1707 msg = (
1706 'revlog.revision(..., raw=True) is deprecated, ' 1708 b'revlog.revision(..., raw=True) is deprecated, '
1707 'use revlog.rawdata(...)' 1709 b'use revlog.rawdata(...)'
1708 ) 1710 )
1709 util.nouideprecwarn(msg, '5.2', stacklevel=2) 1711 util.nouideprecwarn(msg, b'5.2', stacklevel=2)
1710 return self._revisiondata(nodeorrev, _df, raw=raw)[0] 1712 return self._revisiondata(nodeorrev, _df, raw=raw)[0]
1711 1713
1712 def sidedata(self, nodeorrev, _df=None): 1714 def sidedata(self, nodeorrev, _df=None):
1713 """a map of extra data related to the changeset but not part of the hash 1715 """a map of extra data related to the changeset but not part of the hash
1714 1716
1727 node = nodeorrev 1729 node = nodeorrev
1728 rev = None 1730 rev = None
1729 1731
1730 # fast path the special `nullid` rev 1732 # fast path the special `nullid` rev
1731 if node == nullid: 1733 if node == nullid:
1732 return "", {} 1734 return b"", {}
1733 1735
1734 # The text as stored inside the revlog. Might be the revision or might 1736 # The text as stored inside the revlog. Might be the revision or might
1735 # need to be processed to retrieve the revision. 1737 # need to be processed to retrieve the revision.
1736 rawtext = None 1738 rawtext = None
1737 1739
1757 text = rawtext 1759 text = rawtext
1758 else: 1760 else:
1759 try: 1761 try:
1760 r = flagutil.processflagsread(self, rawtext, flags) 1762 r = flagutil.processflagsread(self, rawtext, flags)
1761 except error.SidedataHashError as exc: 1763 except error.SidedataHashError as exc:
1762 msg = _("integrity check failed on %s:%s sidedata key %d") 1764 msg = _(b"integrity check failed on %s:%s sidedata key %d")
1763 msg %= (self.indexfile, pycompat.bytestr(rev), exc.sidedatakey) 1765 msg %= (self.indexfile, pycompat.bytestr(rev), exc.sidedatakey)
1764 raise error.RevlogError(msg) 1766 raise error.RevlogError(msg)
1765 text, validatehash, sidedata = r 1767 text, validatehash, sidedata = r
1766 if validatehash: 1768 if validatehash:
1767 self.checkhash(text, node, rev=rev) 1769 self.checkhash(text, node, rev=rev)
1849 1851
1850 revornode = rev 1852 revornode = rev
1851 if revornode is None: 1853 if revornode is None:
1852 revornode = templatefilters.short(hex(node)) 1854 revornode = templatefilters.short(hex(node))
1853 raise error.RevlogError( 1855 raise error.RevlogError(
1854 _("integrity check failed on %s:%s") 1856 _(b"integrity check failed on %s:%s")
1855 % (self.indexfile, pycompat.bytestr(revornode)) 1857 % (self.indexfile, pycompat.bytestr(revornode))
1856 ) 1858 )
1857 except error.RevlogError: 1859 except error.RevlogError:
1858 if self._censorable and storageutil.iscensoredtext(text): 1860 if self._censorable and storageutil.iscensoredtext(text):
1859 raise error.CensoredNodeError(self.indexfile, node, text) 1861 raise error.CensoredNodeError(self.indexfile, node, text)
1874 return 1876 return
1875 1877
1876 trinfo = tr.find(self.indexfile) 1878 trinfo = tr.find(self.indexfile)
1877 if trinfo is None: 1879 if trinfo is None:
1878 raise error.RevlogError( 1880 raise error.RevlogError(
1879 _("%s not found in the transaction") % self.indexfile 1881 _(b"%s not found in the transaction") % self.indexfile
1880 ) 1882 )
1881 1883
1882 trindex = trinfo[2] 1884 trindex = trinfo[2]
1883 if trindex is not None: 1885 if trindex is not None:
1884 dataoff = self.start(trindex) 1886 dataoff = self.start(trindex)
1894 fp.close() 1896 fp.close()
1895 # We can't use the cached file handle after close(). So prevent 1897 # We can't use the cached file handle after close(). So prevent
1896 # its usage. 1898 # its usage.
1897 self._writinghandles = None 1899 self._writinghandles = None
1898 1900
1899 with self._indexfp('r') as ifh, self._datafp('w') as dfh: 1901 with self._indexfp(b'r') as ifh, self._datafp(b'w') as dfh:
1900 for r in self: 1902 for r in self:
1901 dfh.write(self._getsegmentforrevs(r, r, df=ifh)[1]) 1903 dfh.write(self._getsegmentforrevs(r, r, df=ifh)[1])
1902 1904
1903 with self._indexfp('w') as fp: 1905 with self._indexfp(b'w') as fp:
1904 self.version &= ~FLAG_INLINE_DATA 1906 self.version &= ~FLAG_INLINE_DATA
1905 self._inline = False 1907 self._inline = False
1906 io = self._io 1908 io = self._io
1907 for i in self: 1909 for i in self:
1908 e = io.packentry(self.index[i], self.node, self.version, i) 1910 e = io.packentry(self.index[i], self.node, self.version, i)
1945 deltacomputer - an optional deltacomputer instance shared between 1947 deltacomputer - an optional deltacomputer instance shared between
1946 multiple calls 1948 multiple calls
1947 """ 1949 """
1948 if link == nullrev: 1950 if link == nullrev:
1949 raise error.RevlogError( 1951 raise error.RevlogError(
1950 _("attempted to add linkrev -1 to %s") % self.indexfile 1952 _(b"attempted to add linkrev -1 to %s") % self.indexfile
1951 ) 1953 )
1952 1954
1953 if sidedata is None: 1955 if sidedata is None:
1954 sidedata = {} 1956 sidedata = {}
1955 flags = flags & ~REVIDX_SIDEDATA 1957 flags = flags & ~REVIDX_SIDEDATA
1956 elif not self.hassidedata: 1958 elif not self.hassidedata:
1957 raise error.ProgrammingError( 1959 raise error.ProgrammingError(
1958 _("trying to add sidedata to a revlog who don't support them") 1960 _(b"trying to add sidedata to a revlog who don't support them")
1959 ) 1961 )
1960 else: 1962 else:
1961 flags |= REVIDX_SIDEDATA 1963 flags |= REVIDX_SIDEDATA
1962 1964
1963 if flags: 1965 if flags:
1972 if rawtext != text: 1974 if rawtext != text:
1973 cachedelta = None 1975 cachedelta = None
1974 1976
1975 if len(rawtext) > _maxentrysize: 1977 if len(rawtext) > _maxentrysize:
1976 raise error.RevlogError( 1978 raise error.RevlogError(
1977 _("%s: size of %d bytes exceeds maximum revlog storage of 2GiB") 1979 _(
1980 b"%s: size of %d bytes exceeds maximum revlog storage of 2GiB"
1981 )
1978 % (self.indexfile, len(rawtext)) 1982 % (self.indexfile, len(rawtext))
1979 ) 1983 )
1980 1984
1981 node = node or self.hash(rawtext, p1, p2) 1985 node = node or self.hash(rawtext, p1, p2)
1982 if node in self.nodemap: 1986 if node in self.nodemap:
2013 useful when reusing a revision not stored in this revlog (ex: received 2017 useful when reusing a revision not stored in this revlog (ex: received
2014 over wire, or read from an external bundle). 2018 over wire, or read from an external bundle).
2015 """ 2019 """
2016 dfh = None 2020 dfh = None
2017 if not self._inline: 2021 if not self._inline:
2018 dfh = self._datafp("a+") 2022 dfh = self._datafp(b"a+")
2019 ifh = self._indexfp("a+") 2023 ifh = self._indexfp(b"a+")
2020 try: 2024 try:
2021 return self._addrevision( 2025 return self._addrevision(
2022 node, 2026 node,
2023 rawtext, 2027 rawtext,
2024 transaction, 2028 transaction,
2037 ifh.close() 2041 ifh.close()
2038 2042
2039 def compress(self, data): 2043 def compress(self, data):
2040 """Generate a possibly-compressed representation of data.""" 2044 """Generate a possibly-compressed representation of data."""
2041 if not data: 2045 if not data:
2042 return '', data 2046 return b'', data
2043 2047
2044 compressed = self._compressor.compress(data) 2048 compressed = self._compressor.compress(data)
2045 2049
2046 if compressed: 2050 if compressed:
2047 # The revlog compressor added the header in the returned data. 2051 # The revlog compressor added the header in the returned data.
2048 return '', compressed 2052 return b'', compressed
2049 2053
2050 if data[0:1] == '\0': 2054 if data[0:1] == b'\0':
2051 return '', data 2055 return b'', data
2052 return 'u', data 2056 return b'u', data
2053 2057
2054 def decompress(self, data): 2058 def decompress(self, data):
2055 """Decompress a revlog chunk. 2059 """Decompress a revlog chunk.
2056 2060
2057 The chunk is expected to begin with a header identifying the 2061 The chunk is expected to begin with a header identifying the
2081 # 2085 #
2082 # According to `hg perfrevlogchunks`, this is ~0.5% faster for zlib 2086 # According to `hg perfrevlogchunks`, this is ~0.5% faster for zlib
2083 # compressed chunks. And this matters for changelog and manifest reads. 2087 # compressed chunks. And this matters for changelog and manifest reads.
2084 t = data[0:1] 2088 t = data[0:1]
2085 2089
2086 if t == 'x': 2090 if t == b'x':
2087 try: 2091 try:
2088 return _zlibdecompress(data) 2092 return _zlibdecompress(data)
2089 except zlib.error as e: 2093 except zlib.error as e:
2090 raise error.RevlogError( 2094 raise error.RevlogError(
2091 _('revlog decompress error: %s') 2095 _(b'revlog decompress error: %s')
2092 % stringutil.forcebytestr(e) 2096 % stringutil.forcebytestr(e)
2093 ) 2097 )
2094 # '\0' is more common than 'u' so it goes first. 2098 # '\0' is more common than 'u' so it goes first.
2095 elif t == '\0': 2099 elif t == b'\0':
2096 return data 2100 return data
2097 elif t == 'u': 2101 elif t == b'u':
2098 return util.buffer(data, 1) 2102 return util.buffer(data, 1)
2099 2103
2100 try: 2104 try:
2101 compressor = self._decompressors[t] 2105 compressor = self._decompressors[t]
2102 except KeyError: 2106 except KeyError:
2103 try: 2107 try:
2104 engine = util.compengines.forrevlogheader(t) 2108 engine = util.compengines.forrevlogheader(t)
2105 compressor = engine.revlogcompressor(self._compengineopts) 2109 compressor = engine.revlogcompressor(self._compengineopts)
2106 self._decompressors[t] = compressor 2110 self._decompressors[t] = compressor
2107 except KeyError: 2111 except KeyError:
2108 raise error.RevlogError(_('unknown compression type %r') % t) 2112 raise error.RevlogError(_(b'unknown compression type %r') % t)
2109 2113
2110 return compressor.decompress(data) 2114 return compressor.decompress(data)
2111 2115
2112 def _addrevision( 2116 def _addrevision(
2113 self, 2117 self,
2137 - rawtext is optional (can be None); if not set, cachedelta must be set. 2141 - rawtext is optional (can be None); if not set, cachedelta must be set.
2138 if both are set, they must correspond to each other. 2142 if both are set, they must correspond to each other.
2139 """ 2143 """
2140 if node == nullid: 2144 if node == nullid:
2141 raise error.RevlogError( 2145 raise error.RevlogError(
2142 _("%s: attempt to add null revision") % self.indexfile 2146 _(b"%s: attempt to add null revision") % self.indexfile
2143 ) 2147 )
2144 if node == wdirid or node in wdirfilenodeids: 2148 if node == wdirid or node in wdirfilenodeids:
2145 raise error.RevlogError( 2149 raise error.RevlogError(
2146 _("%s: attempt to add wdir revision") % self.indexfile 2150 _(b"%s: attempt to add wdir revision") % self.indexfile
2147 ) 2151 )
2148 2152
2149 if self._inline: 2153 if self._inline:
2150 fh = ifh 2154 fh = ifh
2151 else: 2155 else:
2254 If ``addrevisioncb`` is defined, it will be called with arguments of 2258 If ``addrevisioncb`` is defined, it will be called with arguments of
2255 this revlog and the node that was added. 2259 this revlog and the node that was added.
2256 """ 2260 """
2257 2261
2258 if self._writinghandles: 2262 if self._writinghandles:
2259 raise error.ProgrammingError('cannot nest addgroup() calls') 2263 raise error.ProgrammingError(b'cannot nest addgroup() calls')
2260 2264
2261 nodes = [] 2265 nodes = []
2262 2266
2263 r = len(self) 2267 r = len(self)
2264 end = 0 2268 end = 0
2265 if r: 2269 if r:
2266 end = self.end(r - 1) 2270 end = self.end(r - 1)
2267 ifh = self._indexfp("a+") 2271 ifh = self._indexfp(b"a+")
2268 isize = r * self._io.size 2272 isize = r * self._io.size
2269 if self._inline: 2273 if self._inline:
2270 transaction.add(self.indexfile, end + isize, r) 2274 transaction.add(self.indexfile, end + isize, r)
2271 dfh = None 2275 dfh = None
2272 else: 2276 else:
2273 transaction.add(self.indexfile, isize, r) 2277 transaction.add(self.indexfile, isize, r)
2274 transaction.add(self.datafile, end) 2278 transaction.add(self.datafile, end)
2275 dfh = self._datafp("a+") 2279 dfh = self._datafp(b"a+")
2276 2280
2277 def flush(): 2281 def flush():
2278 if dfh: 2282 if dfh:
2279 dfh.flush() 2283 dfh.flush()
2280 ifh.flush() 2284 ifh.flush()
2297 continue 2301 continue
2298 2302
2299 for p in (p1, p2): 2303 for p in (p1, p2):
2300 if p not in self.nodemap: 2304 if p not in self.nodemap:
2301 raise error.LookupError( 2305 raise error.LookupError(
2302 p, self.indexfile, _('unknown parent') 2306 p, self.indexfile, _(b'unknown parent')
2303 ) 2307 )
2304 2308
2305 if deltabase not in self.nodemap: 2309 if deltabase not in self.nodemap:
2306 raise error.LookupError( 2310 raise error.LookupError(
2307 deltabase, self.indexfile, _('unknown delta base') 2311 deltabase, self.indexfile, _(b'unknown delta base')
2308 ) 2312 )
2309 2313
2310 baserev = self.rev(deltabase) 2314 baserev = self.rev(deltabase)
2311 2315
2312 if baserev != nullrev and self.iscensored(baserev): 2316 if baserev != nullrev and self.iscensored(baserev):
2313 # if base is censored, delta must be full replacement in a 2317 # if base is censored, delta must be full replacement in a
2314 # single patch operation 2318 # single patch operation
2315 hlen = struct.calcsize(">lll") 2319 hlen = struct.calcsize(b">lll")
2316 oldlen = self.rawsize(baserev) 2320 oldlen = self.rawsize(baserev)
2317 newlen = len(delta) - hlen 2321 newlen = len(delta) - hlen
2318 if delta[:hlen] != mdiff.replacediffheader(oldlen, newlen): 2322 if delta[:hlen] != mdiff.replacediffheader(oldlen, newlen):
2319 raise error.CensoredBaseError( 2323 raise error.CensoredBaseError(
2320 self.indexfile, self.node(baserev) 2324 self.indexfile, self.node(baserev)
2350 2354
2351 if not dfh and not self._inline: 2355 if not dfh and not self._inline:
2352 # addrevision switched from inline to conventional 2356 # addrevision switched from inline to conventional
2353 # reopen the index 2357 # reopen the index
2354 ifh.close() 2358 ifh.close()
2355 dfh = self._datafp("a+") 2359 dfh = self._datafp(b"a+")
2356 ifh = self._indexfp("a+") 2360 ifh = self._indexfp(b"a+")
2357 self._writinghandles = (ifh, dfh) 2361 self._writinghandles = (ifh, dfh)
2358 finally: 2362 finally:
2359 self._writinghandles = None 2363 self._writinghandles = None
2360 2364
2361 if dfh: 2365 if dfh:
2489 nodesorder=None, 2493 nodesorder=None,
2490 revisiondata=False, 2494 revisiondata=False,
2491 assumehaveparentrevisions=False, 2495 assumehaveparentrevisions=False,
2492 deltamode=repository.CG_DELTAMODE_STD, 2496 deltamode=repository.CG_DELTAMODE_STD,
2493 ): 2497 ):
2494 if nodesorder not in ('nodes', 'storage', 'linear', None): 2498 if nodesorder not in (b'nodes', b'storage', b'linear', None):
2495 raise error.ProgrammingError( 2499 raise error.ProgrammingError(
2496 'unhandled value for nodesorder: %s' % nodesorder 2500 b'unhandled value for nodesorder: %s' % nodesorder
2497 ) 2501 )
2498 2502
2499 if nodesorder is None and not self._generaldelta: 2503 if nodesorder is None and not self._generaldelta:
2500 nodesorder = 'storage' 2504 nodesorder = b'storage'
2501 2505
2502 if ( 2506 if (
2503 not self._storedeltachains 2507 not self._storedeltachains
2504 and deltamode != repository.CG_DELTAMODE_PREV 2508 and deltamode != repository.CG_DELTAMODE_PREV
2505 ): 2509 ):
2518 deltamode=deltamode, 2522 deltamode=deltamode,
2519 revisiondata=revisiondata, 2523 revisiondata=revisiondata,
2520 assumehaveparentrevisions=assumehaveparentrevisions, 2524 assumehaveparentrevisions=assumehaveparentrevisions,
2521 ) 2525 )
2522 2526
2523 DELTAREUSEALWAYS = 'always' 2527 DELTAREUSEALWAYS = b'always'
2524 DELTAREUSESAMEREVS = 'samerevs' 2528 DELTAREUSESAMEREVS = b'samerevs'
2525 DELTAREUSENEVER = 'never' 2529 DELTAREUSENEVER = b'never'
2526 2530
2527 DELTAREUSEFULLADD = 'fulladd' 2531 DELTAREUSEFULLADD = b'fulladd'
2528 2532
2529 DELTAREUSEALL = {'always', 'samerevs', 'never', 'fulladd'} 2533 DELTAREUSEALL = {b'always', b'samerevs', b'never', b'fulladd'}
2530 2534
2531 def clone( 2535 def clone(
2532 self, 2536 self,
2533 tr, 2537 tr,
2534 destrevlog, 2538 destrevlog,
2576 In addition to the delta policy, the ``forcedeltabothparents`` 2580 In addition to the delta policy, the ``forcedeltabothparents``
2577 argument controls whether to force compute deltas against both parents 2581 argument controls whether to force compute deltas against both parents
2578 for merges. By default, the current default is used. 2582 for merges. By default, the current default is used.
2579 """ 2583 """
2580 if deltareuse not in self.DELTAREUSEALL: 2584 if deltareuse not in self.DELTAREUSEALL:
2581 raise ValueError(_('value for deltareuse invalid: %s') % deltareuse) 2585 raise ValueError(
2586 _(b'value for deltareuse invalid: %s') % deltareuse
2587 )
2582 2588
2583 if len(destrevlog): 2589 if len(destrevlog):
2584 raise ValueError(_('destination revlog is not empty')) 2590 raise ValueError(_(b'destination revlog is not empty'))
2585 2591
2586 if getattr(self, 'filteredrevs', None): 2592 if getattr(self, 'filteredrevs', None):
2587 raise ValueError(_('source revlog has filtered revisions')) 2593 raise ValueError(_(b'source revlog has filtered revisions'))
2588 if getattr(destrevlog, 'filteredrevs', None): 2594 if getattr(destrevlog, 'filteredrevs', None):
2589 raise ValueError(_('destination revlog has filtered revisions')) 2595 raise ValueError(_(b'destination revlog has filtered revisions'))
2590 2596
2591 # lazydelta and lazydeltabase controls whether to reuse a cached delta, 2597 # lazydelta and lazydeltabase controls whether to reuse a cached delta,
2592 # if possible. 2598 # if possible.
2593 oldlazydelta = destrevlog._lazydelta 2599 oldlazydelta = destrevlog._lazydelta
2594 oldlazydeltabase = destrevlog._lazydeltabase 2600 oldlazydeltabase = destrevlog._lazydeltabase
2658 2664
2659 if not cachedelta: 2665 if not cachedelta:
2660 rawtext = self.rawdata(rev) 2666 rawtext = self.rawdata(rev)
2661 2667
2662 ifh = destrevlog.opener( 2668 ifh = destrevlog.opener(
2663 destrevlog.indexfile, 'a+', checkambig=False 2669 destrevlog.indexfile, b'a+', checkambig=False
2664 ) 2670 )
2665 dfh = None 2671 dfh = None
2666 if not destrevlog._inline: 2672 if not destrevlog._inline:
2667 dfh = destrevlog.opener(destrevlog.datafile, 'a+') 2673 dfh = destrevlog.opener(destrevlog.datafile, b'a+')
2668 try: 2674 try:
2669 destrevlog._addrevision( 2675 destrevlog._addrevision(
2670 node, 2676 node,
2671 rawtext, 2677 rawtext,
2672 tr, 2678 tr,
2688 addrevisioncb(self, rev, node) 2694 addrevisioncb(self, rev, node)
2689 2695
2690 def censorrevision(self, tr, censornode, tombstone=b''): 2696 def censorrevision(self, tr, censornode, tombstone=b''):
2691 if (self.version & 0xFFFF) == REVLOGV0: 2697 if (self.version & 0xFFFF) == REVLOGV0:
2692 raise error.RevlogError( 2698 raise error.RevlogError(
2693 _('cannot censor with version %d revlogs') % self.version 2699 _(b'cannot censor with version %d revlogs') % self.version
2694 ) 2700 )
2695 2701
2696 censorrev = self.rev(censornode) 2702 censorrev = self.rev(censornode)
2697 tombstone = storageutil.packmeta({b'censored': tombstone}, b'') 2703 tombstone = storageutil.packmeta({b'censored': tombstone}, b'')
2698 2704
2699 if len(tombstone) > self.rawsize(censorrev): 2705 if len(tombstone) > self.rawsize(censorrev):
2700 raise error.Abort( 2706 raise error.Abort(
2701 _('censor tombstone must be no longer than ' 'censored data') 2707 _(b'censor tombstone must be no longer than ' b'censored data')
2702 ) 2708 )
2703 2709
2704 # Rewriting the revlog in place is hard. Our strategy for censoring is 2710 # Rewriting the revlog in place is hard. Our strategy for censoring is
2705 # to create a new revlog, copy all revisions to it, then replace the 2711 # to create a new revlog, copy all revisions to it, then replace the
2706 # revlogs on transaction close. 2712 # revlogs on transaction close.
2730 ) 2736 )
2731 2737
2732 if newrl.deltaparent(rev) != nullrev: 2738 if newrl.deltaparent(rev) != nullrev:
2733 raise error.Abort( 2739 raise error.Abort(
2734 _( 2740 _(
2735 'censored revision stored as delta; ' 2741 b'censored revision stored as delta; '
2736 'cannot censor' 2742 b'cannot censor'
2737 ), 2743 ),
2738 hint=_( 2744 hint=_(
2739 'censoring of revlogs is not ' 2745 b'censoring of revlogs is not '
2740 'fully implemented; please report ' 2746 b'fully implemented; please report '
2741 'this bug' 2747 b'this bug'
2742 ), 2748 ),
2743 ) 2749 )
2744 continue 2750 continue
2745 2751
2746 if self.iscensored(rev): 2752 if self.iscensored(rev):
2747 if self.deltaparent(rev) != nullrev: 2753 if self.deltaparent(rev) != nullrev:
2748 raise error.Abort( 2754 raise error.Abort(
2749 _( 2755 _(
2750 'cannot censor due to censored ' 2756 b'cannot censor due to censored '
2751 'revision having delta stored' 2757 b'revision having delta stored'
2752 ) 2758 )
2753 ) 2759 )
2754 rawtext = self._chunk(rev) 2760 rawtext = self._chunk(rev)
2755 else: 2761 else:
2756 rawtext = self.rawdata(rev) 2762 rawtext = self.rawdata(rev)
2757 2763
2758 newrl.addrawrevision( 2764 newrl.addrawrevision(
2759 rawtext, tr, self.linkrev(rev), p1, p2, node, self.flags(rev) 2765 rawtext, tr, self.linkrev(rev), p1, p2, node, self.flags(rev)
2760 ) 2766 )
2761 2767
2762 tr.addbackup(self.indexfile, location='store') 2768 tr.addbackup(self.indexfile, location=b'store')
2763 if not self._inline: 2769 if not self._inline:
2764 tr.addbackup(self.datafile, location='store') 2770 tr.addbackup(self.datafile, location=b'store')
2765 2771
2766 self.opener.rename(newrl.indexfile, self.indexfile) 2772 self.opener.rename(newrl.indexfile, self.indexfile)
2767 if not self._inline: 2773 if not self._inline:
2768 self.opener.rename(newrl.datafile, self.datafile) 2774 self.opener.rename(newrl.datafile, self.datafile)
2769 2775
2776 Yields ``revlogproblem`` instances describing problems that are 2782 Yields ``revlogproblem`` instances describing problems that are
2777 found. 2783 found.
2778 """ 2784 """
2779 dd, di = self.checksize() 2785 dd, di = self.checksize()
2780 if dd: 2786 if dd:
2781 yield revlogproblem(error=_('data length off by %d bytes') % dd) 2787 yield revlogproblem(error=_(b'data length off by %d bytes') % dd)
2782 if di: 2788 if di:
2783 yield revlogproblem(error=_('index contains %d extra bytes') % di) 2789 yield revlogproblem(error=_(b'index contains %d extra bytes') % di)
2784 2790
2785 version = self.version & 0xFFFF 2791 version = self.version & 0xFFFF
2786 2792
2787 # The verifier tells us what version revlog we should be. 2793 # The verifier tells us what version revlog we should be.
2788 if version != state['expectedversion']: 2794 if version != state[b'expectedversion']:
2789 yield revlogproblem( 2795 yield revlogproblem(
2790 warning=_("warning: '%s' uses revlog format %d; expected %d") 2796 warning=_(b"warning: '%s' uses revlog format %d; expected %d")
2791 % (self.indexfile, version, state['expectedversion']) 2797 % (self.indexfile, version, state[b'expectedversion'])
2792 ) 2798 )
2793 2799
2794 state['skipread'] = set() 2800 state[b'skipread'] = set()
2795 2801
2796 for rev in self: 2802 for rev in self:
2797 node = self.node(rev) 2803 node = self.node(rev)
2798 2804
2799 # Verify contents. 4 cases to care about: 2805 # Verify contents. 4 cases to care about:
2843 # 1. length check: L1 == L2, in all cases. 2849 # 1. length check: L1 == L2, in all cases.
2844 # 2. hash check: depending on flag processor, we may need to 2850 # 2. hash check: depending on flag processor, we may need to
2845 # use either "text" (external), or "rawtext" (in revlog). 2851 # use either "text" (external), or "rawtext" (in revlog).
2846 2852
2847 try: 2853 try:
2848 skipflags = state.get('skipflags', 0) 2854 skipflags = state.get(b'skipflags', 0)
2849 if skipflags: 2855 if skipflags:
2850 skipflags &= self.flags(rev) 2856 skipflags &= self.flags(rev)
2851 2857
2852 if skipflags: 2858 if skipflags:
2853 state['skipread'].add(node) 2859 state[b'skipread'].add(node)
2854 else: 2860 else:
2855 # Side-effect: read content and verify hash. 2861 # Side-effect: read content and verify hash.
2856 self.revision(node) 2862 self.revision(node)
2857 2863
2858 l1 = self.rawsize(rev) 2864 l1 = self.rawsize(rev)
2859 l2 = len(self.rawdata(node)) 2865 l2 = len(self.rawdata(node))
2860 2866
2861 if l1 != l2: 2867 if l1 != l2:
2862 yield revlogproblem( 2868 yield revlogproblem(
2863 error=_('unpacked size is %d, %d expected') % (l2, l1), 2869 error=_(b'unpacked size is %d, %d expected') % (l2, l1),
2864 node=node, 2870 node=node,
2865 ) 2871 )
2866 2872
2867 except error.CensoredNodeError: 2873 except error.CensoredNodeError:
2868 if state['erroroncensored']: 2874 if state[b'erroroncensored']:
2869 yield revlogproblem( 2875 yield revlogproblem(
2870 error=_('censored file data'), node=node 2876 error=_(b'censored file data'), node=node
2871 ) 2877 )
2872 state['skipread'].add(node) 2878 state[b'skipread'].add(node)
2873 except Exception as e: 2879 except Exception as e:
2874 yield revlogproblem( 2880 yield revlogproblem(
2875 error=_('unpacking %s: %s') 2881 error=_(b'unpacking %s: %s')
2876 % (short(node), stringutil.forcebytestr(e)), 2882 % (short(node), stringutil.forcebytestr(e)),
2877 node=node, 2883 node=node,
2878 ) 2884 )
2879 state['skipread'].add(node) 2885 state[b'skipread'].add(node)
2880 2886
2881 def storageinfo( 2887 def storageinfo(
2882 self, 2888 self,
2883 exclusivefiles=False, 2889 exclusivefiles=False,
2884 sharedfiles=False, 2890 sharedfiles=False,
2887 storedsize=False, 2893 storedsize=False,
2888 ): 2894 ):
2889 d = {} 2895 d = {}
2890 2896
2891 if exclusivefiles: 2897 if exclusivefiles:
2892 d['exclusivefiles'] = [(self.opener, self.indexfile)] 2898 d[b'exclusivefiles'] = [(self.opener, self.indexfile)]
2893 if not self._inline: 2899 if not self._inline:
2894 d['exclusivefiles'].append((self.opener, self.datafile)) 2900 d[b'exclusivefiles'].append((self.opener, self.datafile))
2895 2901
2896 if sharedfiles: 2902 if sharedfiles:
2897 d['sharedfiles'] = [] 2903 d[b'sharedfiles'] = []
2898 2904
2899 if revisionscount: 2905 if revisionscount:
2900 d['revisionscount'] = len(self) 2906 d[b'revisionscount'] = len(self)
2901 2907
2902 if trackedsize: 2908 if trackedsize:
2903 d['trackedsize'] = sum(map(self.rawsize, iter(self))) 2909 d[b'trackedsize'] = sum(map(self.rawsize, iter(self)))
2904 2910
2905 if storedsize: 2911 if storedsize:
2906 d['storedsize'] = sum( 2912 d[b'storedsize'] = sum(
2907 self.opener.stat(path).st_size for path in self.files() 2913 self.opener.stat(path).st_size for path in self.files()
2908 ) 2914 )
2909 2915
2910 return d 2916 return d