~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

Merge tarball branch that's already with PQM, resolving conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
31
32
 
32
33
# Note: RemoteBzrDirFormat is in bzrdir.py
33
34
 
430
431
        self._ensure_real()
431
432
        return self._real_repository.break_lock()
432
433
 
 
434
    def _get_tarball(self, compression):
 
435
        """Return a TemporaryFile containing a repository tarball"""
 
436
        import tempfile
 
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())
 
447
            t.seek(0)
 
448
            return t
 
449
        else:
 
450
            raise errors.SmartServerError(error_code=response)
 
451
 
 
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)
 
456
        return to_repo
 
457
 
433
458
    ### These methods are just thin shims to the VFS object for now.
434
459
 
435
460
    def revision_tree(self, revision_id):
570
595
        return self._real_repository.copy_content_into(
571
596
            destination, revision_id=revision_id)
572
597
 
 
598
    def _copy_repository_tarball(self, destination, revision_id=None):
 
599
        # get a tarball of the remote repository, and copy from that into the
 
600
        # destination
 
601
        from bzrlib import osutils
 
602
        import tarfile
 
603
        import tempfile
 
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')
 
608
        try:
 
609
            tar = tarfile.open('repository', fileobj=tar_file,
 
610
                mode='r|bz2')
 
611
            tmpdir = tempfile.mkdtemp()
 
612
            try:
 
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)
 
617
            finally:
 
618
                osutils.rmtree(tmpdir)
 
619
        finally:
 
620
            tar_file.close()
 
621
        # TODO: if the server doesn't support this operation, maybe do it the
 
622
        # slow way using the _real_repository?
 
623
        #
 
624
        # TODO: Suggestion from john: using external tar is much faster than
 
625
        # python's tarfile library, but it may not work on windows.
 
626
 
573
627
    def set_make_working_trees(self, new_value):
574
628
        raise NotImplementedError(self.set_make_working_trees)
575
629
 
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...
929
 
        self._ensure_real()
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)
933
986
        return result
934
987
 
990
1043
            self._branch_data_config = TreeConfig(self.branch._real_branch)
991
1044
        return self._branch_data_config
992
1045
 
 
1046
 
 
1047
def _extract_tar(tar, to_dir):
 
1048
    """Extract all the contents of a tarfile object.
 
1049
 
 
1050
    A replacement for extractall, which is not present in python2.4
 
1051
    """
 
1052
    for tarinfo in tar:
 
1053
        tar.extract(tarinfo, to_dir)