~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

  • Committer: Lukáš Lalinský
  • Date: 2007-12-17 17:28:25 UTC
  • mfrom: (3120 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3123.
  • Revision ID: lalinsky@gmail.com-20071217172825-tr3pqm1mhvs3gwnn
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
    errors,
25
25
    lockdir,
26
26
    repository,
 
27
    revision,
27
28
)
28
29
from bzrlib.branch import Branch, BranchReferenceFormat
29
30
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
32
33
from bzrlib.errors import NoSuchRevision
33
34
from bzrlib.lockable_files import LockableFiles
34
35
from bzrlib.pack import ContainerReader
35
 
from bzrlib.revision import NULL_REVISION
36
36
from bzrlib.smart import client, vfs
37
37
from bzrlib.symbol_versioning import (
38
38
    deprecated_method,
85
85
        self._real_bzrdir.create_repository(shared=shared)
86
86
        return self.open_repository()
87
87
 
 
88
    def destroy_repository(self):
 
89
        """See BzrDir.destroy_repository"""
 
90
        self._ensure_real()
 
91
        self._real_bzrdir.destroy_repository()
 
92
 
88
93
    def create_branch(self):
89
94
        self._ensure_real()
90
95
        real_branch = self._real_bzrdir.create_branch()
95
100
        self._ensure_real()
96
101
        self._real_bzrdir.destroy_branch()
97
102
 
98
 
    def create_workingtree(self, revision_id=None):
 
103
    def create_workingtree(self, revision_id=None, from_branch=None):
99
104
        raise errors.NotLocalUrl(self.transport.base)
100
105
 
101
106
    def find_branch_format(self):
305
310
            #self._real_repository = self.bzrdir._real_bzrdir.open_repository()
306
311
            self._set_real_repository(self.bzrdir._real_bzrdir.open_repository())
307
312
 
 
313
    def find_text_key_references(self):
 
314
        """Find the text key references within the repository.
 
315
 
 
316
        :return: a dictionary mapping (file_id, revision_id) tuples to altered file-ids to an iterable of
 
317
        revision_ids. Each altered file-ids has the exact revision_ids that
 
318
        altered it listed explicitly.
 
319
        :return: A dictionary mapping text keys ((fileid, revision_id) tuples)
 
320
            to whether they were referred to by the inventory of the
 
321
            revision_id that they contain. The inventory texts from all present
 
322
            revision ids are assessed to generate this report.
 
323
        """
 
324
        self._ensure_real()
 
325
        return self._real_repository.find_text_key_references()
 
326
 
 
327
    def _generate_text_key_index(self):
 
328
        """Generate a new text key index for the repository.
 
329
 
 
330
        This is an expensive function that will take considerable time to run.
 
331
 
 
332
        :return: A dict mapping (file_id, revision_id) tuples to a list of
 
333
            parents, also (file_id, revision_id) tuples.
 
334
        """
 
335
        self._ensure_real()
 
336
        return self._real_repository._generate_text_key_index()
 
337
 
308
338
    def get_revision_graph(self, revision_id=None):
309
339
        """See Repository.get_revision_graph()."""
310
340
        if revision_id is None:
311
341
            revision_id = ''
312
 
        elif revision_id == NULL_REVISION:
 
342
        elif revision.is_null(revision_id):
313
343
            return {}
314
344
 
315
345
        path = self.bzrdir._path_for_remote_call(self._client)
357
387
    def gather_stats(self, revid=None, committers=None):
358
388
        """See Repository.gather_stats()."""
359
389
        path = self.bzrdir._path_for_remote_call(self._client)
360
 
        if revid in (None, NULL_REVISION):
 
390
        # revid can be None to indicate no revisions, not just NULL_REVISION
 
391
        if revid is None or revision.is_null(revid):
361
392
            fmt_revid = ''
362
393
        else:
363
394
            fmt_revid = revid
386
417
 
387
418
    def get_physical_lock_status(self):
388
419
        """See Repository.get_physical_lock_status()."""
389
 
        return False
 
420
        # should be an API call to the server.
 
421
        self._ensure_real()
 
422
        return self._real_repository.get_physical_lock_status()
390
423
 
391
424
    def is_in_write_group(self):
392
425
        """Return True if there is an open write group.
439
472
    def lock_write(self, token=None):
440
473
        if not self._lock_mode:
441
474
            self._lock_token = self._remote_lock_write(token)
442
 
            assert self._lock_token, 'Remote server did not return a token!'
 
475
            # if self._lock_token is None, then this is something like packs or
 
476
            # svn where we don't get to lock the repo, or a weave style repository
 
477
            # where we cannot lock it over the wire and attempts to do so will
 
478
            # fail.
443
479
            if self._real_repository is not None:
444
480
                self._real_repository.lock_write(token=self._lock_token)
445
481
            if token is not None:
452
488
            raise errors.ReadOnlyError(self)
453
489
        else:
454
490
            self._lock_count += 1
455
 
        return self._lock_token
 
491
        return self._lock_token or None
456
492
 
457
493
    def leave_lock_in_place(self):
 
494
        if not self._lock_token:
 
495
            raise NotImplementedError(self.leave_lock_in_place)
458
496
        self._leave_lock = True
459
497
 
460
498
    def dont_leave_lock_in_place(self):
 
499
        if not self._lock_token:
 
500
            raise NotImplementedError(self.dont_leave_lock_in_place)
461
501
        self._leave_lock = False
462
502
 
463
503
    def _set_real_repository(self, repository):
488
528
 
489
529
    def _unlock(self, token):
490
530
        path = self.bzrdir._path_for_remote_call(self._client)
 
531
        if not token:
 
532
            # with no token the remote repository is not persistently locked.
 
533
            return
491
534
        response = self._client.call('Repository.unlock', path, token)
492
535
        if response == ('ok',):
493
536
            return
516
559
            if old_mode == 'w':
517
560
                # Only write-locked repositories need to make a remote method
518
561
                # call to perfom the unlock.
519
 
                assert self._lock_token, \
520
 
                    '%s is locked, but has no token' \
521
 
                    % self
522
562
                old_token = self._lock_token
523
563
                self._lock_token = None
524
564
                if not self._leave_lock:
555
595
 
556
596
    def sprout(self, to_bzrdir, revision_id=None):
557
597
        # TODO: Option to control what format is created?
558
 
        dest_repo = to_bzrdir.create_repository()
 
598
        self._ensure_real()
 
599
        dest_repo = self._real_repository._format.initialize(to_bzrdir,
 
600
                                                             shared=False)
559
601
        dest_repo.fetch(self, revision_id=revision_id)
560
602
        return dest_repo
561
603
 
578
620
        builder = self._real_repository.get_commit_builder(branch, parents,
579
621
                config, timestamp=timestamp, timezone=timezone,
580
622
                committer=committer, revprops=revprops, revision_id=revision_id)
581
 
        # Make the builder use this RemoteRepository rather than the real one.
582
 
        builder.repository = self
583
623
        return builder
584
624
 
585
625
    @needs_write_lock
626
666
            # check that last_revision is in 'from' and then return a
627
667
            # no-operation.
628
668
            if (revision_id is not None and
629
 
                not _mod_revision.is_null(revision_id)):
 
669
                not revision.is_null(revision_id)):
630
670
                self.get_revision(revision_id)
631
671
            return 0, []
632
672
        self._ensure_real()
656
696
        self._ensure_real()
657
697
        return self._real_repository.fileids_altered_by_revision_ids(revision_ids)
658
698
 
659
 
    def get_versioned_file_checker(self, revisions, revision_versions_cache):
 
699
    def _get_versioned_file_checker(self, revisions, revision_versions_cache):
660
700
        self._ensure_real()
661
 
        return self._real_repository.get_versioned_file_checker(
 
701
        return self._real_repository._get_versioned_file_checker(
662
702
            revisions, revision_versions_cache)
663
703
        
664
704
    def iter_files_bytes(self, desired_files):
795
835
        return self._real_repository.store_revision_signature(
796
836
            gpg_strategy, plaintext, revision_id)
797
837
 
 
838
    def add_signature_text(self, revision_id, signature):
 
839
        self._ensure_real()
 
840
        return self._real_repository.add_signature_text(revision_id, signature)
 
841
 
798
842
    def has_signature_for_revision_id(self, revision_id):
799
843
        self._ensure_real()
800
844
        return self._real_repository.has_signature_for_revision_id(revision_id)
851
895
        self._ensure_real()
852
896
        return self._real_repository._check_for_inconsistent_revision_parents()
853
897
 
 
898
    def _make_parents_provider(self):
 
899
        self._ensure_real()
 
900
        return self._real_repository._make_parents_provider()
 
901
 
854
902
 
855
903
class RemoteBranchLockableFiles(LockableFiles):
856
904
    """A 'LockableFiles' implementation that talks to a smart server.
933
981
        # We intentionally don't call the parent class's __init__, because it
934
982
        # will try to assign to self.tags, which is a property in this subclass.
935
983
        # And the parent's __init__ doesn't do much anyway.
 
984
        self._revision_id_to_revno_cache = None
936
985
        self._revision_history_cache = None
937
986
        self.bzrdir = remote_bzrdir
938
987
        if _client is not None:
1024
1073
            self.repository.unlock()
1025
1074
        path = self.bzrdir._path_for_remote_call(self._client)
1026
1075
        response = self._client.call('Branch.lock_write', path, branch_token,
1027
 
                                     repo_token)
 
1076
                                     repo_token or '')
1028
1077
        if response[0] == 'ok':
1029
1078
            ok, branch_token, repo_token = response
1030
1079
            return branch_token, repo_token
1077
1126
                if token != self._lock_token:
1078
1127
                    raise errors.TokenMismatch(token, self._lock_token)
1079
1128
            self._lock_count += 1
1080
 
        return self._lock_token
 
1129
        return self._lock_token or None
1081
1130
 
1082
1131
    def _unlock(self, branch_token, repo_token):
1083
1132
        path = self.bzrdir._path_for_remote_call(self._client)
1084
1133
        response = self._client.call('Branch.unlock', path, branch_token,
1085
 
                                     repo_token)
 
1134
                                     repo_token or '')
1086
1135
        if response == ('ok',):
1087
1136
            return
1088
1137
        elif response[0] == 'TokenMismatch':
1098
1147
            mode = self._lock_mode
1099
1148
            self._lock_mode = None
1100
1149
            if self._real_branch is not None:
1101
 
                if not self._leave_lock:
 
1150
                if (not self._leave_lock and mode == 'w' and
 
1151
                    self._repo_lock_token):
1102
1152
                    # If this RemoteBranch will remove the physical lock for the
1103
1153
                    # repository, make sure the _real_branch doesn't do it
1104
1154
                    # first.  (Because the _real_branch's repository is set to
1122
1172
        return self._real_branch.break_lock()
1123
1173
 
1124
1174
    def leave_lock_in_place(self):
 
1175
        if not self._lock_token:
 
1176
            raise NotImplementedError(self.leave_lock_in_place)
1125
1177
        self._leave_lock = True
1126
1178
 
1127
1179
    def dont_leave_lock_in_place(self):
 
1180
        if not self._lock_token:
 
1181
            raise NotImplementedError(self.dont_leave_lock_in_place)
1128
1182
        self._leave_lock = False
1129
1183
 
1130
1184
    def last_revision_info(self):
1184
1238
        # format, because RemoteBranches can't be created at arbitrary URLs.
1185
1239
        # XXX: if to_bzrdir is a RemoteBranch, this should perhaps do
1186
1240
        # to_bzrdir.create_branch...
1187
 
        result = branch.BranchFormat.get_default_format().initialize(to_bzrdir)
 
1241
        self._ensure_real()
 
1242
        result = self._real_branch._format.initialize(to_bzrdir)
1188
1243
        self.copy_content_into(result, revision_id=revision_id)
1189
1244
        result.set_parent(self.bzrdir.root_transport.base)
1190
1245
        return result
1232
1287
        self._ensure_real()
1233
1288
        return self._real_branch.set_push_location(location)
1234
1289
 
1235
 
    def update_revisions(self, other, stop_revision=None):
 
1290
    def update_revisions(self, other, stop_revision=None, overwrite=False):
1236
1291
        self._ensure_real()
1237
1292
        return self._real_branch.update_revisions(
1238
 
            other, stop_revision=stop_revision)
 
1293
            other, stop_revision=stop_revision, overwrite=overwrite)
1239
1294
 
1240
1295
 
1241
1296
class RemoteBranchConfig(BranchConfig):