48
47
from bzrlib.errors import (
51
49
IncompatibleFormat,
52
50
LocalRequiresBoundBranch,
53
NoColocatedBranchSupport,
54
TokenLockingNotSupported,
56
55
UnstackableBranchFormat,
58
57
from bzrlib.foreign import (
119
118
class SubversionWriteLock(object):
120
119
"""A (dummy) write lock on a Subversion object."""
122
__slots__ = ('unlock')
121
__slots__ = ('unlock', 'branch_token')
124
123
def __init__(self, unlock):
124
self.branch_token = None
125
125
self.unlock = unlock
127
127
def __repr__(self):
232
232
if type not in ('branch', 'tag') or ip != '':
233
233
raise NotBranchError(branch_path)
235
def leave_lock_in_place(self):
236
raise NotImplementedError(self.leave_lock_in_place)
238
def dont_leave_lock_in_place(self):
239
raise NotImplementedError(self.dont_leave_lock_in_place)
235
241
def _push_should_merge_tags(self):
236
242
return self.supports_tags()
263
269
assert revnum >= 0
265
271
last_revmeta, _ = self.last_revmeta()
272
if revnum > last_revmeta.metarev.revnum:
273
# Apparently a commit happened in the mean time
274
self._clear_cached_state()
275
last_revmeta, _ = self.last_revmeta()
266
276
if revnum == last_revmeta.metarev.revnum:
267
277
return last_revmeta.metarev.branch_path
279
locations = self.repository.transport.get_locations(
280
last_revmeta.metarev.branch_path, last_revmeta.metarev.revnum,
269
283
# Use revnum - this branch may have been moved in the past
270
return self.repository.transport.get_locations(
271
last_revmeta.metarev.branch_path, last_revmeta.metarev.revnum,
272
[revnum])[revnum].strip("/")
284
return locations[revnum].strip("/")
274
286
def get_revnum(self):
275
287
"""Obtain the Subversion revision number this branch was
414
426
def _set_last_revision(self, revid):
416
rev = self.repository.get_revision(revid)
417
except NoSuchRevision:
418
raise NotImplementedError("set_last_revision_info can't add ghosts")
420
base_revid = rev.parent_ids[0]
427
if revid == NULL_REVISION:
428
create_branch_with_hidden_commit(
430
self.get_branch_path(), NULL_REVISION,
431
set_metadata=True, deletefirst=True)
422
base_revid = NULL_REVISION
423
interrepo = InterToSvnRepository(self.repository, self.repository)
424
base_foreign_info = interrepo._get_foreign_revision_info(base_revid, self.get_branch_path())
425
interrepo.push_single_revision(self.get_branch_path(), self.get_config(), rev,
426
push_metadata=True, root_action=("replace", self.get_revnum()),
427
base_foreign_info=base_foreign_info)
434
rev = self.repository.get_revision(revid)
435
except NoSuchRevision:
436
raise NotImplementedError("set_last_revision_info can't add ghosts")
438
base_revid = rev.parent_ids[0]
440
base_revid = NULL_REVISION
441
interrepo = InterToSvnRepository(self.repository, self.repository)
442
base_foreign_info = interrepo._get_foreign_revision_info(base_revid,
443
self.get_branch_path())
444
interrepo.push_single_revision(self.get_branch_path(), self.get_config(), rev,
445
push_metadata=True, root_action=("replace", self.get_revnum()),
446
base_foreign_info=base_foreign_info)
428
447
self._clear_cached_state()
430
449
def last_revision_info(self):
460
479
def _iter_revision_meta_ancestry(self, pb=None):
461
return self.repository._iter_reverse_revmeta_mapping_ancestry(
480
return self.repository._revmeta_provider._iter_reverse_revmeta_mapping_ancestry(
462
481
self.get_branch_path(),
463
482
self._revnum or self.repository.get_latest_revnum(), self.mapping,
464
483
lhs_history=self._revision_meta_history(), pb=pb)
466
485
def _revision_meta_history(self):
467
486
if self._revmeta_cache is None:
468
487
self._revmeta_cache = util.lazy_readonly_list(
469
self.repository._iter_reverse_revmeta_mapping_history(
488
self.repository._revmeta_provider._iter_reverse_revmeta_mapping_history(
470
489
self.get_branch_path(),
471
490
self._revnum or self.repository.get_latest_revnum(),
472
491
to_revnum=0, mapping=self.mapping))
500
519
# Shortcut for finding the tip. This avoids expensive generation time
501
520
# on large branches.
502
521
last_revmeta, mapping = self.last_revmeta()
522
if last_revmeta is None:
503
524
return last_revmeta.get_revision_id(mapping)
505
526
def get_push_merged_revisions(self):
509
530
def import_last_revision_info(self, source_repo, revno, revid, lossy=False):
510
531
interrepo = InterToSvnRepository(source_repo, self.repository)
511
532
last_revmeta, mapping = self.last_revmeta()
512
revidmap = interrepo.push_todo(last_revmeta.get_revision_id(mapping),
533
if last_revmeta is None:
534
last_revid = NULL_REVISION
536
last_revid = last_revmeta.get_revision_id(mapping)
537
revidmap = interrepo.push_todo(last_revid,
513
538
last_revmeta.metarev.get_foreign_revid(), mapping, revid, self.layout,
514
539
self.project, self.get_branch_path(), self.get_config(),
515
540
push_merged=self.get_push_merged_revisions(),
557
582
def break_lock(self):
560
def lock_write(self):
585
def lock_write(self, token=None):
561
586
"""See Branch.lock_write()."""
562
587
# TODO: Obtain lock on the remote server?
588
if token is not None:
589
raise TokenLockingNotSupported(self)
563
590
if self._lock_mode:
564
591
assert self._lock_mode == 'w'
565
592
self._lock_count += 1
643
670
from bzrlib.plugins.svn.remote import SvnRemoteAccess
644
671
if not isinstance(to_bzrdir, SvnRemoteAccess):
645
672
raise IncompatibleFormat(self, to_bzrdir._format)
646
if repository is None:
647
repository = to_bzrdir.find_repository()
649
raise NoColocatedBranchSupport(to_bzrdir)
651
create_branch_with_hidden_commit(repository,
652
to_bzrdir._branch_path, NULL_REVISION, set_metadata=True,
654
except SubversionException, (_, num):
655
if num == ERR_FS_ALREADY_EXISTS:
656
raise AlreadyBranchError(to_bzrdir.user_url)
658
return to_bzrdir.open_branch()
673
return to_bzrdir.create_branch(name)
660
675
def supports_tags(self):
683
698
from bzrlib.branch import format_registry as branch_format_registry
684
699
return [(SvnBranchFormat(), branch_format_registry.get_default())]
686
def fetch(self, stop_revision=None, fetch_tags=True, find_ghosts=False, limit=None):
701
def fetch(self, stop_revision=None, fetch_tags=None, find_ghosts=False, limit=None):
687
702
"""See InterBranch.fetch."""
688
703
# we fetch here so that we don't process data twice in the
689
704
# common case of having something to pull, and so that the
700
715
# No need to fetch tags if there are already up to 'limit' revisions
701
716
# missing in mainline.
702
717
fetch_tags = False
718
if fetch_tags is None:
719
c = self.source.get_config()
720
fetch_tags = c.get_user_option_as_bool('branch.fetch_tags')
703
721
if fetch_tags and self.source.supports_tags():
704
722
tag_revmetas = self.source.tags._get_tag_dict_revmeta()
705
723
d = resolve_tags_svn_ancestry(self.source, tag_revmetas)
718
736
project=self.source.project, mapping=self.source.mapping)
720
738
def _update_revisions(self, stop_revision=None, overwrite=False,
721
graph=None, fetch_tags=True):
739
graph=None, fetch_tags=None):
722
740
"See InterBranch.update_revisions."""
723
741
self.source.lock_read()
906
924
# For compatibility with bzr < 2.4
907
925
return self.push(lossy=True, stop_revision=stop_revision)
927
def fetch(self, stop_revision=None, fetch_tags=None, find_ghosts=False,
929
"""Fetch into a subversion repository."""
930
# For the moment, this method is disabled. Merge uses it to fetch
931
# revisions before doing its work, but then fails later on.
932
# Having this method fail means the user won't end up with
933
# spurious revisions in their repository for an operation that's
934
# not going to work anyway.
935
raise NotImplementedError(self.fetch)
936
# FIXME: Handle limit
937
# FIXME: Handle fetch_tags
938
# FIXME: Handle find_ghosts
939
interrepo = InterToSvnRepository(
940
self.source.repository, self.target.repository)
941
interrepo.fetch(revision_id=stop_revision)
909
943
def update_tags(self, overwrite=False):
910
944
return self.source.tags.merge_to(self.target.tags, overwrite)
946
def _basic_push(self, overwrite=False, stop_revision=None):
947
# Wrapper for the benefit of GenericInterBranch, which
948
# calls it for bound branches
949
return self.push(overwrite=overwrite, stop_revision=stop_revision)
912
951
def push(self, overwrite=False, stop_revision=None,
913
952
lossy=False, _override_hook_source_branch=None):
914
953
"""See InterBranch.push()."""
954
if lossy and isinstance(self.source, SvnBranch):
955
raise LossyPushToSameVCS(self.source, self.target)
915
956
result = SubversionTargetBranchPushResult()
916
957
result.target_branch = self.target
917
958
result.master_branch = None