Show More
@@ -514,7 +514,7 b' def unixpath(path):' | |||
|
514 | 514 | def islfilesrepo(repo): |
|
515 | 515 | '''Return true if the repo is a largefile repo.''' |
|
516 | 516 | if b'largefiles' in repo.requirements and any( |
|
517 |
shortnameslash in f[ |
|
|
517 | shortnameslash in f[1] for f in repo.store.datafiles() | |
|
518 | 518 | ): |
|
519 | 519 | return True |
|
520 | 520 |
@@ -445,7 +445,7 b' def reposetup(ui, repo):' | |||
|
445 | 445 | |
|
446 | 446 | def checkrequireslfiles(ui, repo, **kwargs): |
|
447 | 447 | if b'largefiles' not in repo.requirements and any( |
|
448 |
lfutil.shortname + b'/' in f[ |
|
|
448 | lfutil.shortname + b'/' in f[1] for f in repo.store.datafiles() | |
|
449 | 449 | ): |
|
450 | 450 | repo.requirements.add(b'largefiles') |
|
451 | 451 | scmutil.writereporequirements(repo) |
@@ -276,7 +276,7 b' def _narrow(' | |||
|
276 | 276 | repair.strip(ui, unfi, tostrip, topic=b'narrow', backup=backup) |
|
277 | 277 | |
|
278 | 278 | todelete = [] |
|
279 | for f, f2, size in repo.store.datafiles(): | |
|
279 | for t, f, f2, size in repo.store.datafiles(): | |
|
280 | 280 | if f.startswith(b'data/'): |
|
281 | 281 | file = f[5:-2] |
|
282 | 282 | if not newmatch(file): |
@@ -365,7 +365,7 b' class manifestrevlogstore(object):' | |||
|
365 | 365 | ledger.markdataentry(self, treename, node) |
|
366 | 366 | ledger.markhistoryentry(self, treename, node) |
|
367 | 367 | |
|
368 | for path, encoded, size in self._store.datafiles(): | |
|
368 | for t, path, encoded, size in self._store.datafiles(): | |
|
369 | 369 | if path[:5] != b'meta/' or path[-2:] != b'.i': |
|
370 | 370 | continue |
|
371 | 371 |
@@ -164,24 +164,26 b' def onetimesetup(ui):' | |||
|
164 | 164 | b'.d' |
|
165 | 165 | ): |
|
166 | 166 | n = util.pconvert(fp[striplen:]) |
|
167 |
|
|
|
167 | d = store.decodedir(n) | |
|
168 | t = store.FILETYPE_OTHER | |
|
169 | yield (t, d, n, st.st_size) | |
|
168 | 170 | if kind == stat.S_IFDIR: |
|
169 | 171 | visit.append(fp) |
|
170 | 172 | |
|
171 | 173 | if scmutil.istreemanifest(repo): |
|
172 | for (u, e, s) in repo.store.datafiles(): | |
|
174 | for (t, u, e, s) in repo.store.datafiles(): | |
|
173 | 175 | if u.startswith(b'meta/') and ( |
|
174 | 176 | u.endswith(b'.i') or u.endswith(b'.d') |
|
175 | 177 | ): |
|
176 | yield (u, e, s) | |
|
178 | yield (t, u, e, s) | |
|
177 | 179 | |
|
178 | 180 | # Return .d and .i files that do not match the shallow pattern |
|
179 | 181 | match = state.match |
|
180 | 182 | if match and not match.always(): |
|
181 | for (u, e, s) in repo.store.datafiles(): | |
|
183 | for (t, u, e, s) in repo.store.datafiles(): | |
|
182 | 184 | f = u[5:-2] # trim data/... and .i/.d |
|
183 | 185 | if not state.match(f): |
|
184 | yield (u, e, s) | |
|
186 | yield (t, u, e, s) | |
|
185 | 187 | |
|
186 | 188 | for x in repo.store.topfiles(): |
|
187 | 189 | if state.noflatmf and x[0][:11] == b'00manifest.': |
@@ -428,7 +428,7 b' def manifestrevlogs(repo):' | |||
|
428 | 428 | if scmutil.istreemanifest(repo): |
|
429 | 429 | # This logic is safe if treemanifest isn't enabled, but also |
|
430 | 430 | # pointless, so we skip it if treemanifest isn't enabled. |
|
431 | for unencoded, encoded, size in repo.store.datafiles(): | |
|
431 | for t, unencoded, encoded, size in repo.store.datafiles(): | |
|
432 | 432 | if unencoded.startswith(b'meta/') and unencoded.endswith( |
|
433 | 433 | b'00manifest.i' |
|
434 | 434 | ): |
@@ -387,13 +387,44 b' def _calcmode(vfs):' | |||
|
387 | 387 | b'requires', |
|
388 | 388 | ] |
|
389 | 389 | |
|
390 |
REVLOG_FILES_EXT = (b'.i', b' |
|
|
390 | REVLOG_FILES_MAIN_EXT = (b'.i', b'i.tmpcensored') | |
|
391 | REVLOG_FILES_OTHER_EXT = (b'.d', b'.n', b'.nd', b'd.tmpcensored') | |
|
392 | ||
|
393 | ||
|
394 | def is_revlog(f, kind, st): | |
|
395 | if kind != stat.S_IFREG: | |
|
396 | return None | |
|
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 | |
|
391 | 405 | |
|
392 | 406 | |
|
393 | def isrevlog(f, kind, st): | |
|
394 | if kind != stat.S_IFREG: | |
|
395 | return False | |
|
396 | return f.endswith(REVLOG_FILES_EXT) | |
|
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 | 430 | class basicstore(object): |
@@ -425,9 +456,10 b' class basicstore(object):' | |||
|
425 | 456 | p = visit.pop() |
|
426 | 457 | for f, kind, st in readdir(p, stat=True): |
|
427 | 458 | fp = p + b'/' + f |
|
428 |
|
|
|
459 | rl_type = is_revlog(f, kind, st) | |
|
460 | if rl_type is not None: | |
|
429 | 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 | 463 | elif kind == stat.S_IFDIR and recurse: |
|
432 | 464 | visit.append(fp) |
|
433 | 465 | l.sort() |
@@ -445,16 +477,25 b' class basicstore(object):' | |||
|
445 | 477 | return manifest.manifestlog(self.vfs, repo, rootstore, storenarrowmatch) |
|
446 | 478 | |
|
447 | 479 | def datafiles(self, matcher=None): |
|
448 |
|
|
|
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 | 484 | def topfiles(self): |
|
451 | 485 | # yield manifest before changelog |
|
452 |
|
|
|
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 | 495 | def walk(self, matcher=None): |
|
455 | 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 | 500 | if a matcher is passed, storage files of only those tracked paths |
|
460 | 501 | are passed with matches the matcher |
@@ -500,14 +541,14 b' class encodedstore(basicstore):' | |||
|
500 | 541 | self.opener = self.vfs |
|
501 | 542 | |
|
502 | 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 | 545 | try: |
|
505 | 546 | a = decodefilename(a) |
|
506 | 547 | except KeyError: |
|
507 | 548 | a = None |
|
508 | 549 | if a is not None and not _matchtrackedpath(a, matcher): |
|
509 | 550 | continue |
|
510 | yield a, b, size | |
|
551 | yield t, a, b, size | |
|
511 | 552 | |
|
512 | 553 | def join(self, f): |
|
513 | 554 | return self.path + b'/' + encodefilename(f) |
@@ -696,7 +737,9 b' class fncachestore(basicstore):' | |||
|
696 | 737 | continue |
|
697 | 738 | ef = self.encode(f) |
|
698 | 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 | 743 | except OSError as err: |
|
701 | 744 | if err.errno != errno.ENOENT: |
|
702 | 745 | raise |
@@ -243,7 +243,7 b' def generatev1(repo):' | |||
|
243 | 243 | # Get consistent snapshot of repo, lock during scan. |
|
244 | 244 | with repo.lock(): |
|
245 | 245 | repo.ui.debug(b'scanning\n') |
|
246 | for name, ename, size in _walkstreamfiles(repo): | |
|
246 | for file_type, name, ename, size in _walkstreamfiles(repo): | |
|
247 | 247 | if size: |
|
248 | 248 | entries.append((name, size)) |
|
249 | 249 | total_bytes += size |
@@ -616,7 +616,7 b' def generatev2(repo, includes, excludes,' | |||
|
616 | 616 | matcher = narrowspec.match(repo.root, includes, excludes) |
|
617 | 617 | |
|
618 | 618 | repo.ui.debug(b'scanning\n') |
|
619 | for name, ename, size in _walkstreamfiles(repo, matcher): | |
|
619 | for rl_type, name, ename, size in _walkstreamfiles(repo, matcher): | |
|
620 | 620 | if size: |
|
621 | 621 | entries.append((_srcstore, name, _fileappend, size)) |
|
622 | 622 | totalfilesize += size |
@@ -192,7 +192,7 b' def _clonerevlogs(' | |||
|
192 | 192 | |
|
193 | 193 | # Perform a pass to collect metadata. This validates we can open all |
|
194 | 194 | # source files and allows a unified progress bar to be displayed. |
|
195 | for unencoded, encoded, size in alldatafiles: | |
|
195 | for revlog_type, unencoded, encoded, size in alldatafiles: | |
|
196 | 196 | if not unencoded.endswith(b'.i'): |
|
197 | 197 | continue |
|
198 | 198 |
@@ -416,7 +416,7 b' class verifier(object):' | |||
|
416 | 416 | storefiles = set() |
|
417 | 417 | subdirs = set() |
|
418 | 418 | revlogv1 = self.revlogv1 |
|
419 | for f, f2, size in repo.store.datafiles(): | |
|
419 | for t, f, f2, size in repo.store.datafiles(): | |
|
420 | 420 | if not f: |
|
421 | 421 | self._err(None, _(b"cannot decode filename '%s'") % f2) |
|
422 | 422 | elif (size > 0 or not revlogv1) and f.startswith(b'meta/'): |
@@ -480,7 +480,7 b' class verifier(object):' | |||
|
480 | 480 | ui.status(_(b"checking files\n")) |
|
481 | 481 | |
|
482 | 482 | storefiles = set() |
|
483 | for f, f2, size in repo.store.datafiles(): | |
|
483 | for rl_type, f, f2, size in repo.store.datafiles(): | |
|
484 | 484 | if not f: |
|
485 | 485 | self._err(None, _(b"cannot decode filename '%s'") % f2) |
|
486 | 486 | elif (size > 0 or not revlogv1) and f.startswith(b'data/'): |
@@ -1582,7 +1582,8 b' def rawstorefiledata(repo, proto, files,' | |||
|
1582 | 1582 | |
|
1583 | 1583 | # TODO this is a bunch of storage layer interface abstractions because |
|
1584 | 1584 | # it assumes revlogs. |
|
1585 | for name, encodedname, size in topfiles: | |
|
1585 | for rl_type, name, encodedname, size in topfiles: | |
|
1586 | # XXX use the `rl_type` for that | |
|
1586 | 1587 | if b'changelog' in files and name.startswith(b'00changelog'): |
|
1587 | 1588 | pass |
|
1588 | 1589 | elif b'manifestlog' in files and name.startswith(b'00manifest'): |
@@ -754,15 +754,15 b' The persistent nodemap should exist afte' | |||
|
754 | 754 | |
|
755 | 755 | $ hg clone -U --stream --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/test-repo stream-clone --debug | egrep '00(changelog|manifest)' |
|
756 | 756 | adding [s] 00manifest.n (70 bytes) |
|
757 | adding [s] 00manifest.i (313 KB) | |
|
758 | 757 | adding [s] 00manifest.d (452 KB) (no-zstd !) |
|
759 | 758 | adding [s] 00manifest.d (491 KB) (zstd !) |
|
760 | 759 | adding [s] 00manifest-*.nd (118 KB) (glob) |
|
761 | 760 | adding [s] 00changelog.n (70 bytes) |
|
762 | adding [s] 00changelog.i (313 KB) | |
|
763 | 761 | adding [s] 00changelog.d (360 KB) (no-zstd !) |
|
764 | 762 | adding [s] 00changelog.d (368 KB) (zstd !) |
|
765 | 763 | adding [s] 00changelog-*.nd (118 KB) (glob) |
|
764 | adding [s] 00manifest.i (313 KB) | |
|
765 | adding [s] 00changelog.i (313 KB) | |
|
766 | 766 | $ ls -1 stream-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)' |
|
767 | 767 | 00changelog-*.nd (glob) |
|
768 | 768 | 00changelog.n |
General Comments 0
You need to be logged in to leave comments.
Login now