comparison mercurial/store.py @ 46895:6085b7f1536d

store: also return some information about the type of file `walk` found We start returning of 4th information in the `store.walk` return tuple: the type of the file. This will make it easier for caller to determine which kind of file they are looking at. This should especically help with the `upgrade-repo` code that has to do a lot of fragile index's file name comparison. Differential Revision: https://phab.mercurial-scm.org/D10315
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 06 Apr 2021 10:38:03 +0200
parents 6afb5ef1e776
children aed6ceaad6d7
comparison
equal deleted inserted replaced
46894:fe34c75f62ab 46895:6085b7f1536d
385 b'phaseroots', 385 b'phaseroots',
386 b'obsstore', 386 b'obsstore',
387 b'requires', 387 b'requires',
388 ] 388 ]
389 389
390 REVLOG_FILES_EXT = (b'.i', b'.d', b'.n', b'.nd') 390 REVLOG_FILES_MAIN_EXT = (b'.i', b'i.tmpcensored')
391 391 REVLOG_FILES_OTHER_EXT = (b'.d', b'.n', b'.nd', b'd.tmpcensored')
392 392
393 def isrevlog(f, kind, st): 393
394 def is_revlog(f, kind, st):
394 if kind != stat.S_IFREG: 395 if kind != stat.S_IFREG:
395 return False 396 return None
396 return f.endswith(REVLOG_FILES_EXT) 397 return revlog_type(f)
398
399
400 def revlog_type(f):
401 if f.endswith(REVLOG_FILES_MAIN_EXT):
402 return FILEFLAGS_REVLOG_MAIN
403 elif f.endswith(REVLOG_FILES_OTHER_EXT):
404 return FILETYPE_FILELOG_OTHER
405
406
407 # the file is part of changelog data
408 FILEFLAGS_CHANGELOG = 1 << 13
409 # the file is part of manifest data
410 FILEFLAGS_MANIFESTLOG = 1 << 12
411 # the file is part of filelog data
412 FILEFLAGS_FILELOG = 1 << 11
413 # file that are not directly part of a revlog
414 FILEFLAGS_OTHER = 1 << 10
415
416 # the main entry point for a revlog
417 FILEFLAGS_REVLOG_MAIN = 1 << 1
418 # a secondary file for a revlog
419 FILEFLAGS_REVLOG_OTHER = 1 << 0
420
421 FILETYPE_CHANGELOG_MAIN = FILEFLAGS_CHANGELOG | FILEFLAGS_REVLOG_MAIN
422 FILETYPE_CHANGELOG_OTHER = FILEFLAGS_CHANGELOG | FILEFLAGS_REVLOG_OTHER
423 FILETYPE_MANIFESTLOG_MAIN = FILEFLAGS_MANIFESTLOG | FILEFLAGS_REVLOG_MAIN
424 FILETYPE_MANIFESTLOG_OTHER = FILEFLAGS_MANIFESTLOG | FILEFLAGS_REVLOG_OTHER
425 FILETYPE_FILELOG_MAIN = FILEFLAGS_FILELOG | FILEFLAGS_REVLOG_MAIN
426 FILETYPE_FILELOG_OTHER = FILEFLAGS_FILELOG | FILEFLAGS_REVLOG_OTHER
427 FILETYPE_OTHER = FILEFLAGS_OTHER
397 428
398 429
399 class basicstore(object): 430 class basicstore(object):
400 '''base class for local repository stores''' 431 '''base class for local repository stores'''
401 432
423 readdir = self.rawvfs.readdir 454 readdir = self.rawvfs.readdir
424 while visit: 455 while visit:
425 p = visit.pop() 456 p = visit.pop()
426 for f, kind, st in readdir(p, stat=True): 457 for f, kind, st in readdir(p, stat=True):
427 fp = p + b'/' + f 458 fp = p + b'/' + f
428 if isrevlog(f, kind, st): 459 rl_type = is_revlog(f, kind, st)
460 if rl_type is not None:
429 n = util.pconvert(fp[striplen:]) 461 n = util.pconvert(fp[striplen:])
430 l.append((decodedir(n), n, st.st_size)) 462 l.append((rl_type, decodedir(n), n, st.st_size))
431 elif kind == stat.S_IFDIR and recurse: 463 elif kind == stat.S_IFDIR and recurse:
432 visit.append(fp) 464 visit.append(fp)
433 l.sort() 465 l.sort()
434 return l 466 return l
435 467
443 def manifestlog(self, repo, storenarrowmatch): 475 def manifestlog(self, repo, storenarrowmatch):
444 rootstore = manifest.manifestrevlog(repo.nodeconstants, self.vfs) 476 rootstore = manifest.manifestrevlog(repo.nodeconstants, self.vfs)
445 return manifest.manifestlog(self.vfs, repo, rootstore, storenarrowmatch) 477 return manifest.manifestlog(self.vfs, repo, rootstore, storenarrowmatch)
446 478
447 def datafiles(self, matcher=None): 479 def datafiles(self, matcher=None):
448 return self._walk(b'data', True) + self._walk(b'meta', True) 480 files = self._walk(b'data', True) + self._walk(b'meta', True)
481 for (t, u, e, s) in files:
482 yield (FILEFLAGS_FILELOG | t, u, e, s)
449 483
450 def topfiles(self): 484 def topfiles(self):
451 # yield manifest before changelog 485 # yield manifest before changelog
452 return reversed(self._walk(b'', False)) 486 files = reversed(self._walk(b'', False))
487 for (t, u, e, s) in files:
488 if u.startswith(b'00changelog'):
489 yield (FILEFLAGS_CHANGELOG | t, u, e, s)
490 elif u.startswith(b'00manifest'):
491 yield (FILEFLAGS_MANIFESTLOG | t, u, e, s)
492 else:
493 yield (FILETYPE_OTHER | t, u, e, s)
453 494
454 def walk(self, matcher=None): 495 def walk(self, matcher=None):
455 """return file related to data storage (ie: revlogs) 496 """return file related to data storage (ie: revlogs)
456 497
457 yields (unencoded, encoded, size) 498 yields (file_type, unencoded, encoded, size)
458 499
459 if a matcher is passed, storage files of only those tracked paths 500 if a matcher is passed, storage files of only those tracked paths
460 are passed with matches the matcher 501 are passed with matches the matcher
461 """ 502 """
462 # yield data files first 503 # yield data files first
498 self.rawvfs = vfs 539 self.rawvfs = vfs
499 self.vfs = vfsmod.filtervfs(vfs, encodefilename) 540 self.vfs = vfsmod.filtervfs(vfs, encodefilename)
500 self.opener = self.vfs 541 self.opener = self.vfs
501 542
502 def datafiles(self, matcher=None): 543 def datafiles(self, matcher=None):
503 for a, b, size in super(encodedstore, self).datafiles(): 544 for t, a, b, size in super(encodedstore, self).datafiles():
504 try: 545 try:
505 a = decodefilename(a) 546 a = decodefilename(a)
506 except KeyError: 547 except KeyError:
507 a = None 548 a = None
508 if a is not None and not _matchtrackedpath(a, matcher): 549 if a is not None and not _matchtrackedpath(a, matcher):
509 continue 550 continue
510 yield a, b, size 551 yield t, a, b, size
511 552
512 def join(self, f): 553 def join(self, f):
513 return self.path + b'/' + encodefilename(f) 554 return self.path + b'/' + encodefilename(f)
514 555
515 def copylist(self): 556 def copylist(self):
694 for f in sorted(self.fncache): 735 for f in sorted(self.fncache):
695 if not _matchtrackedpath(f, matcher): 736 if not _matchtrackedpath(f, matcher):
696 continue 737 continue
697 ef = self.encode(f) 738 ef = self.encode(f)
698 try: 739 try:
699 yield f, ef, self.getsize(ef) 740 t = revlog_type(f)
741 t |= FILEFLAGS_FILELOG
742 yield t, f, ef, self.getsize(ef)
700 except OSError as err: 743 except OSError as err:
701 if err.errno != errno.ENOENT: 744 if err.errno != errno.ENOENT:
702 raise 745 raise
703 746
704 def copylist(self): 747 def copylist(self):