~ubuntu-branches/ubuntu/oneiric/bzr-svn/oneiric

« back to all changes in this revision

Viewing changes to branch.py

  • Committer: Bazaar Package Importer
  • Author(s): Jelmer Vernooij
  • Date: 2011-08-26 19:47:18 UTC
  • mfrom: (1.1.31 upstream) (3.3.8 sid)
  • Revision ID: james.westby@ubuntu.com-20110826194718-iefslmdqyftcjyxx
Tags: 1.1.0-1
* New upstream release.
 + Fixes problems with sparse revision caches. LP: #795700, LP: #664085
 + Fixes test run against bzr 2.4.0. LP: #828381

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
import os
21
21
from subvertpy import (
22
 
    ERR_FS_ALREADY_EXISTS,
23
22
    ERR_FS_NO_SUCH_REVISION,
24
23
    NODE_DIR,
25
24
    SubversionException,
46
45
    format_registry,
47
46
    )
48
47
from bzrlib.errors import (
49
 
    AlreadyBranchError,
50
48
    DivergedBranches,
51
49
    IncompatibleFormat,
52
50
    LocalRequiresBoundBranch,
53
 
    NoColocatedBranchSupport,
 
51
    LossyPushToSameVCS,
54
52
    NoSuchRevision,
55
53
    NotBranchError,
 
54
    TokenLockingNotSupported,
56
55
    UnstackableBranchFormat,
57
56
    )
58
57
from bzrlib.foreign import (
119
118
class SubversionWriteLock(object):
120
119
    """A (dummy) write lock on a Subversion object."""
121
120
 
122
 
    __slots__ = ('unlock')
 
121
    __slots__ = ('unlock', 'branch_token')
123
122
 
124
123
    def __init__(self, unlock):
 
124
        self.branch_token = None
125
125
        self.unlock = unlock
126
126
 
127
127
    def __repr__(self):
232
232
        if type not in ('branch', 'tag') or ip != '':
233
233
            raise NotBranchError(branch_path)
234
234
 
 
235
    def leave_lock_in_place(self):
 
236
        raise NotImplementedError(self.leave_lock_in_place)
 
237
 
 
238
    def dont_leave_lock_in_place(self):
 
239
        raise NotImplementedError(self.dont_leave_lock_in_place)
 
240
 
235
241
    def _push_should_merge_tags(self):
236
242
        return self.supports_tags()
237
243
 
263
269
        assert revnum >= 0
264
270
 
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
268
278
 
 
279
        locations = self.repository.transport.get_locations(
 
280
                last_revmeta.metarev.branch_path, last_revmeta.metarev.revnum,
 
281
                [revnum])
 
282
 
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("/")
273
285
 
274
286
    def get_revnum(self):
275
287
        """Obtain the Subversion revision number this branch was
293
305
            return revmeta, mapping
294
306
        return None, None
295
307
 
296
 
    def check(self):
 
308
    def check(self, refs=None):
297
309
        """See Branch.Check.
298
310
 
299
311
        Doesn't do anything for Subversion repositories at the moment (yet).
412
424
        # FIXME: 
413
425
 
414
426
    def _set_last_revision(self, revid):
415
 
        try:
416
 
            rev = self.repository.get_revision(revid)
417
 
        except NoSuchRevision:
418
 
            raise NotImplementedError("set_last_revision_info can't add ghosts")
419
 
        if rev.parent_ids:
420
 
            base_revid = rev.parent_ids[0]
 
427
        if revid == NULL_REVISION:
 
428
            create_branch_with_hidden_commit(
 
429
                self.repository,
 
430
                self.get_branch_path(), NULL_REVISION,
 
431
                set_metadata=True, deletefirst=True)
421
432
        else:
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)
 
433
            try:
 
434
                rev = self.repository.get_revision(revid)
 
435
            except NoSuchRevision:
 
436
                raise NotImplementedError("set_last_revision_info can't add ghosts")
 
437
            if rev.parent_ids:
 
438
                base_revid = rev.parent_ids[0]
 
439
            else:
 
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()
429
448
 
430
449
    def last_revision_info(self):
458
477
        return None
459
478
 
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:
 
523
            return NULL_REVISION
503
524
        return last_revmeta.get_revision_id(mapping)
504
525
 
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
 
535
        else:
 
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):
558
583
        pass
559
584
 
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()
648
 
        if name is not None:
649
 
            raise NoColocatedBranchSupport(to_bzrdir)
650
 
        try:
651
 
            create_branch_with_hidden_commit(repository,
652
 
                to_bzrdir._branch_path, NULL_REVISION, set_metadata=True,
653
 
                deletefirst=False)
654
 
        except SubversionException, (_, num):
655
 
            if num == ERR_FS_ALREADY_EXISTS:
656
 
                raise AlreadyBranchError(to_bzrdir.user_url)
657
 
            raise
658
 
        return to_bzrdir.open_branch()
 
673
        return to_bzrdir.create_branch(name)
659
674
 
660
675
    def supports_tags(self):
661
676
        return True
683
698
        from bzrlib.branch import format_registry as branch_format_registry
684
699
        return [(SvnBranchFormat(), branch_format_registry.get_default())]
685
700
 
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)
719
737
 
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()
724
742
        try:
906
924
        # For compatibility with bzr < 2.4
907
925
        return self.push(lossy=True, stop_revision=stop_revision)
908
926
 
 
927
    def fetch(self, stop_revision=None, fetch_tags=None, find_ghosts=False,
 
928
            limit=None):
 
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)
 
942
 
909
943
    def update_tags(self, overwrite=False):
910
944
        return self.source.tags.merge_to(self.target.tags, overwrite)
911
945
 
 
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)
 
950
 
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