28
28
from bzrlib.lockable_files import LockableFiles
29
29
from bzrlib.revision import NULL_REVISION
30
30
from bzrlib.smart import client, vfs
31
from bzrlib.trace import note
32
33
# Note: RemoteBzrDirFormat is in bzrdir.py
430
431
self._ensure_real()
431
432
return self._real_repository.break_lock()
434
def _get_tarball(self, compression):
435
"""Return a TemporaryFile containing a repository tarball"""
437
path = self.bzrdir._path_for_remote_call(self._client)
438
response, protocol = self._client.call_expecting_body(
439
'Repository.tarball', path, compression)
440
assert response[0] in ('ok', 'failure'), \
441
'unexpected response code %s' % (response,)
442
if response[0] == 'ok':
443
# Extract the tarball and return it
444
t = tempfile.NamedTemporaryFile()
445
# TODO: rpc layer should read directly into it...
446
t.write(protocol.read_body_bytes())
450
raise errors.SmartServerError(error_code=response)
452
def sprout(self, to_bzrdir, revision_id=None):
453
# TODO: Option to control what format is created?
454
to_repo = to_bzrdir.create_repository()
455
self._copy_repository_tarball(to_repo, revision_id)
433
458
### These methods are just thin shims to the VFS object for now.
435
460
def revision_tree(self, revision_id):
570
595
return self._real_repository.copy_content_into(
571
596
destination, revision_id=revision_id)
598
def _copy_repository_tarball(self, destination, revision_id=None):
599
# get a tarball of the remote repository, and copy from that into the
601
from bzrlib import osutils
604
from StringIO import StringIO
605
# TODO: Maybe a progress bar while streaming the tarball?
606
note("Copying repository content as tarball...")
607
tar_file = self._get_tarball('bz2')
609
tar = tarfile.open('repository', fileobj=tar_file,
611
tmpdir = tempfile.mkdtemp()
613
_extract_tar(tar, tmpdir)
614
tmp_bzrdir = BzrDir.open(tmpdir)
615
tmp_repo = tmp_bzrdir.open_repository()
616
tmp_repo.copy_content_into(destination, revision_id)
618
osutils.rmtree(tmpdir)
621
# TODO: if the server doesn't support this operation, maybe do it the
622
# slow way using the _real_repository?
624
# TODO: Suggestion from john: using external tar is much faster than
625
# python's tarfile library, but it may not work on windows.
573
627
def set_make_working_trees(self, new_value):
574
628
raise NotImplementedError(self.set_make_working_trees)
926
980
# format, because RemoteBranches can't be created at arbitrary URLs.
927
981
# XXX: if to_bzrdir is a RemoteBranch, this should perhaps do
928
982
# to_bzrdir.create_branch...
930
983
result = branch.BranchFormat.get_default_format().initialize(to_bzrdir)
931
self._real_branch.copy_content_into(result, revision_id=revision_id)
984
self.copy_content_into(result, revision_id=revision_id)
932
985
result.set_parent(self.bzrdir.root_transport.base)
990
1043
self._branch_data_config = TreeConfig(self.branch._real_branch)
991
1044
return self._branch_data_config
1047
def _extract_tar(tar, to_dir):
1048
"""Extract all the contents of a tarfile object.
1050
A replacement for extractall, which is not present in python2.4
1053
tar.extract(tarinfo, to_dir)