29
from bzrlib.branch import Branch, BranchReferenceFormat
29
from bzrlib.branch import BranchReferenceFormat
30
30
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
31
31
from bzrlib.config import BranchConfig, TreeConfig
32
32
from bzrlib.decorators import needs_read_lock, needs_write_lock
33
33
from bzrlib.errors import NoSuchRevision
34
34
from bzrlib.lockable_files import LockableFiles
35
from bzrlib.pack import ContainerReader
35
from bzrlib.pack import ContainerPushParser
36
36
from bzrlib.smart import client, vfs
37
37
from bzrlib.symbol_versioning import (
41
from bzrlib.revision import NULL_REVISION
41
42
from bzrlib.trace import note
43
44
# Note: RemoteBzrDirFormat is in bzrdir.py
368
369
def has_revision(self, revision_id):
369
370
"""See Repository.has_revision()."""
370
if revision_id is None:
371
if revision_id == NULL_REVISION:
371
372
# The null revision is always present.
373
374
path = self.bzrdir._path_for_remote_call(self._client)
375
376
assert response[0] in ('yes', 'no'), 'unexpected response code %s' % (response,)
376
377
return response[0] == 'yes'
379
def has_revisions(self, revision_ids):
380
"""See Repository.has_revisions()."""
382
for revision_id in revision_ids:
383
if self.has_revision(revision_id):
384
result.add(revision_id)
378
387
def has_same_location(self, other):
379
388
return (self.__class__ == other.__class__ and
380
389
self.bzrdir.transport.base == other.bzrdir.transport.base)
644
653
self._ensure_real()
645
654
return self._real_repository.get_inventory(revision_id)
656
def iter_inventories(self, revision_ids):
658
return self._real_repository.iter_inventories(revision_ids)
648
661
def get_revision(self, revision_id):
649
662
self._ensure_real()
777
790
from bzrlib import osutils
780
from StringIO import StringIO
781
793
# TODO: Maybe a progress bar while streaming the tarball?
782
794
note("Copying repository content as tarball...")
783
795
tar_file = self._get_tarball('bz2')
850
862
return self._real_repository.has_signature_for_revision_id(revision_id)
852
864
def get_data_stream(self, revision_ids):
865
REQUEST_NAME = 'Repository.stream_revisions_chunked'
853
866
path = self.bzrdir._path_for_remote_call(self._client)
854
867
response, protocol = self._client.call_expecting_body(
855
'Repository.stream_knit_data_for_revisions', path, *revision_ids)
868
REQUEST_NAME, path, *revision_ids)
856
870
if response == ('ok',):
857
871
return self._deserialise_stream(protocol)
858
872
elif (response == ('error', "Generic bzr smart protocol error: "
859
"bad request 'Repository.stream_knit_data_for_revisions'") or
873
"bad request '%s'" % REQUEST_NAME) or
860
874
response == ('error', "Generic bzr smart protocol error: "
861
"bad request u'Repository.stream_knit_data_for_revisions'")):
875
"bad request u'%s'" % REQUEST_NAME)):
862
876
protocol.cancel_read_body()
863
877
self._ensure_real()
864
878
return self._real_repository.get_data_stream(revision_ids)
866
880
raise errors.UnexpectedSmartServerResponse(response)
868
882
def _deserialise_stream(self, protocol):
869
buffer = StringIO(protocol.read_body_bytes())
870
reader = ContainerReader(buffer)
871
for record_names, read_bytes in reader.iter_records():
873
# These records should have only one name, and that name
874
# should be a one-element tuple.
875
[name_tuple] = record_names
877
raise errors.SmartProtocolError(
878
'Repository data stream had invalid record name %r'
880
yield name_tuple, read_bytes(None)
883
stream = protocol.read_streamed_body()
884
container_parser = ContainerPushParser()
886
container_parser.accept_bytes(bytes)
887
records = container_parser.read_pending_records()
888
for record_names, record_bytes in records:
889
if len(record_names) != 1:
890
# These records should have only one name, and that name
891
# should be a one-element tuple.
892
raise errors.SmartProtocolError(
893
'Repository data stream had invalid record name %r'
895
name_tuple = record_names[0]
896
yield name_tuple, record_bytes
882
898
def insert_data_stream(self, stream):
883
899
self._ensure_real()