comparison mercurial/streamclone.py @ 50639:5e60abf811f3

stream-clone: make it the responsability of the store entry to stream content The store entry has more context, this will especially be true when it comes to revlogs. So we move the details of how to retrieve binary content to the StoreEntry. The stream clone code now focus on the protocol bits.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Sun, 28 May 2023 05:52:58 +0200
parents c90ea9bbf327
children 9caa860dcbec
comparison
equal deleted inserted replaced
50638:8fc10bfd9887 50639:5e60abf811f3
9 import contextlib 9 import contextlib
10 import os 10 import os
11 import struct 11 import struct
12 12
13 from .i18n import _ 13 from .i18n import _
14 from .pycompat import open
15 from .interfaces import repository 14 from .interfaces import repository
16 from . import ( 15 from . import (
17 bookmarks, 16 bookmarks,
18 bundle2 as bundle2mod, 17 bundle2 as bundle2mod,
19 cacheutil, 18 cacheutil,
656 # the first yield release the lock on the repository 655 # the first yield release the lock on the repository
657 yield file_count, totalfilesize 656 yield file_count, totalfilesize
658 totalbytecount = 0 657 totalbytecount = 0
659 658
660 for src, vfs, e in entries: 659 for src, vfs, e in entries:
661 for f in e.files(): 660 for name, stream, size in e.get_streams(vfs, copies=copy):
662 yield src 661 yield src
663 name = f.unencoded_path
664 yield util.uvarintencode(len(name)) 662 yield util.uvarintencode(len(name))
665 actual_path = copy[vfs.join(name)] 663 yield util.uvarintencode(size)
666 fp = open(actual_path, b'rb') 664 yield name
667 size = f.file_size(vfs)
668 bytecount = 0 665 bytecount = 0
669 try: 666 for chunk in stream:
670 yield util.uvarintencode(size) 667 bytecount += len(chunk)
671 yield name 668 totalbytecount += len(chunk)
672 if size <= 65536: 669 progress.update(totalbytecount)
673 chunks = (fp.read(size),) 670 yield chunk
674 else: 671 if bytecount != size:
675 chunks = util.filechunkiter(fp, limit=size) 672 # Would most likely be caused by a race due to `hg
676 for chunk in chunks: 673 # strip` or a revlog split
677 bytecount += len(chunk) 674 msg = _(
678 totalbytecount += len(chunk) 675 b'clone could only read %d bytes from %s, but '
679 progress.update(totalbytecount) 676 b'expected %d bytes'
680 yield chunk 677 )
681 if bytecount != size: 678 raise error.Abort(msg % (bytecount, name, size))
682 # Would most likely be caused by a race due to `hg
683 # strip` or a revlog split
684 msg = _(
685 b'clone could only read %d bytes from %s, but '
686 b'expected %d bytes'
687 )
688 raise error.Abort(msg % (bytecount, name, size))
689 finally:
690 fp.close()
691 679
692 680
693 def _test_sync_point_walk_1(repo): 681 def _test_sync_point_walk_1(repo):
694 """a function for synchronisation during tests""" 682 """a function for synchronisation during tests"""
695 683