~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Robert Collins
  • Date: 2010-04-08 04:34:03 UTC
  • mfrom: (5138 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5139.
  • Revision ID: robertc@robertcollins.net-20100408043403-56z0d07vdqrx7f3t
Update bugfix for 528114 to trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 
30
30
import os
31
31
import sys
 
32
import warnings
32
33
 
33
34
from bzrlib.lazy_import import lazy_import
34
35
lazy_import(globals(), """
354
355
                for subdir in sorted(subdirs, reverse=True):
355
356
                    pending.append(current_transport.clone(subdir))
356
357
 
 
358
    def list_branches(self):
 
359
        """Return a sequence of all branches local to this control directory.
 
360
 
 
361
        """
 
362
        try:
 
363
            return [self.open_branch()]
 
364
        except errors.NotBranchError:
 
365
            return []
 
366
 
357
367
    @staticmethod
358
368
    def find_branches(transport):
359
369
        """Find all branches under a transport.
371
381
            except errors.NoRepositoryPresent:
372
382
                pass
373
383
            else:
374
 
                return False, (None, repository)
375
 
            try:
376
 
                branch = bzrdir.open_branch()
377
 
            except errors.NotBranchError:
378
 
                return True, (None, None)
379
 
            else:
380
 
                return True, (branch, None)
381
 
        branches = []
382
 
        for branch, repo in BzrDir.find_bzrdirs(transport, evaluate=evaluate):
 
384
                return False, ([], repository)
 
385
            return True, (bzrdir.list_branches(), None)
 
386
        ret = []
 
387
        for branches, repo in BzrDir.find_bzrdirs(transport,
 
388
                                                  evaluate=evaluate):
383
389
            if repo is not None:
384
 
                branches.extend(repo.find_branches())
385
 
            if branch is not None:
386
 
                branches.append(branch)
387
 
        return branches
 
390
                ret.extend(repo.find_branches())
 
391
            if branches is not None:
 
392
                ret.extend(branches)
 
393
        return ret
388
394
 
389
395
    def destroy_repository(self):
390
396
        """Destroy the repository in this BzrDir"""
391
397
        raise NotImplementedError(self.destroy_repository)
392
398
 
393
 
    def create_branch(self):
 
399
    def create_branch(self, name=None):
394
400
        """Create a branch in this BzrDir.
395
401
 
 
402
        :param name: Name of the colocated branch to create, None for
 
403
            the default branch.
 
404
 
396
405
        The bzrdir's format will control what branch format is created.
397
406
        For more control see BranchFormatXX.create(a_bzrdir).
398
407
        """
399
408
        raise NotImplementedError(self.create_branch)
400
409
 
401
 
    def destroy_branch(self):
402
 
        """Destroy the branch in this BzrDir"""
 
410
    def destroy_branch(self, name=None):
 
411
        """Destroy a branch in this BzrDir.
 
412
        
 
413
        :param name: Name of the branch to destroy, None for the default 
 
414
            branch.
 
415
        """
403
416
        raise NotImplementedError(self.destroy_branch)
404
417
 
405
418
    @staticmethod
574
587
 
575
588
        :return: Tuple with old path name and new path name
576
589
        """
 
590
        def name_gen(base='backup.bzr'):
 
591
            counter = 1
 
592
            name = "%s.~%d~" % (base, counter)
 
593
            while self.root_transport.has(name):
 
594
                counter += 1
 
595
                name = "%s.~%d~" % (base, counter)
 
596
            return name
 
597
 
 
598
        backup_dir=name_gen()
577
599
        pb = ui.ui_factory.nested_progress_bar()
578
600
        try:
579
601
            # FIXME: bug 300001 -- the backup fails if the backup directory
580
602
            # already exists, but it should instead either remove it or make
581
603
            # a new backup directory.
582
604
            #
583
 
            # FIXME: bug 262450 -- the backup directory should have the same
584
 
            # permissions as the .bzr directory (probably a bug in copy_tree)
585
605
            old_path = self.root_transport.abspath('.bzr')
586
 
            new_path = self.root_transport.abspath('backup.bzr')
 
606
            new_path = self.root_transport.abspath(backup_dir)
587
607
            ui.ui_factory.note('making backup of %s\n  to %s' % (old_path, new_path,))
588
 
            self.root_transport.copy_tree('.bzr', 'backup.bzr')
 
608
            self.root_transport.copy_tree('.bzr', backup_dir)
589
609
            return (old_path, new_path)
590
610
        finally:
591
611
            pb.finished()
693
713
        """
694
714
        return None
695
715
 
696
 
    def get_branch_transport(self, branch_format):
 
716
    def get_branch_transport(self, branch_format, name=None):
697
717
        """Get the transport for use by branch format in this BzrDir.
698
718
 
699
719
        Note that bzr dirs that do not support format strings will raise
877
897
        BzrDir._check_supported(format, _unsupported)
878
898
        return format.open(transport, _found=True)
879
899
 
880
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
900
    def open_branch(self, name=None, unsupported=False,
 
901
                    ignore_fallbacks=False):
881
902
        """Open the branch object at this BzrDir if one is present.
882
903
 
883
904
        If unsupported is True, then no longer supported branch formats can
1021
1042
        """
1022
1043
        raise NotImplementedError(self.open_workingtree)
1023
1044
 
1024
 
    def has_branch(self):
 
1045
    def has_branch(self, name=None):
1025
1046
        """Tell if this bzrdir contains a branch.
1026
1047
 
1027
1048
        Note: if you're going to open the branch, you should just go ahead
1029
1050
        branch and discards it, and that's somewhat expensive.)
1030
1051
        """
1031
1052
        try:
1032
 
            self.open_branch()
 
1053
            self.open_branch(name)
1033
1054
            return True
1034
1055
        except errors.NotBranchError:
1035
1056
            return False
1358
1379
            tree.clone(result)
1359
1380
        return result
1360
1381
 
1361
 
    def create_branch(self):
 
1382
    def create_branch(self, name=None):
1362
1383
        """See BzrDir.create_branch."""
1363
 
        return self._format.get_branch_format().initialize(self)
 
1384
        return self._format.get_branch_format().initialize(self, name=name)
1364
1385
 
1365
 
    def destroy_branch(self):
 
1386
    def destroy_branch(self, name=None):
1366
1387
        """See BzrDir.destroy_branch."""
1367
1388
        raise errors.UnsupportedOperation(self.destroy_branch, self)
1368
1389
 
1424
1445
        raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1425
1446
                                          self)
1426
1447
 
1427
 
    def get_branch_transport(self, branch_format):
 
1448
    def get_branch_transport(self, branch_format, name=None):
1428
1449
        """See BzrDir.get_branch_transport()."""
 
1450
        if name is not None:
 
1451
            raise errors.NoColocatedBranchSupport(self)
1429
1452
        if branch_format is None:
1430
1453
            return self.transport
1431
1454
        try:
1464
1487
            format = BzrDirFormat.get_default_format()
1465
1488
        return not isinstance(self._format, format.__class__)
1466
1489
 
1467
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
1490
    def open_branch(self, name=None, unsupported=False,
 
1491
                    ignore_fallbacks=False):
1468
1492
        """See BzrDir.open_branch."""
1469
1493
        from bzrlib.branch import BzrBranchFormat4
1470
1494
        format = BzrBranchFormat4()
1471
1495
        self._check_supported(format, unsupported)
1472
 
        return format.open(self, _found=True)
 
1496
        return format.open(self, name, _found=True)
1473
1497
 
1474
1498
    def sprout(self, url, revision_id=None, force_new_repo=False,
1475
1499
               possible_transports=None, accelerator_tree=None,
1592
1616
        """See BzrDir.can_convert_format()."""
1593
1617
        return True
1594
1618
 
1595
 
    def create_branch(self):
 
1619
    def create_branch(self, name=None):
1596
1620
        """See BzrDir.create_branch."""
1597
 
        return self._format.get_branch_format().initialize(self)
 
1621
        return self._format.get_branch_format().initialize(self, name=name)
1598
1622
 
1599
 
    def destroy_branch(self):
 
1623
    def destroy_branch(self, name=None):
1600
1624
        """See BzrDir.create_branch."""
 
1625
        if name is not None:
 
1626
            raise errors.NoColocatedBranchSupport(self)
1601
1627
        self.transport.delete_tree('branch')
1602
1628
 
1603
1629
    def create_repository(self, shared=False):
1646
1672
        format = BranchFormat.find_format(self)
1647
1673
        return format.get_reference(self)
1648
1674
 
1649
 
    def get_branch_transport(self, branch_format):
 
1675
    def get_branch_transport(self, branch_format, name=None):
1650
1676
        """See BzrDir.get_branch_transport()."""
 
1677
        if name is not None:
 
1678
            raise errors.NoColocatedBranchSupport(self)
1651
1679
        # XXX: this shouldn't implicitly create the directory if it's just
1652
1680
        # promising to get a transport -- mbp 20090727
1653
1681
        if branch_format is None:
1724
1752
                return True
1725
1753
        except errors.NoRepositoryPresent:
1726
1754
            pass
1727
 
        try:
1728
 
            if not isinstance(self.open_branch()._format,
 
1755
        for branch in self.list_branches():
 
1756
            if not isinstance(branch._format,
1729
1757
                              format.get_branch_format().__class__):
1730
1758
                # the branch needs an upgrade.
1731
1759
                return True
1732
 
        except errors.NotBranchError:
1733
 
            pass
1734
1760
        try:
1735
1761
            my_wt = self.open_workingtree(recommend_upgrade=False)
1736
1762
            if not isinstance(my_wt._format,
1741
1767
            pass
1742
1768
        return False
1743
1769
 
1744
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
1770
    def open_branch(self, name=None, unsupported=False,
 
1771
                    ignore_fallbacks=False):
1745
1772
        """See BzrDir.open_branch."""
1746
1773
        format = self.find_branch_format()
1747
1774
        self._check_supported(format, unsupported)
1748
 
        return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)
 
1775
        return format.open(self, name=name,
 
1776
            _found=True, ignore_fallbacks=ignore_fallbacks)
1749
1777
 
1750
1778
    def open_repository(self, unsupported=False):
1751
1779
        """See BzrDir.open_repository."""
1783
1811
    Once a format is deprecated, just deprecate the initialize and open
1784
1812
    methods on the format class. Do not deprecate the object, as the
1785
1813
    object will be created every system load.
 
1814
 
 
1815
    :cvar colocated_branches: Whether this formats supports colocated branches.
1786
1816
    """
1787
1817
 
1788
1818
    _default_format = None
1805
1835
 
1806
1836
    _lock_file_name = 'branch-lock'
1807
1837
 
 
1838
    colocated_branches = False
 
1839
    """Whether co-located branches are supported for this control dir format.
 
1840
    """
 
1841
 
1808
1842
    # _lock_class must be set in subclasses to the lock type, typ.
1809
1843
    # TransportLock or LockDir
1810
1844
 
2609
2643
    def convert(self, to_convert, pb):
2610
2644
        """See Converter.convert()."""
2611
2645
        self.bzrdir = to_convert
2612
 
        self.pb = pb
2613
 
        ui.ui_factory.note('starting upgrade from format 4 to 5')
2614
 
        if isinstance(self.bzrdir.transport, local.LocalTransport):
2615
 
            self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2616
 
        self._convert_to_weaves()
2617
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
2646
        if pb is not None:
 
2647
            warnings.warn("pb parameter to convert() is deprecated")
 
2648
        self.pb = ui.ui_factory.nested_progress_bar()
 
2649
        try:
 
2650
            ui.ui_factory.note('starting upgrade from format 4 to 5')
 
2651
            if isinstance(self.bzrdir.transport, local.LocalTransport):
 
2652
                self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
 
2653
            self._convert_to_weaves()
 
2654
            return BzrDir.open(self.bzrdir.root_transport.base)
 
2655
        finally:
 
2656
            self.pb.finished()
2618
2657
 
2619
2658
    def _convert_to_weaves(self):
2620
2659
        ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2861
2900
    def convert(self, to_convert, pb):
2862
2901
        """See Converter.convert()."""
2863
2902
        self.bzrdir = to_convert
2864
 
        self.pb = pb
2865
 
        ui.ui_factory.note('starting upgrade from format 5 to 6')
2866
 
        self._convert_to_prefixed()
2867
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
2903
        pb = ui.ui_factory.nested_progress_bar()
 
2904
        try:
 
2905
            ui.ui_factory.note('starting upgrade from format 5 to 6')
 
2906
            self._convert_to_prefixed()
 
2907
            return BzrDir.open(self.bzrdir.root_transport.base)
 
2908
        finally:
 
2909
            pb.finished()
2868
2910
 
2869
2911
    def _convert_to_prefixed(self):
2870
2912
        from bzrlib.store import TransportStore
2903
2945
        from bzrlib.repofmt.weaverepo import RepositoryFormat7
2904
2946
        from bzrlib.branch import BzrBranchFormat5
2905
2947
        self.bzrdir = to_convert
2906
 
        self.pb = pb
 
2948
        self.pb = ui.ui_factory.nested_progress_bar()
2907
2949
        self.count = 0
2908
2950
        self.total = 20 # the steps we know about
2909
2951
        self.garbage_inventories = []
2989
3031
            'branch-format',
2990
3032
            BzrDirMetaFormat1().get_format_string(),
2991
3033
            mode=self.file_mode)
 
3034
        self.pb.finished()
2992
3035
        return BzrDir.open(self.bzrdir.root_transport.base)
2993
3036
 
2994
3037
    def make_lock(self, name):
3030
3073
    def convert(self, to_convert, pb):
3031
3074
        """See Converter.convert()."""
3032
3075
        self.bzrdir = to_convert
3033
 
        self.pb = pb
 
3076
        self.pb = ui.ui_factory.nested_progress_bar()
3034
3077
        self.count = 0
3035
3078
        self.total = 1
3036
3079
        self.step('checking repository format')
3044
3087
                ui.ui_factory.note('starting repository conversion')
3045
3088
                converter = CopyConverter(self.target_format.repository_format)
3046
3089
                converter.convert(repo, pb)
3047
 
        try:
3048
 
            branch = self.bzrdir.open_branch()
3049
 
        except errors.NotBranchError:
3050
 
            pass
3051
 
        else:
 
3090
        for branch in self.bzrdir.list_branches():
3052
3091
            # TODO: conversions of Branch and Tree should be done by
3053
3092
            # InterXFormat lookups/some sort of registry.
3054
3093
            # Avoid circular imports
3096
3135
                isinstance(self.target_format.workingtree_format,
3097
3136
                    workingtree_4.WorkingTreeFormat6)):
3098
3137
                workingtree_4.Converter4or5to6().convert(tree)
 
3138
        self.pb.finished()
3099
3139
        return to_convert
3100
3140
 
3101
3141
 
3772
3812
    help='New in 0.92: Pack-based format with data compatible with '
3773
3813
        'dirstate-tags format repositories. Interoperates with '
3774
3814
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3775
 
        'Previously called knitpack-experimental.  '
3776
 
        'For more information, see '
3777
 
        'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
 
3815
        ,
3778
3816
    branch_format='bzrlib.branch.BzrBranchFormat6',
3779
3817
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3780
3818
    )
3783
3821
    help='New in 0.92: Pack-based format with data compatible with '
3784
3822
        'dirstate-with-subtree format repositories. Interoperates with '
3785
3823
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3786
 
        'Previously called knitpack-experimental.  '
3787
 
        'For more information, see '
3788
 
        'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
 
3824
        ,
3789
3825
    branch_format='bzrlib.branch.BzrBranchFormat6',
3790
3826
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3791
3827
    hidden=True,
3853
3889
        'to and from rich-root-pack (and anything compatible with '
3854
3890
        'rich-root-pack) format repositories. Repositories and branches in '
3855
3891
        'this format can only be read by bzr.dev. Please read '
3856
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3892
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3857
3893
        'before use.',
3858
3894
    branch_format='bzrlib.branch.BzrBranchFormat7',
3859
3895
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3867
3903
        'from pack-0.92-subtree (and anything compatible with '
3868
3904
        'pack-0.92-subtree) format repositories. Repositories and branches in '
3869
3905
        'this format can only be read by bzr.dev. Please read '
3870
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3906
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3871
3907
        'before use.',
3872
3908
    branch_format='bzrlib.branch.BzrBranchFormat7',
3873
3909
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3883
3919
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3884
3920
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3885
3921
        'Please read '
3886
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3922
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3887
3923
        'before use.',
3888
3924
    branch_format='bzrlib.branch.BzrBranchFormat7',
3889
3925
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3895
3931
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
3896
3932
    help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
3897
3933
        'rich roots. Please read '
3898
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
3934
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3899
3935
        'before use.',
3900
3936
    branch_format='bzrlib.branch.BzrBranchFormat7',
3901
3937
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',