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 (
85
85
self._real_bzrdir.create_repository(shared=shared)
86
86
return self.open_repository()
88
def destroy_repository(self):
89
"""See BzrDir.destroy_repository"""
91
self._real_bzrdir.destroy_repository()
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()
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)
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())
313
def find_text_key_references(self):
314
"""Find the text key references within the repository.
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.
325
return self._real_repository.find_text_key_references()
327
def _generate_text_key_index(self):
328
"""Generate a new text key index for the repository.
330
This is an expensive function that will take considerable time to run.
332
:return: A dict mapping (file_id, revision_id) tuples to a list of
333
parents, also (file_id, revision_id) tuples.
336
return self._real_repository._generate_text_key_index()
308
338
def get_revision_graph(self, revision_id=None):
309
339
"""See Repository.get_revision_graph()."""
310
340
if revision_id is None:
312
elif revision_id == NULL_REVISION:
342
elif revision.is_null(revision_id):
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):
363
394
fmt_revid = revid
387
418
def get_physical_lock_status(self):
388
419
"""See Repository.get_physical_lock_status()."""
420
# should be an API call to the server.
422
return self._real_repository.get_physical_lock_status()
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
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)
454
490
self._lock_count += 1
455
return self._lock_token
491
return self._lock_token or None
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
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
463
503
def _set_real_repository(self, repository):
489
529
def _unlock(self, token):
490
530
path = self.bzrdir._path_for_remote_call(self._client)
532
# with no token the remote repository is not persistently locked.
491
534
response = self._client.call('Repository.unlock', path, token)
492
535
if response == ('ok',):
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' \
522
562
old_token = self._lock_token
523
563
self._lock_token = None
524
564
if not self._leave_lock:
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()
599
dest_repo = self._real_repository._format.initialize(to_bzrdir,
559
601
dest_repo.fetch(self, revision_id=revision_id)
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
585
625
@needs_write_lock
626
666
# check that last_revision is in 'from' and then return a
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)
632
672
self._ensure_real()
656
696
self._ensure_real()
657
697
return self._real_repository.fileids_altered_by_revision_ids(revision_ids)
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)
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)
838
def add_signature_text(self, revision_id, signature):
840
return self._real_repository.add_signature_text(revision_id, signature)
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()
898
def _make_parents_provider(self):
900
return self._real_repository._make_parents_provider()
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,
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
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,
1086
1135
if response == ('ok',):
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()
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
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
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)
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)
1232
1287
self._ensure_real()
1233
1288
return self._real_branch.set_push_location(location)
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)
1241
1296
class RemoteBranchConfig(BranchConfig):