Mercurial > hg
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 |