/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/bzrdir.py

  • Committer: Martin Pool
  • Date: 2010-02-18 04:17:22 UTC
  • mto: This revision was merged to the branch mainline in revision 5051.
  • Revision ID: mbp@sourcefrog.net-20100218041722-qmx7bz11qkeeh0nn
Link to commonly-duped bugs

Show diffs side-by-side

added added

removed removed

Lines of Context:
86
86
    registry,
87
87
    symbol_versioning,
88
88
    )
89
 
    
90
 
    
91
 
class ControlComponent(object):
92
 
    """Abstract base class for control directory components.
93
 
    
94
 
    This provides interfaces that are common across bzrdirs, 
95
 
    repositories, branches, and workingtree control directories.
96
 
    
97
 
    They all expose two urls and transports: the *user* URL is the 
98
 
    one that stops above the control directory (eg .bzr) and that 
99
 
    should normally be used in messages, and the *control* URL is
100
 
    under that in eg .bzr/checkout and is used to read the control
101
 
    files.
102
 
    
103
 
    This can be used as a mixin and is intended to fit with 
104
 
    foreign formats.
105
 
    """
106
 
    
107
 
    @property
108
 
    def control_transport(self):
109
 
        raise NotImplementedError
110
 
   
111
 
    @property
112
 
    def control_url(self):
113
 
        return self.control_transport.base
114
 
    
115
 
    @property
116
 
    def user_transport(self):
117
 
        raise NotImplementedError
118
 
        
119
 
    @property
120
 
    def user_url(self):
121
 
        return self.user_transport.base
122
 
    
123
 
 
124
 
class BzrDir(ControlComponent):
 
89
 
 
90
 
 
91
class BzrDir(object):
125
92
    """A .bzr control diretory.
126
93
 
127
94
    BzrDir instances let you create or open any of the things that can be
294
261
                # copied, and finally if we are copying up to a specific
295
262
                # revision_id then we can use the pending-ancestry-result which
296
263
                # does not require traversing all of history to describe it.
297
 
                if (result_repo.user_url == result.user_url
298
 
                    and not require_stacking and
 
264
                if (result_repo.bzrdir.root_transport.base ==
 
265
                    result.root_transport.base and not require_stacking and
299
266
                    revision_id is not None):
300
267
                    fetch_spec = graph.PendingAncestryResult(
301
268
                        [revision_id], local_repo)
429
396
        """Destroy the repository in this BzrDir"""
430
397
        raise NotImplementedError(self.destroy_repository)
431
398
 
432
 
    def create_branch(self, name=None):
 
399
    def create_branch(self):
433
400
        """Create a branch in this BzrDir.
434
401
 
435
 
        :param name: Name of the colocated branch to create, None for
436
 
            the default branch.
437
 
 
438
402
        The bzrdir's format will control what branch format is created.
439
403
        For more control see BranchFormatXX.create(a_bzrdir).
440
404
        """
441
405
        raise NotImplementedError(self.create_branch)
442
406
 
443
 
    def destroy_branch(self, name=None):
444
 
        """Destroy a branch in this BzrDir.
445
 
        
446
 
        :param name: Name of the branch to destroy, None for the default 
447
 
            branch.
448
 
        """
 
407
    def destroy_branch(self):
 
408
        """Destroy the branch in this BzrDir"""
449
409
        raise NotImplementedError(self.destroy_branch)
450
410
 
451
411
    @staticmethod
491
451
            stop = False
492
452
            stack_on = config.get_default_stack_on()
493
453
            if stack_on is not None:
494
 
                stack_on_pwd = found_bzrdir.user_url
 
454
                stack_on_pwd = found_bzrdir.root_transport.base
495
455
                stop = True
496
456
            # does it have a repository ?
497
457
            try:
499
459
            except errors.NoRepositoryPresent:
500
460
                repository = None
501
461
            else:
502
 
                if (found_bzrdir.user_url != self.user_url 
503
 
                    and not repository.is_shared()):
 
462
                if ((found_bzrdir.root_transport.base !=
 
463
                     self.root_transport.base) and not repository.is_shared()):
504
464
                    # Don't look higher, can't use a higher shared repo.
505
465
                    repository = None
506
466
                    stop = True
620
580
 
621
581
        :return: Tuple with old path name and new path name
622
582
        """
623
 
        def name_gen(base='backup.bzr'):
624
 
            counter = 1
625
 
            name = "%s.~%d~" % (base, counter)
626
 
            while self.root_transport.has(name):
627
 
                counter += 1
628
 
                name = "%s.~%d~" % (base, counter)
629
 
            return name
630
 
 
631
 
        backup_dir=name_gen()
632
583
        pb = ui.ui_factory.nested_progress_bar()
633
584
        try:
634
585
            # FIXME: bug 300001 -- the backup fails if the backup directory
635
586
            # already exists, but it should instead either remove it or make
636
587
            # a new backup directory.
637
588
            #
 
589
            # FIXME: bug 262450 -- the backup directory should have the same
 
590
            # permissions as the .bzr directory (probably a bug in copy_tree)
638
591
            old_path = self.root_transport.abspath('.bzr')
639
 
            new_path = self.root_transport.abspath(backup_dir)
 
592
            new_path = self.root_transport.abspath('backup.bzr')
640
593
            ui.ui_factory.note('making backup of %s\n  to %s' % (old_path, new_path,))
641
 
            self.root_transport.copy_tree('.bzr', backup_dir)
 
594
            self.root_transport.copy_tree('.bzr', 'backup.bzr')
642
595
            return (old_path, new_path)
643
596
        finally:
644
597
            pb.finished()
702
655
            if stop:
703
656
                return result
704
657
            next_transport = found_bzrdir.root_transport.clone('..')
705
 
            if (found_bzrdir.user_url == next_transport.base):
 
658
            if (found_bzrdir.root_transport.base == next_transport.base):
706
659
                # top of the file system
707
660
                return None
708
661
            # find the next containing bzrdir
725
678
                repository = found_bzrdir.open_repository()
726
679
            except errors.NoRepositoryPresent:
727
680
                return None, False
728
 
            if found_bzrdir.user_url == self.user_url:
 
681
            if found_bzrdir.root_transport.base == self.root_transport.base:
729
682
                return repository, True
730
683
            elif repository.is_shared():
731
684
                return repository, True
737
690
            raise errors.NoRepositoryPresent(self)
738
691
        return found_repo
739
692
 
740
 
    def get_branch_reference(self, name=None):
 
693
    def get_branch_reference(self):
741
694
        """Return the referenced URL for the branch in this bzrdir.
742
695
 
743
 
        :param name: Optional colocated branch name
744
696
        :raises NotBranchError: If there is no Branch.
745
 
        :raises NoColocatedBranchSupport: If a branch name was specified
746
 
            but colocated branches are not supported.
747
697
        :return: The URL the branch in this bzrdir references if it is a
748
698
            reference branch, or None for regular branches.
749
699
        """
750
 
        if name is not None:
751
 
            raise errors.NoColocatedBranchSupport(self)
752
700
        return None
753
701
 
754
 
    def get_branch_transport(self, branch_format, name=None):
 
702
    def get_branch_transport(self, branch_format):
755
703
        """Get the transport for use by branch format in this BzrDir.
756
704
 
757
705
        Note that bzr dirs that do not support format strings will raise
852
800
        :param _transport: the transport this dir is based at.
853
801
        """
854
802
        self._format = _format
855
 
        # these are also under the more standard names of 
856
 
        # control_transport and user_transport
857
803
        self.transport = _transport.clone('.bzr')
858
804
        self.root_transport = _transport
859
805
        self._mode_check_done = False
860
 
        
861
 
    @property 
862
 
    def user_transport(self):
863
 
        return self.root_transport
864
 
        
865
 
    @property
866
 
    def control_transport(self):
867
 
        return self.transport
868
806
 
869
807
    def is_control_filename(self, filename):
870
808
        """True if filename is the name of a path which is reserved for bzrdir's.
945
883
        BzrDir._check_supported(format, _unsupported)
946
884
        return format.open(transport, _found=True)
947
885
 
948
 
    def open_branch(self, name=None, unsupported=False,
949
 
                    ignore_fallbacks=False):
 
886
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
950
887
        """Open the branch object at this BzrDir if one is present.
951
888
 
952
889
        If unsupported is True, then no longer supported branch formats can
999
936
                raise errors.NotBranchError(path=url)
1000
937
            a_transport = new_t
1001
938
 
1002
 
    def _get_tree_branch(self, name=None):
 
939
    def _get_tree_branch(self):
1003
940
        """Return the branch and tree, if any, for this bzrdir.
1004
941
 
1005
 
        :param name: Name of colocated branch to open.
1006
 
 
1007
942
        Return None for tree if not present or inaccessible.
1008
943
        Raise NotBranchError if no branch is present.
1009
944
        :return: (tree, branch)
1012
947
            tree = self.open_workingtree()
1013
948
        except (errors.NoWorkingTree, errors.NotLocalUrl):
1014
949
            tree = None
1015
 
            branch = self.open_branch(name=name)
 
950
            branch = self.open_branch()
1016
951
        else:
1017
 
            if name is not None:
1018
 
                branch = self.open_branch(name=name)
1019
 
            else:
1020
 
                branch = tree.branch
 
952
            branch = tree.branch
1021
953
        return tree, branch
1022
954
 
1023
955
    @classmethod
1095
1027
        """
1096
1028
        raise NotImplementedError(self.open_workingtree)
1097
1029
 
1098
 
    def has_branch(self, name=None):
 
1030
    def has_branch(self):
1099
1031
        """Tell if this bzrdir contains a branch.
1100
1032
 
1101
1033
        Note: if you're going to open the branch, you should just go ahead
1103
1035
        branch and discards it, and that's somewhat expensive.)
1104
1036
        """
1105
1037
        try:
1106
 
            self.open_branch(name)
 
1038
            self.open_branch()
1107
1039
            return True
1108
1040
        except errors.NotBranchError:
1109
1041
            return False
1383
1315
        self.create_hook(hooks.HookPoint('pre_open',
1384
1316
            "Invoked before attempting to open a BzrDir with the transport "
1385
1317
            "that the open will use.", (1, 14), None))
1386
 
        self.create_hook(hooks.HookPoint('post_repo_init',
1387
 
            "Invoked after a repository has been initialized. "
1388
 
            "post_repo_init is called with a "
1389
 
            "bzrlib.bzrdir.RepoInitHookParams.",
1390
 
            (2, 2), None))
1391
1318
 
1392
1319
# install the default hooks
1393
1320
BzrDir.hooks = BzrDirHooks()
1394
1321
 
1395
1322
 
1396
 
class RepoInitHookParams(object):
1397
 
    """Object holding parameters passed to *_repo_init hooks.
1398
 
 
1399
 
    There are 4 fields that hooks may wish to access:
1400
 
 
1401
 
    :ivar repository: Repository created
1402
 
    :ivar format: Repository format
1403
 
    :ivar bzrdir: The bzrdir for the repository
1404
 
    :ivar shared: The repository is shared
1405
 
    """
1406
 
 
1407
 
    def __init__(self, repository, format, a_bzrdir, shared):
1408
 
        """Create a group of RepoInitHook parameters.
1409
 
 
1410
 
        :param repository: Repository created
1411
 
        :param format: Repository format
1412
 
        :param bzrdir: The bzrdir for the repository
1413
 
        :param shared: The repository is shared
1414
 
        """
1415
 
        self.repository = repository
1416
 
        self.format = format
1417
 
        self.bzrdir = a_bzrdir
1418
 
        self.shared = shared
1419
 
 
1420
 
    def __eq__(self, other):
1421
 
        return self.__dict__ == other.__dict__
1422
 
 
1423
 
    def __repr__(self):
1424
 
        if self.repository:
1425
 
            return "<%s for %s>" % (self.__class__.__name__,
1426
 
                self.repository)
1427
 
        else:
1428
 
            return "<%s for %s>" % (self.__class__.__name__,
1429
 
                self.bzrdir)
1430
 
 
1431
 
 
1432
1323
class BzrDirPreSplitOut(BzrDir):
1433
1324
    """A common class for the all-in-one formats."""
1434
1325
 
1473
1364
            tree.clone(result)
1474
1365
        return result
1475
1366
 
1476
 
    def create_branch(self, name=None):
 
1367
    def create_branch(self):
1477
1368
        """See BzrDir.create_branch."""
1478
 
        return self._format.get_branch_format().initialize(self, name=name)
 
1369
        return self._format.get_branch_format().initialize(self)
1479
1370
 
1480
 
    def destroy_branch(self, name=None):
 
1371
    def destroy_branch(self):
1481
1372
        """See BzrDir.destroy_branch."""
1482
1373
        raise errors.UnsupportedOperation(self.destroy_branch, self)
1483
1374
 
1539
1430
        raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1540
1431
                                          self)
1541
1432
 
1542
 
    def get_branch_transport(self, branch_format, name=None):
 
1433
    def get_branch_transport(self, branch_format):
1543
1434
        """See BzrDir.get_branch_transport()."""
1544
 
        if name is not None:
1545
 
            raise errors.NoColocatedBranchSupport(self)
1546
1435
        if branch_format is None:
1547
1436
            return self.transport
1548
1437
        try:
1581
1470
            format = BzrDirFormat.get_default_format()
1582
1471
        return not isinstance(self._format, format.__class__)
1583
1472
 
1584
 
    def open_branch(self, name=None, unsupported=False,
1585
 
                    ignore_fallbacks=False):
 
1473
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
1586
1474
        """See BzrDir.open_branch."""
1587
1475
        from bzrlib.branch import BzrBranchFormat4
1588
1476
        format = BzrBranchFormat4()
1589
1477
        self._check_supported(format, unsupported)
1590
 
        return format.open(self, name, _found=True)
 
1478
        return format.open(self, _found=True)
1591
1479
 
1592
1480
    def sprout(self, url, revision_id=None, force_new_repo=False,
1593
1481
               possible_transports=None, accelerator_tree=None,
1710
1598
        """See BzrDir.can_convert_format()."""
1711
1599
        return True
1712
1600
 
1713
 
    def create_branch(self, name=None):
 
1601
    def create_branch(self):
1714
1602
        """See BzrDir.create_branch."""
1715
 
        return self._format.get_branch_format().initialize(self, name=name)
 
1603
        return self._format.get_branch_format().initialize(self)
1716
1604
 
1717
 
    def destroy_branch(self, name=None):
 
1605
    def destroy_branch(self):
1718
1606
        """See BzrDir.create_branch."""
1719
 
        if name is not None:
1720
 
            raise errors.NoColocatedBranchSupport(self)
1721
1607
        self.transport.delete_tree('branch')
1722
1608
 
1723
1609
    def create_repository(self, shared=False):
1746
1632
    def destroy_workingtree_metadata(self):
1747
1633
        self.transport.delete_tree('checkout')
1748
1634
 
1749
 
    def find_branch_format(self, name=None):
 
1635
    def find_branch_format(self):
1750
1636
        """Find the branch 'format' for this bzrdir.
1751
1637
 
1752
1638
        This might be a synthetic object for e.g. RemoteBranch and SVN.
1753
1639
        """
1754
1640
        from bzrlib.branch import BranchFormat
1755
 
        return BranchFormat.find_format(self, name=name)
 
1641
        return BranchFormat.find_format(self)
1756
1642
 
1757
1643
    def _get_mkdir_mode(self):
1758
1644
        """Figure out the mode to use when creating a bzrdir subdir."""
1760
1646
                                     lockable_files.TransportLock)
1761
1647
        return temp_control._dir_mode
1762
1648
 
1763
 
    def get_branch_reference(self, name=None):
 
1649
    def get_branch_reference(self):
1764
1650
        """See BzrDir.get_branch_reference()."""
1765
1651
        from bzrlib.branch import BranchFormat
1766
 
        format = BranchFormat.find_format(self, name=name)
1767
 
        return format.get_reference(self, name=name)
 
1652
        format = BranchFormat.find_format(self)
 
1653
        return format.get_reference(self)
1768
1654
 
1769
 
    def get_branch_transport(self, branch_format, name=None):
 
1655
    def get_branch_transport(self, branch_format):
1770
1656
        """See BzrDir.get_branch_transport()."""
1771
 
        if name is not None:
1772
 
            raise errors.NoColocatedBranchSupport(self)
1773
1657
        # XXX: this shouldn't implicitly create the directory if it's just
1774
1658
        # promising to get a transport -- mbp 20090727
1775
1659
        if branch_format is None:
1846
1730
                return True
1847
1731
        except errors.NoRepositoryPresent:
1848
1732
            pass
1849
 
        for branch in self.list_branches():
1850
 
            if not isinstance(branch._format,
 
1733
        try:
 
1734
            if not isinstance(self.open_branch()._format,
1851
1735
                              format.get_branch_format().__class__):
1852
1736
                # the branch needs an upgrade.
1853
1737
                return True
 
1738
        except errors.NotBranchError:
 
1739
            pass
1854
1740
        try:
1855
1741
            my_wt = self.open_workingtree(recommend_upgrade=False)
1856
1742
            if not isinstance(my_wt._format,
1861
1747
            pass
1862
1748
        return False
1863
1749
 
1864
 
    def open_branch(self, name=None, unsupported=False,
1865
 
                    ignore_fallbacks=False):
 
1750
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
1866
1751
        """See BzrDir.open_branch."""
1867
 
        format = self.find_branch_format(name=name)
 
1752
        format = self.find_branch_format()
1868
1753
        self._check_supported(format, unsupported)
1869
 
        return format.open(self, name=name,
1870
 
            _found=True, ignore_fallbacks=ignore_fallbacks)
 
1754
        return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)
1871
1755
 
1872
1756
    def open_repository(self, unsupported=False):
1873
1757
        """See BzrDir.open_repository."""
1905
1789
    Once a format is deprecated, just deprecate the initialize and open
1906
1790
    methods on the format class. Do not deprecate the object, as the
1907
1791
    object will be created every system load.
1908
 
 
1909
 
    :cvar colocated_branches: Whether this formats supports colocated branches.
1910
1792
    """
1911
1793
 
1912
1794
    _default_format = None
1929
1811
 
1930
1812
    _lock_file_name = 'branch-lock'
1931
1813
 
1932
 
    colocated_branches = False
1933
 
    """Whether co-located branches are supported for this control dir format.
1934
 
    """
1935
 
 
1936
1814
    # _lock_class must be set in subclasses to the lock type, typ.
1937
1815
    # TransportLock or LockDir
1938
1816
 
2745
2623
            if isinstance(self.bzrdir.transport, local.LocalTransport):
2746
2624
                self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2747
2625
            self._convert_to_weaves()
2748
 
            return BzrDir.open(self.bzrdir.user_url)
 
2626
            return BzrDir.open(self.bzrdir.root_transport.base)
2749
2627
        finally:
2750
2628
            self.pb.finished()
2751
2629
 
2998
2876
        try:
2999
2877
            ui.ui_factory.note('starting upgrade from format 5 to 6')
3000
2878
            self._convert_to_prefixed()
3001
 
            return BzrDir.open(self.bzrdir.user_url)
 
2879
            return BzrDir.open(self.bzrdir.root_transport.base)
3002
2880
        finally:
3003
2881
            pb.finished()
3004
2882
 
3126
3004
            BzrDirMetaFormat1().get_format_string(),
3127
3005
            mode=self.file_mode)
3128
3006
        self.pb.finished()
3129
 
        return BzrDir.open(self.bzrdir.user_url)
 
3007
        return BzrDir.open(self.bzrdir.root_transport.base)
3130
3008
 
3131
3009
    def make_lock(self, name):
3132
3010
        """Make a lock for the new control dir name."""
3713
3591
            try:
3714
3592
                stack_on = urlutils.rebase_url(self._stack_on,
3715
3593
                    self._stack_on_pwd,
3716
 
                    branch.user_url)
 
3594
                    branch.bzrdir.root_transport.base)
3717
3595
            except errors.InvalidRebaseURLs:
3718
3596
                stack_on = self._get_full_stack_on()
3719
3597
        try: