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
431
432
self._ensure_real()
432
433
return self._real_repository.break_lock()
435
def _get_tarball(self, compression):
436
"""Return a TemporaryFile containing a repository tarball"""
438
path = self.bzrdir._path_for_remote_call(self._client)
439
response, protocol = self._client.call_expecting_body(
440
'Repository.tarball', path, compression)
441
assert response[0] in ('ok', 'failure'), \
442
'unexpected response code %s' % (response,)
443
if response[0] == 'ok':
444
# Extract the tarball and return it
445
t = tempfile.NamedTemporaryFile()
446
# TODO: rpc layer should read directly into it...
447
t.write(protocol.read_body_bytes())
451
raise errors.SmartServerError(error_code=response)
453
def sprout(self, to_bzrdir, revision_id=None):
454
# TODO: Option to control what format is created?
455
to_repo = to_bzrdir.create_repository()
456
self._copy_repository_tarball(to_repo, revision_id)
434
459
### These methods are just thin shims to the VFS object for now.
436
461
def revision_tree(self, revision_id):
571
596
return self._real_repository.copy_content_into(
572
597
destination, revision_id=revision_id)
599
def _copy_repository_tarball(self, destination, revision_id=None):
600
# get a tarball of the remote repository, and copy from that into the
602
from bzrlib import osutils
605
from StringIO import StringIO
606
# TODO: Maybe a progress bar while streaming the tarball?
607
note("Copying repository content as tarball...")
608
tar_file = self._get_tarball('bz2')
610
tar = tarfile.open('repository', fileobj=tar_file,
612
tmpdir = tempfile.mkdtemp()
614
_extract_tar(tar, tmpdir)
615
tmp_bzrdir = BzrDir.open(tmpdir)
616
tmp_repo = tmp_bzrdir.open_repository()
617
tmp_repo.copy_content_into(destination, revision_id)
619
osutils.rmtree(tmpdir)
622
# TODO: if the server doesn't support this operation, maybe do it the
623
# slow way using the _real_repository?
625
# TODO: Suggestion from john: using external tar is much faster than
626
# python's tarfile library, but it may not work on windows.
574
628
def set_make_working_trees(self, new_value):
575
629
raise NotImplementedError(self.set_make_working_trees)
927
981
# format, because RemoteBranches can't be created at arbitrary URLs.
928
982
# XXX: if to_bzrdir is a RemoteBranch, this should perhaps do
929
983
# to_bzrdir.create_branch...
931
984
result = branch.BranchFormat.get_default_format().initialize(to_bzrdir)
932
self._real_branch.copy_content_into(result, revision_id=revision_id)
985
self.copy_content_into(result, revision_id=revision_id)
933
986
result.set_parent(self.bzrdir.root_transport.base)
991
1044
self._branch_data_config = TreeConfig(self.branch._real_branch)
992
1045
return self._branch_data_config
1048
def _extract_tar(tar, to_dir):
1049
"""Extract all the contents of a tarfile object.
1051
A replacement for extractall, which is not present in python2.4
1054
tar.extract(tarinfo, to_dir)