/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
from bzrlib.decorators import needs_read_lock, needs_write_lock
32
32
from bzrlib.errors import NoSuchRevision
33
33
from bzrlib.lockable_files import LockableFiles
 
34
from bzrlib.pack import ContainerReader
34
35
from bzrlib.revision import NULL_REVISION
35
36
from bzrlib.smart import client, vfs
36
37
from bzrlib.symbol_versioning import (
89
90
        real_branch = self._real_bzrdir.create_branch()
90
91
        return RemoteBranch(self, self.find_repository(), real_branch)
91
92
 
 
93
    def destroy_branch(self):
 
94
        """See BzrDir.destroy_branch"""
 
95
        self._ensure_real()
 
96
        self._real_bzrdir.destroy_branch()
 
97
 
92
98
    def create_workingtree(self, revision_id=None):
93
99
        raise errors.NotLocalUrl(self.transport.base)
94
100
 
254
260
        self._leave_lock = False
255
261
        # for tests
256
262
        self._reconcile_does_inventory_gc = True
 
263
        self._reconcile_fixes_text_parents = True
 
264
        self.base = self.bzrdir.transport.base
 
265
 
 
266
    def __str__(self):
 
267
        return "%s(%s)" % (self.__class__.__name__, self.base)
 
268
 
 
269
    __repr__ = __str__
257
270
 
258
271
    def abort_write_group(self):
259
272
        """Complete a write group on the decorated repository.
333
346
        
334
347
    def get_graph(self, other_repository=None):
335
348
        """Return the graph for this repository format"""
 
349
        self._ensure_real()
336
350
        return self._real_repository.get_graph(other_repository)
337
351
 
338
352
    def gather_stats(self, revid=None, committers=None):
387
401
        assert response[0] in ('yes', 'no'), 'unexpected response code %s' % (response,)
388
402
        return response[0] == 'yes'
389
403
 
 
404
    def is_write_locked(self):
 
405
        return self._lock_mode == 'w'
 
406
 
390
407
    def lock_read(self):
391
408
        # wrong eventually - want a local lock cache context
392
409
        if not self._lock_mode:
409
426
            raise errors.LockContention('(remote lock)')
410
427
        elif response[0] == 'UnlockableTransport':
411
428
            raise errors.UnlockableTransport(self.bzrdir.root_transport)
 
429
        elif response[0] == 'LockFailed':
 
430
            raise errors.LockFailed(response[1], response[2])
412
431
        else:
413
432
            raise errors.UnexpectedSmartServerResponse(response)
414
433
 
500
519
        return self._real_repository.break_lock()
501
520
 
502
521
    def _get_tarball(self, compression):
503
 
        """Return a TemporaryFile containing a repository tarball"""
 
522
        """Return a TemporaryFile containing a repository tarball.
 
523
        
 
524
        Returns None if the server does not support sending tarballs.
 
525
        """
504
526
        import tempfile
505
527
        path = self.bzrdir._path_for_remote_call(self._client)
506
528
        response, protocol = self._client.call_expecting_body(
507
529
            'Repository.tarball', path, compression)
508
 
        assert response[0] in ('ok', 'failure'), \
509
 
            'unexpected response code %s' % (response,)
510
530
        if response[0] == 'ok':
511
531
            # Extract the tarball and return it
512
532
            t = tempfile.NamedTemporaryFile()
514
534
            t.write(protocol.read_body_bytes())
515
535
            t.seek(0)
516
536
            return t
517
 
        else:
518
 
            raise errors.SmartServerError(error_code=response)
 
537
        if (response == ('error', "Generic bzr smart protocol error: "
 
538
                "bad request 'Repository.tarball'") or
 
539
              response == ('error', "Generic bzr smart protocol error: "
 
540
                "bad request u'Repository.tarball'")):
 
541
            protocol.cancel_read_body()
 
542
            return None
 
543
        raise errors.UnexpectedSmartServerResponse(response)
519
544
 
520
545
    def sprout(self, to_bzrdir, revision_id=None):
521
546
        # TODO: Option to control what format is created?
522
 
        to_repo = to_bzrdir.create_repository()
523
 
        self._copy_repository_tarball(to_repo, revision_id)
524
 
        return to_repo
 
547
        dest_repo = to_bzrdir.create_repository()
 
548
        dest_repo.fetch(self, revision_id=revision_id)
 
549
        return dest_repo
525
550
 
526
551
    ### These methods are just thin shims to the VFS object for now.
527
552
 
586
611
        return False
587
612
 
588
613
    def fetch(self, source, revision_id=None, pb=None):
 
614
        if self.has_same_location(source):
 
615
            # check that last_revision is in 'from' and then return a
 
616
            # no-operation.
 
617
            if (revision_id is not None and
 
618
                not _mod_revision.is_null(revision_id)):
 
619
                self.get_revision(revision_id)
 
620
            return 0, []
589
621
        self._ensure_real()
590
622
        return self._real_repository.fetch(
591
623
            source, revision_id=revision_id, pb=pb)
613
645
        self._ensure_real()
614
646
        return self._real_repository.fileids_altered_by_revision_ids(revision_ids)
615
647
 
 
648
    def get_versioned_file_checker(self, revisions, revision_versions_cache):
 
649
        self._ensure_real()
 
650
        return self._real_repository.get_versioned_file_checker(
 
651
            revisions, revision_versions_cache)
 
652
        
616
653
    def iter_files_bytes(self, desired_files):
617
654
        """See Repository.iter_file_bytes.
618
655
        """
668
705
        return self._real_repository.get_revision_reconcile(revision_id)
669
706
 
670
707
    @needs_read_lock
671
 
    def check(self, revision_ids):
 
708
    def check(self, revision_ids=None):
672
709
        self._ensure_real()
673
 
        return self._real_repository.check(revision_ids)
 
710
        return self._real_repository.check(revision_ids=revision_ids)
674
711
 
675
712
    def copy_content_into(self, destination, revision_id=None):
676
713
        self._ensure_real()
677
714
        return self._real_repository.copy_content_into(
678
715
            destination, revision_id=revision_id)
679
716
 
680
 
    def _copy_repository_tarball(self, destination, revision_id=None):
 
717
    def _copy_repository_tarball(self, to_bzrdir, revision_id=None):
681
718
        # get a tarball of the remote repository, and copy from that into the
682
719
        # destination
683
720
        from bzrlib import osutils
687
724
        # TODO: Maybe a progress bar while streaming the tarball?
688
725
        note("Copying repository content as tarball...")
689
726
        tar_file = self._get_tarball('bz2')
 
727
        if tar_file is None:
 
728
            return None
 
729
        destination = to_bzrdir.create_repository()
690
730
        try:
691
731
            tar = tarfile.open('repository', fileobj=tar_file,
692
732
                mode='r|bz2')
700
740
                osutils.rmtree(tmpdir)
701
741
        finally:
702
742
            tar_file.close()
703
 
        # TODO: if the server doesn't support this operation, maybe do it the
704
 
        # slow way using the _real_repository?
705
 
        #
 
743
        return destination
706
744
        # TODO: Suggestion from john: using external tar is much faster than
707
745
        # python's tarfile library, but it may not work on windows.
708
746
 
750
788
        self._ensure_real()
751
789
        return self._real_repository.has_signature_for_revision_id(revision_id)
752
790
 
 
791
    def get_data_stream(self, revision_ids):
 
792
        path = self.bzrdir._path_for_remote_call(self._client)
 
793
        response, protocol = self._client.call_expecting_body(
 
794
            'Repository.stream_knit_data_for_revisions', path, *revision_ids)
 
795
        if response == ('ok',):
 
796
            return self._deserialise_stream(protocol)
 
797
        elif (response == ('error', "Generic bzr smart protocol error: "
 
798
                "bad request 'Repository.stream_knit_data_for_revisions'") or
 
799
              response == ('error', "Generic bzr smart protocol error: "
 
800
                "bad request u'Repository.stream_knit_data_for_revisions'")):
 
801
            protocol.cancel_read_body()
 
802
            self._ensure_real()
 
803
            return self._real_repository.get_data_stream(revision_ids)
 
804
        else:
 
805
            raise errors.UnexpectedSmartServerResponse(response)
 
806
 
 
807
    def _deserialise_stream(self, protocol):
 
808
        buffer = StringIO(protocol.read_body_bytes())
 
809
        reader = ContainerReader(buffer)
 
810
        for record_names, read_bytes in reader.iter_records():
 
811
            try:
 
812
                # These records should have only one name, and that name
 
813
                # should be a one-element tuple.
 
814
                [name_tuple] = record_names
 
815
            except ValueError:
 
816
                raise errors.SmartProtocolError(
 
817
                    'Repository data stream had invalid record name %r'
 
818
                    % (record_names,))
 
819
            yield name_tuple, read_bytes(None)
 
820
 
 
821
    def insert_data_stream(self, stream):
 
822
        self._ensure_real()
 
823
        self._real_repository.insert_data_stream(stream)
 
824
 
 
825
    def item_keys_introduced_by(self, revision_ids, _files_pb=None):
 
826
        self._ensure_real()
 
827
        return self._real_repository.item_keys_introduced_by(revision_ids,
 
828
            _files_pb=_files_pb)
 
829
 
 
830
    def revision_graph_can_have_wrong_parents(self):
 
831
        # The answer depends on the remote repo format.
 
832
        self._ensure_real()
 
833
        return self._real_repository.revision_graph_can_have_wrong_parents()
 
834
 
 
835
    def _find_inconsistent_revision_parents(self):
 
836
        self._ensure_real()
 
837
        return self._real_repository._find_inconsistent_revision_parents()
 
838
 
 
839
    def _check_for_inconsistent_revision_parents(self):
 
840
        self._ensure_real()
 
841
        return self._real_repository._check_for_inconsistent_revision_parents()
 
842
 
753
843
 
754
844
class RemoteBranchLockableFiles(LockableFiles):
755
845
    """A 'LockableFiles' implementation that talks to a smart server.
935
1025
            raise errors.UnlockableTransport(self.bzrdir.root_transport)
936
1026
        elif response[0] == 'ReadOnlyError':
937
1027
            raise errors.ReadOnlyError(self)
 
1028
        elif response[0] == 'LockFailed':
 
1029
            raise errors.LockFailed(response[1], response[2])
938
1030
        else:
939
1031
            raise errors.UnexpectedSmartServerResponse(response)
940
1032