~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

Merge up through 2.2.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
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(), """
85
86
    registry,
86
87
    symbol_versioning,
87
88
    )
88
 
 
89
 
 
90
 
class BzrDir(object):
91
 
    """A .bzr control directory.
 
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):
 
125
    """A .bzr control diretory.
92
126
 
93
127
    BzrDir instances let you create or open any of the things that can be
94
128
    found within .bzr - checkouts, branches and repositories.
260
294
                # copied, and finally if we are copying up to a specific
261
295
                # revision_id then we can use the pending-ancestry-result which
262
296
                # does not require traversing all of history to describe it.
263
 
                if (result_repo.bzrdir.root_transport.base ==
264
 
                    result.root_transport.base and not require_stacking and
 
297
                if (result_repo.user_url == result.user_url
 
298
                    and not require_stacking and
265
299
                    revision_id is not None):
266
300
                    fetch_spec = graph.PendingAncestryResult(
267
301
                        [revision_id], local_repo)
341
375
            recurse = True
342
376
            try:
343
377
                bzrdir = BzrDir.open_from_transport(current_transport)
344
 
            except errors.NotBranchError:
 
378
            except (errors.NotBranchError, errors.PermissionDenied):
345
379
                pass
346
380
            else:
347
381
                recurse, value = evaluate(bzrdir)
348
382
                yield value
349
383
            try:
350
384
                subdirs = list_current(current_transport)
351
 
            except errors.NoSuchFile:
 
385
            except (errors.NoSuchFile, errors.PermissionDenied):
352
386
                continue
353
387
            if recurse:
354
388
                for subdir in sorted(subdirs, reverse=True):
355
389
                    pending.append(current_transport.clone(subdir))
356
390
 
 
391
    def list_branches(self):
 
392
        """Return a sequence of all branches local to this control directory.
 
393
 
 
394
        """
 
395
        try:
 
396
            return [self.open_branch()]
 
397
        except (errors.NotBranchError, errors.NoRepositoryPresent):
 
398
            return []
 
399
 
357
400
    @staticmethod
358
401
    def find_branches(transport):
359
402
        """Find all branches under a transport.
371
414
            except errors.NoRepositoryPresent:
372
415
                pass
373
416
            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):
 
417
                return False, ([], repository)
 
418
            return True, (bzrdir.list_branches(), None)
 
419
        ret = []
 
420
        for branches, repo in BzrDir.find_bzrdirs(transport,
 
421
                                                  evaluate=evaluate):
383
422
            if repo is not None:
384
 
                branches.extend(repo.find_branches())
385
 
            if branch is not None:
386
 
                branches.append(branch)
387
 
        return branches
 
423
                ret.extend(repo.find_branches())
 
424
            if branches is not None:
 
425
                ret.extend(branches)
 
426
        return ret
388
427
 
389
428
    def destroy_repository(self):
390
429
        """Destroy the repository in this BzrDir"""
391
430
        raise NotImplementedError(self.destroy_repository)
392
431
 
393
 
    def create_branch(self):
 
432
    def create_branch(self, name=None):
394
433
        """Create a branch in this BzrDir.
395
434
 
 
435
        :param name: Name of the colocated branch to create, None for
 
436
            the default branch.
 
437
 
396
438
        The bzrdir's format will control what branch format is created.
397
439
        For more control see BranchFormatXX.create(a_bzrdir).
398
440
        """
399
441
        raise NotImplementedError(self.create_branch)
400
442
 
401
 
    def destroy_branch(self):
402
 
        """Destroy the branch in this BzrDir"""
 
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
        """
403
449
        raise NotImplementedError(self.destroy_branch)
404
450
 
405
451
    @staticmethod
445
491
            stop = False
446
492
            stack_on = config.get_default_stack_on()
447
493
            if stack_on is not None:
448
 
                stack_on_pwd = found_bzrdir.root_transport.base
 
494
                stack_on_pwd = found_bzrdir.user_url
449
495
                stop = True
450
496
            # does it have a repository ?
451
497
            try:
453
499
            except errors.NoRepositoryPresent:
454
500
                repository = None
455
501
            else:
456
 
                if ((found_bzrdir.root_transport.base !=
457
 
                     self.root_transport.base) and not repository.is_shared()):
 
502
                if (found_bzrdir.user_url != self.user_url 
 
503
                    and not repository.is_shared()):
458
504
                    # Don't look higher, can't use a higher shared repo.
459
505
                    repository = None
460
506
                    stop = True
574
620
 
575
621
        :return: Tuple with old path name and new path name
576
622
        """
 
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()
577
632
        pb = ui.ui_factory.nested_progress_bar()
578
633
        try:
579
634
            # FIXME: bug 300001 -- the backup fails if the backup directory
580
635
            # already exists, but it should instead either remove it or make
581
636
            # a new backup directory.
582
637
            #
583
 
            # FIXME: bug 262450 -- the backup directory should have the same
584
 
            # permissions as the .bzr directory (probably a bug in copy_tree)
585
638
            old_path = self.root_transport.abspath('.bzr')
586
 
            new_path = self.root_transport.abspath('backup.bzr')
587
 
            pb.note('making backup of %s' % (old_path,))
588
 
            pb.note('  to %s' % (new_path,))
589
 
            self.root_transport.copy_tree('.bzr', 'backup.bzr')
 
639
            new_path = self.root_transport.abspath(backup_dir)
 
640
            ui.ui_factory.note('making backup of %s\n  to %s' % (old_path, new_path,))
 
641
            self.root_transport.copy_tree('.bzr', backup_dir)
590
642
            return (old_path, new_path)
591
643
        finally:
592
644
            pb.finished()
650
702
            if stop:
651
703
                return result
652
704
            next_transport = found_bzrdir.root_transport.clone('..')
653
 
            if (found_bzrdir.root_transport.base == next_transport.base):
 
705
            if (found_bzrdir.user_url == next_transport.base):
654
706
                # top of the file system
655
707
                return None
656
708
            # find the next containing bzrdir
673
725
                repository = found_bzrdir.open_repository()
674
726
            except errors.NoRepositoryPresent:
675
727
                return None, False
676
 
            if found_bzrdir.root_transport.base == self.root_transport.base:
 
728
            if found_bzrdir.user_url == self.user_url:
677
729
                return repository, True
678
730
            elif repository.is_shared():
679
731
                return repository, True
685
737
            raise errors.NoRepositoryPresent(self)
686
738
        return found_repo
687
739
 
688
 
    def get_branch_reference(self):
 
740
    def get_branch_reference(self, name=None):
689
741
        """Return the referenced URL for the branch in this bzrdir.
690
742
 
 
743
        :param name: Optional colocated branch name
691
744
        :raises NotBranchError: If there is no Branch.
 
745
        :raises NoColocatedBranchSupport: If a branch name was specified
 
746
            but colocated branches are not supported.
692
747
        :return: The URL the branch in this bzrdir references if it is a
693
748
            reference branch, or None for regular branches.
694
749
        """
 
750
        if name is not None:
 
751
            raise errors.NoColocatedBranchSupport(self)
695
752
        return None
696
753
 
697
 
    def get_branch_transport(self, branch_format):
 
754
    def get_branch_transport(self, branch_format, name=None):
698
755
        """Get the transport for use by branch format in this BzrDir.
699
756
 
700
757
        Note that bzr dirs that do not support format strings will raise
795
852
        :param _transport: the transport this dir is based at.
796
853
        """
797
854
        self._format = _format
 
855
        # these are also under the more standard names of 
 
856
        # control_transport and user_transport
798
857
        self.transport = _transport.clone('.bzr')
799
858
        self.root_transport = _transport
800
859
        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
801
868
 
802
869
    def is_control_filename(self, filename):
803
870
        """True if filename is the name of a path which is reserved for bzrdir's.
878
945
        BzrDir._check_supported(format, _unsupported)
879
946
        return format.open(transport, _found=True)
880
947
 
881
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
948
    def open_branch(self, name=None, unsupported=False,
 
949
                    ignore_fallbacks=False):
882
950
        """Open the branch object at this BzrDir if one is present.
883
951
 
884
952
        If unsupported is True, then no longer supported branch formats can
931
999
                raise errors.NotBranchError(path=url)
932
1000
            a_transport = new_t
933
1001
 
934
 
    def _get_tree_branch(self):
 
1002
    def _get_tree_branch(self, name=None):
935
1003
        """Return the branch and tree, if any, for this bzrdir.
936
1004
 
 
1005
        :param name: Name of colocated branch to open.
 
1006
 
937
1007
        Return None for tree if not present or inaccessible.
938
1008
        Raise NotBranchError if no branch is present.
939
1009
        :return: (tree, branch)
942
1012
            tree = self.open_workingtree()
943
1013
        except (errors.NoWorkingTree, errors.NotLocalUrl):
944
1014
            tree = None
945
 
            branch = self.open_branch()
 
1015
            branch = self.open_branch(name=name)
946
1016
        else:
947
 
            branch = tree.branch
 
1017
            if name is not None:
 
1018
                branch = self.open_branch(name=name)
 
1019
            else:
 
1020
                branch = tree.branch
948
1021
        return tree, branch
949
1022
 
950
1023
    @classmethod
1022
1095
        """
1023
1096
        raise NotImplementedError(self.open_workingtree)
1024
1097
 
1025
 
    def has_branch(self):
 
1098
    def has_branch(self, name=None):
1026
1099
        """Tell if this bzrdir contains a branch.
1027
1100
 
1028
1101
        Note: if you're going to open the branch, you should just go ahead
1030
1103
        branch and discards it, and that's somewhat expensive.)
1031
1104
        """
1032
1105
        try:
1033
 
            self.open_branch()
 
1106
            self.open_branch(name)
1034
1107
            return True
1035
1108
        except errors.NotBranchError:
1036
1109
            return False
1171
1244
        repository_policy = result.determine_repository_policy(
1172
1245
            force_new_repo, stacked_branch_url, require_stacking=stacked)
1173
1246
        result_repo, is_new_repo = repository_policy.acquire_repository()
1174
 
        if is_new_repo and revision_id is not None and not stacked:
 
1247
        is_stacked = stacked or (len(result_repo._fallback_repositories) != 0)
 
1248
        if is_new_repo and revision_id is not None and not is_stacked:
1175
1249
            fetch_spec = graph.PendingAncestryResult(
1176
1250
                [revision_id], source_repository)
1177
1251
        else:
1344
1418
        self.create_hook(hooks.HookPoint('pre_open',
1345
1419
            "Invoked before attempting to open a BzrDir with the transport "
1346
1420
            "that the open will use.", (1, 14), None))
 
1421
        self.create_hook(hooks.HookPoint('post_repo_init',
 
1422
            "Invoked after a repository has been initialized. "
 
1423
            "post_repo_init is called with a "
 
1424
            "bzrlib.bzrdir.RepoInitHookParams.",
 
1425
            (2, 2), None))
1347
1426
 
1348
1427
# install the default hooks
1349
1428
BzrDir.hooks = BzrDirHooks()
1350
1429
 
1351
1430
 
 
1431
class RepoInitHookParams(object):
 
1432
    """Object holding parameters passed to *_repo_init hooks.
 
1433
 
 
1434
    There are 4 fields that hooks may wish to access:
 
1435
 
 
1436
    :ivar repository: Repository created
 
1437
    :ivar format: Repository format
 
1438
    :ivar bzrdir: The bzrdir for the repository
 
1439
    :ivar shared: The repository is shared
 
1440
    """
 
1441
 
 
1442
    def __init__(self, repository, format, a_bzrdir, shared):
 
1443
        """Create a group of RepoInitHook parameters.
 
1444
 
 
1445
        :param repository: Repository created
 
1446
        :param format: Repository format
 
1447
        :param bzrdir: The bzrdir for the repository
 
1448
        :param shared: The repository is shared
 
1449
        """
 
1450
        self.repository = repository
 
1451
        self.format = format
 
1452
        self.bzrdir = a_bzrdir
 
1453
        self.shared = shared
 
1454
 
 
1455
    def __eq__(self, other):
 
1456
        return self.__dict__ == other.__dict__
 
1457
 
 
1458
    def __repr__(self):
 
1459
        if self.repository:
 
1460
            return "<%s for %s>" % (self.__class__.__name__,
 
1461
                self.repository)
 
1462
        else:
 
1463
            return "<%s for %s>" % (self.__class__.__name__,
 
1464
                self.bzrdir)
 
1465
 
 
1466
 
1352
1467
class BzrDirPreSplitOut(BzrDir):
1353
1468
    """A common class for the all-in-one formats."""
1354
1469
 
1393
1508
            tree.clone(result)
1394
1509
        return result
1395
1510
 
1396
 
    def create_branch(self):
 
1511
    def create_branch(self, name=None):
1397
1512
        """See BzrDir.create_branch."""
1398
 
        return self._format.get_branch_format().initialize(self)
 
1513
        return self._format.get_branch_format().initialize(self, name=name)
1399
1514
 
1400
 
    def destroy_branch(self):
 
1515
    def destroy_branch(self, name=None):
1401
1516
        """See BzrDir.destroy_branch."""
1402
1517
        raise errors.UnsupportedOperation(self.destroy_branch, self)
1403
1518
 
1459
1574
        raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1460
1575
                                          self)
1461
1576
 
1462
 
    def get_branch_transport(self, branch_format):
 
1577
    def get_branch_transport(self, branch_format, name=None):
1463
1578
        """See BzrDir.get_branch_transport()."""
 
1579
        if name is not None:
 
1580
            raise errors.NoColocatedBranchSupport(self)
1464
1581
        if branch_format is None:
1465
1582
            return self.transport
1466
1583
        try:
1499
1616
            format = BzrDirFormat.get_default_format()
1500
1617
        return not isinstance(self._format, format.__class__)
1501
1618
 
1502
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
1619
    def open_branch(self, name=None, unsupported=False,
 
1620
                    ignore_fallbacks=False):
1503
1621
        """See BzrDir.open_branch."""
1504
1622
        from bzrlib.branch import BzrBranchFormat4
1505
1623
        format = BzrBranchFormat4()
1506
1624
        self._check_supported(format, unsupported)
1507
 
        return format.open(self, _found=True)
 
1625
        return format.open(self, name, _found=True)
1508
1626
 
1509
1627
    def sprout(self, url, revision_id=None, force_new_repo=False,
1510
1628
               possible_transports=None, accelerator_tree=None,
1571
1689
    This is a deprecated format and may be removed after sept 2006.
1572
1690
    """
1573
1691
 
 
1692
    def has_workingtree(self):
 
1693
        """See BzrDir.has_workingtree."""
 
1694
        return True
 
1695
    
1574
1696
    def open_repository(self):
1575
1697
        """See BzrDir.open_repository."""
1576
1698
        from bzrlib.repofmt.weaverepo import RepositoryFormat5
1592
1714
    This is a deprecated format and may be removed after sept 2006.
1593
1715
    """
1594
1716
 
 
1717
    def has_workingtree(self):
 
1718
        """See BzrDir.has_workingtree."""
 
1719
        return True
 
1720
    
1595
1721
    def open_repository(self):
1596
1722
        """See BzrDir.open_repository."""
1597
1723
        from bzrlib.repofmt.weaverepo import RepositoryFormat6
1619
1745
        """See BzrDir.can_convert_format()."""
1620
1746
        return True
1621
1747
 
1622
 
    def create_branch(self):
 
1748
    def create_branch(self, name=None):
1623
1749
        """See BzrDir.create_branch."""
1624
 
        return self._format.get_branch_format().initialize(self)
 
1750
        return self._format.get_branch_format().initialize(self, name=name)
1625
1751
 
1626
 
    def destroy_branch(self):
 
1752
    def destroy_branch(self, name=None):
1627
1753
        """See BzrDir.create_branch."""
 
1754
        if name is not None:
 
1755
            raise errors.NoColocatedBranchSupport(self)
1628
1756
        self.transport.delete_tree('branch')
1629
1757
 
1630
1758
    def create_repository(self, shared=False):
1653
1781
    def destroy_workingtree_metadata(self):
1654
1782
        self.transport.delete_tree('checkout')
1655
1783
 
1656
 
    def find_branch_format(self):
 
1784
    def find_branch_format(self, name=None):
1657
1785
        """Find the branch 'format' for this bzrdir.
1658
1786
 
1659
1787
        This might be a synthetic object for e.g. RemoteBranch and SVN.
1660
1788
        """
1661
1789
        from bzrlib.branch import BranchFormat
1662
 
        return BranchFormat.find_format(self)
 
1790
        return BranchFormat.find_format(self, name=name)
1663
1791
 
1664
1792
    def _get_mkdir_mode(self):
1665
1793
        """Figure out the mode to use when creating a bzrdir subdir."""
1667
1795
                                     lockable_files.TransportLock)
1668
1796
        return temp_control._dir_mode
1669
1797
 
1670
 
    def get_branch_reference(self):
 
1798
    def get_branch_reference(self, name=None):
1671
1799
        """See BzrDir.get_branch_reference()."""
1672
1800
        from bzrlib.branch import BranchFormat
1673
 
        format = BranchFormat.find_format(self)
1674
 
        return format.get_reference(self)
 
1801
        format = BranchFormat.find_format(self, name=name)
 
1802
        return format.get_reference(self, name=name)
1675
1803
 
1676
 
    def get_branch_transport(self, branch_format):
 
1804
    def get_branch_transport(self, branch_format, name=None):
1677
1805
        """See BzrDir.get_branch_transport()."""
 
1806
        if name is not None:
 
1807
            raise errors.NoColocatedBranchSupport(self)
1678
1808
        # XXX: this shouldn't implicitly create the directory if it's just
1679
1809
        # promising to get a transport -- mbp 20090727
1680
1810
        if branch_format is None:
1717
1847
            pass
1718
1848
        return self.transport.clone('checkout')
1719
1849
 
 
1850
    def has_workingtree(self):
 
1851
        """Tell if this bzrdir contains a working tree.
 
1852
 
 
1853
        This will still raise an exception if the bzrdir has a workingtree that
 
1854
        is remote & inaccessible.
 
1855
 
 
1856
        Note: if you're going to open the working tree, you should just go
 
1857
        ahead and try, and not ask permission first.
 
1858
        """
 
1859
        from bzrlib.workingtree import WorkingTreeFormat
 
1860
        try:
 
1861
            WorkingTreeFormat.find_format(self)
 
1862
        except errors.NoWorkingTree:
 
1863
            return False
 
1864
        return True
 
1865
 
1720
1866
    def needs_format_conversion(self, format=None):
1721
1867
        """See BzrDir.needs_format_conversion()."""
1722
1868
        if format is None:
1735
1881
                return True
1736
1882
        except errors.NoRepositoryPresent:
1737
1883
            pass
1738
 
        try:
1739
 
            if not isinstance(self.open_branch()._format,
 
1884
        for branch in self.list_branches():
 
1885
            if not isinstance(branch._format,
1740
1886
                              format.get_branch_format().__class__):
1741
1887
                # the branch needs an upgrade.
1742
1888
                return True
1743
 
        except errors.NotBranchError:
1744
 
            pass
1745
1889
        try:
1746
1890
            my_wt = self.open_workingtree(recommend_upgrade=False)
1747
1891
            if not isinstance(my_wt._format,
1752
1896
            pass
1753
1897
        return False
1754
1898
 
1755
 
    def open_branch(self, unsupported=False, ignore_fallbacks=False):
 
1899
    def open_branch(self, name=None, unsupported=False,
 
1900
                    ignore_fallbacks=False):
1756
1901
        """See BzrDir.open_branch."""
1757
 
        format = self.find_branch_format()
 
1902
        format = self.find_branch_format(name=name)
1758
1903
        self._check_supported(format, unsupported)
1759
 
        return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)
 
1904
        return format.open(self, name=name,
 
1905
            _found=True, ignore_fallbacks=ignore_fallbacks)
1760
1906
 
1761
1907
    def open_repository(self, unsupported=False):
1762
1908
        """See BzrDir.open_repository."""
1794
1940
    Once a format is deprecated, just deprecate the initialize and open
1795
1941
    methods on the format class. Do not deprecate the object, as the
1796
1942
    object will be created every system load.
 
1943
 
 
1944
    :cvar colocated_branches: Whether this formats supports colocated branches.
1797
1945
    """
1798
1946
 
1799
1947
    _default_format = None
1816
1964
 
1817
1965
    _lock_file_name = 'branch-lock'
1818
1966
 
 
1967
    colocated_branches = False
 
1968
    """Whether co-located branches are supported for this control dir format.
 
1969
    """
 
1970
 
1819
1971
    # _lock_class must be set in subclasses to the lock type, typ.
1820
1972
    # TransportLock or LockDir
1821
1973
 
1838
1990
    def probe_transport(klass, transport):
1839
1991
        """Return the .bzrdir style format present in a directory."""
1840
1992
        try:
1841
 
            format_string = transport.get(".bzr/branch-format").read()
 
1993
            format_string = transport.get_bytes(".bzr/branch-format")
1842
1994
        except errors.NoSuchFile:
1843
1995
            raise errors.NotBranchError(path=transport.base)
1844
 
 
1845
1996
        try:
1846
1997
            return klass._formats[format_string]
1847
1998
        except KeyError:
2620
2771
    def convert(self, to_convert, pb):
2621
2772
        """See Converter.convert()."""
2622
2773
        self.bzrdir = to_convert
2623
 
        self.pb = pb
2624
 
        self.pb.note('starting upgrade from format 4 to 5')
2625
 
        if isinstance(self.bzrdir.transport, local.LocalTransport):
2626
 
            self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2627
 
        self._convert_to_weaves()
2628
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
2774
        if pb is not None:
 
2775
            warnings.warn("pb parameter to convert() is deprecated")
 
2776
        self.pb = ui.ui_factory.nested_progress_bar()
 
2777
        try:
 
2778
            ui.ui_factory.note('starting upgrade from format 4 to 5')
 
2779
            if isinstance(self.bzrdir.transport, local.LocalTransport):
 
2780
                self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
 
2781
            self._convert_to_weaves()
 
2782
            return BzrDir.open(self.bzrdir.user_url)
 
2783
        finally:
 
2784
            self.pb.finished()
2629
2785
 
2630
2786
    def _convert_to_weaves(self):
2631
 
        self.pb.note('note: upgrade may be faster if all store files are ungzipped first')
 
2787
        ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2632
2788
        try:
2633
2789
            # TODO permissions
2634
2790
            stat = self.bzrdir.transport.stat('weaves')
2662
2818
        self.pb.clear()
2663
2819
        self._write_all_weaves()
2664
2820
        self._write_all_revs()
2665
 
        self.pb.note('upgraded to weaves:')
2666
 
        self.pb.note('  %6d revisions and inventories', len(self.revisions))
2667
 
        self.pb.note('  %6d revisions not present', len(self.absent_revisions))
2668
 
        self.pb.note('  %6d texts', self.text_count)
 
2821
        ui.ui_factory.note('upgraded to weaves:')
 
2822
        ui.ui_factory.note('  %6d revisions and inventories' % len(self.revisions))
 
2823
        ui.ui_factory.note('  %6d revisions not present' % len(self.absent_revisions))
 
2824
        ui.ui_factory.note('  %6d texts' % self.text_count)
2669
2825
        self._cleanup_spare_files_after_format4()
2670
2826
        self.branch._transport.put_bytes(
2671
2827
            'branch-format',
2739
2895
                       len(self.known_revisions))
2740
2896
        if not self.branch.repository.has_revision(rev_id):
2741
2897
            self.pb.clear()
2742
 
            self.pb.note('revision {%s} not present in branch; '
2743
 
                         'will be converted as a ghost',
 
2898
            ui.ui_factory.note('revision {%s} not present in branch; '
 
2899
                         'will be converted as a ghost' %
2744
2900
                         rev_id)
2745
2901
            self.absent_revisions.add(rev_id)
2746
2902
        else:
2751
2907
            self.revisions[rev_id] = rev
2752
2908
 
2753
2909
    def _load_old_inventory(self, rev_id):
2754
 
        old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
 
2910
        f = self.branch.repository.inventory_store.get(rev_id)
 
2911
        try:
 
2912
            old_inv_xml = f.read()
 
2913
        finally:
 
2914
            f.close()
2755
2915
        inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2756
2916
        inv.revision_id = rev_id
2757
2917
        rev = self.revisions[rev_id]
2835
2995
                ie.revision = previous_ie.revision
2836
2996
                return
2837
2997
        if ie.has_text():
2838
 
            text = self.branch.repository._text_store.get(ie.text_id)
2839
 
            file_lines = text.readlines()
 
2998
            f = self.branch.repository._text_store.get(ie.text_id)
 
2999
            try:
 
3000
                file_lines = f.readlines()
 
3001
            finally:
 
3002
                f.close()
2840
3003
            w.add_lines(rev_id, previous_revisions, file_lines)
2841
3004
            self.text_count += 1
2842
3005
        else:
2872
3035
    def convert(self, to_convert, pb):
2873
3036
        """See Converter.convert()."""
2874
3037
        self.bzrdir = to_convert
2875
 
        self.pb = pb
2876
 
        self.pb.note('starting upgrade from format 5 to 6')
2877
 
        self._convert_to_prefixed()
2878
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
3038
        pb = ui.ui_factory.nested_progress_bar()
 
3039
        try:
 
3040
            ui.ui_factory.note('starting upgrade from format 5 to 6')
 
3041
            self._convert_to_prefixed()
 
3042
            return BzrDir.open(self.bzrdir.user_url)
 
3043
        finally:
 
3044
            pb.finished()
2879
3045
 
2880
3046
    def _convert_to_prefixed(self):
2881
3047
        from bzrlib.store import TransportStore
2882
3048
        self.bzrdir.transport.delete('branch-format')
2883
3049
        for store_name in ["weaves", "revision-store"]:
2884
 
            self.pb.note("adding prefixes to %s" % store_name)
 
3050
            ui.ui_factory.note("adding prefixes to %s" % store_name)
2885
3051
            store_transport = self.bzrdir.transport.clone(store_name)
2886
3052
            store = TransportStore(store_transport, prefixed=True)
2887
3053
            for urlfilename in store_transport.list_dir('.'):
2914
3080
        from bzrlib.repofmt.weaverepo import RepositoryFormat7
2915
3081
        from bzrlib.branch import BzrBranchFormat5
2916
3082
        self.bzrdir = to_convert
2917
 
        self.pb = pb
 
3083
        self.pb = ui.ui_factory.nested_progress_bar()
2918
3084
        self.count = 0
2919
3085
        self.total = 20 # the steps we know about
2920
3086
        self.garbage_inventories = []
2921
3087
        self.dir_mode = self.bzrdir._get_dir_mode()
2922
3088
        self.file_mode = self.bzrdir._get_file_mode()
2923
3089
 
2924
 
        self.pb.note('starting upgrade from format 6 to metadir')
 
3090
        ui.ui_factory.note('starting upgrade from format 6 to metadir')
2925
3091
        self.bzrdir.transport.put_bytes(
2926
3092
                'branch-format',
2927
3093
                "Converting to format 6",
2977
3143
        else:
2978
3144
            has_checkout = True
2979
3145
        if not has_checkout:
2980
 
            self.pb.note('No working tree.')
 
3146
            ui.ui_factory.note('No working tree.')
2981
3147
            # If some checkout files are there, we may as well get rid of them.
2982
3148
            for name, mandatory in checkout_files:
2983
3149
                if name in bzrcontents:
3000
3166
            'branch-format',
3001
3167
            BzrDirMetaFormat1().get_format_string(),
3002
3168
            mode=self.file_mode)
3003
 
        return BzrDir.open(self.bzrdir.root_transport.base)
 
3169
        self.pb.finished()
 
3170
        return BzrDir.open(self.bzrdir.user_url)
3004
3171
 
3005
3172
    def make_lock(self, name):
3006
3173
        """Make a lock for the new control dir name."""
3041
3208
    def convert(self, to_convert, pb):
3042
3209
        """See Converter.convert()."""
3043
3210
        self.bzrdir = to_convert
3044
 
        self.pb = pb
 
3211
        self.pb = ui.ui_factory.nested_progress_bar()
3045
3212
        self.count = 0
3046
3213
        self.total = 1
3047
3214
        self.step('checking repository format')
3052
3219
        else:
3053
3220
            if not isinstance(repo._format, self.target_format.repository_format.__class__):
3054
3221
                from bzrlib.repository import CopyConverter
3055
 
                self.pb.note('starting repository conversion')
 
3222
                ui.ui_factory.note('starting repository conversion')
3056
3223
                converter = CopyConverter(self.target_format.repository_format)
3057
3224
                converter.convert(repo, pb)
3058
 
        try:
3059
 
            branch = self.bzrdir.open_branch()
3060
 
        except errors.NotBranchError:
3061
 
            pass
3062
 
        else:
 
3225
        for branch in self.bzrdir.list_branches():
3063
3226
            # TODO: conversions of Branch and Tree should be done by
3064
3227
            # InterXFormat lookups/some sort of registry.
3065
3228
            # Avoid circular imports
3107
3270
                isinstance(self.target_format.workingtree_format,
3108
3271
                    workingtree_4.WorkingTreeFormat6)):
3109
3272
                workingtree_4.Converter4or5to6().convert(tree)
 
3273
        self.pb.finished()
3110
3274
        return to_convert
3111
3275
 
3112
3276
 
3119
3283
 
3120
3284
    def __init__(self):
3121
3285
        BzrDirMetaFormat1.__init__(self)
 
3286
        # XXX: It's a bit ugly that the network name is here, because we'd
 
3287
        # like to believe that format objects are stateless or at least
 
3288
        # immutable,  However, we do at least avoid mutating the name after
 
3289
        # it's returned.  See <https://bugs.launchpad.net/bzr/+bug/504102>
3122
3290
        self._network_name = None
3123
3291
 
 
3292
    def __repr__(self):
 
3293
        return "%s(_network_name=%r)" % (self.__class__.__name__,
 
3294
            self._network_name)
 
3295
 
3124
3296
    def get_format_description(self):
 
3297
        if self._network_name:
 
3298
            real_format = network_format_registry.get(self._network_name)
 
3299
            return 'Remote: ' + real_format.get_format_description()
3125
3300
        return 'bzr remote bzrdir'
3126
3301
 
3127
3302
    def get_format_string(self):
3260
3435
        args.append(self._serialize_NoneString(repo_format_name))
3261
3436
        args.append(self._serialize_NoneTrueFalse(make_working_trees))
3262
3437
        args.append(self._serialize_NoneTrueFalse(shared_repo))
3263
 
        if self._network_name is None:
3264
 
            self._network_name = \
 
3438
        request_network_name = self._network_name or \
3265
3439
            BzrDirFormat.get_default_format().network_name()
3266
3440
        try:
3267
3441
            response = client.call('BzrDirFormat.initialize_ex_1.16',
3268
 
                self.network_name(), path, *args)
 
3442
                request_network_name, path, *args)
3269
3443
        except errors.UnknownSmartMethod:
3270
3444
            client._medium._remember_remote_is_before((1,16))
3271
3445
            local_dir_format = BzrDirMetaFormat1()
3521
3695
                experimental_pairs.append((key, help))
3522
3696
            else:
3523
3697
                output += wrapped(key, help, info)
3524
 
        output += "\nSee ``bzr help formats`` for more about storage formats."
 
3698
        output += "\nSee :doc:`formats-help` for more about storage formats."
3525
3699
        other_output = ""
3526
3700
        if len(experimental_pairs) > 0:
3527
3701
            other_output += "Experimental formats are shown below.\n\n"
3540
3714
            other_output += \
3541
3715
                "\nNo deprecated formats are available.\n\n"
3542
3716
        other_output += \
3543
 
            "\nSee ``bzr help formats`` for more about storage formats."
 
3717
                "\nSee :doc:`formats-help` for more about storage formats."
3544
3718
 
3545
3719
        if topic == 'other-formats':
3546
3720
            return other_output
3580
3754
            try:
3581
3755
                stack_on = urlutils.rebase_url(self._stack_on,
3582
3756
                    self._stack_on_pwd,
3583
 
                    branch.bzrdir.root_transport.base)
 
3757
                    branch.user_url)
3584
3758
            except errors.InvalidRebaseURLs:
3585
3759
                stack_on = self._get_full_stack_on()
3586
3760
        try:
3715
3889
format_registry.register('weave', BzrDirFormat6,
3716
3890
    'Pre-0.8 format.  Slower than knit and does not'
3717
3891
    ' support checkouts or shared repositories.',
 
3892
    hidden=True,
3718
3893
    deprecated=True)
3719
3894
format_registry.register_metadir('metaweave',
3720
3895
    'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3721
3896
    'Transitional format in 0.8.  Slower than knit.',
3722
3897
    branch_format='bzrlib.branch.BzrBranchFormat5',
3723
3898
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
 
3899
    hidden=True,
3724
3900
    deprecated=True)
3725
3901
format_registry.register_metadir('knit',
3726
3902
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3727
3903
    'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
3728
3904
    branch_format='bzrlib.branch.BzrBranchFormat5',
3729
3905
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
 
3906
    hidden=True,
3730
3907
    deprecated=True)
3731
3908
format_registry.register_metadir('dirstate',
3732
3909
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3736
3913
    # this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
3737
3914
    # directly from workingtree_4 triggers a circular import.
3738
3915
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3916
    hidden=True,
3739
3917
    deprecated=True)
3740
3918
format_registry.register_metadir('dirstate-tags',
3741
3919
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3744
3922
        ' Incompatible with bzr < 0.15.',
3745
3923
    branch_format='bzrlib.branch.BzrBranchFormat6',
3746
3924
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3925
    hidden=True,
3747
3926
    deprecated=True)
3748
3927
format_registry.register_metadir('rich-root',
3749
3928
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
3751
3930
        ' bzr < 1.0.',
3752
3931
    branch_format='bzrlib.branch.BzrBranchFormat6',
3753
3932
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3933
    hidden=True,
3754
3934
    deprecated=True)
3755
3935
format_registry.register_metadir('dirstate-with-subtree',
3756
3936
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
3767
3947
    help='New in 0.92: Pack-based format with data compatible with '
3768
3948
        'dirstate-tags format repositories. Interoperates with '
3769
3949
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3770
 
        'Previously called knitpack-experimental.  '
3771
 
        'For more information, see '
3772
 
        'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
 
3950
        ,
3773
3951
    branch_format='bzrlib.branch.BzrBranchFormat6',
3774
3952
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3775
3953
    )
3778
3956
    help='New in 0.92: Pack-based format with data compatible with '
3779
3957
        'dirstate-with-subtree format repositories. Interoperates with '
3780
3958
        'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3781
 
        'Previously called knitpack-experimental.  '
3782
 
        'For more information, see '
3783
 
        'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
 
3959
        ,
3784
3960
    branch_format='bzrlib.branch.BzrBranchFormat6',
3785
3961
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3786
3962
    hidden=True,
3792
3968
         '(needed for bzr-svn and bzr-git).',
3793
3969
    branch_format='bzrlib.branch.BzrBranchFormat6',
3794
3970
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3971
    hidden=True,
3795
3972
    )
3796
3973
format_registry.register_metadir('1.6',
3797
3974
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3800
3977
         'not present locally.',
3801
3978
    branch_format='bzrlib.branch.BzrBranchFormat7',
3802
3979
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3980
    hidden=True,
3803
3981
    )
3804
3982
format_registry.register_metadir('1.6.1-rich-root',
3805
3983
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3807
3985
         '(needed for bzr-svn and bzr-git).',
3808
3986
    branch_format='bzrlib.branch.BzrBranchFormat7',
3809
3987
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3988
    hidden=True,
3810
3989
    )
3811
3990
format_registry.register_metadir('1.9',
3812
3991
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3815
3994
         'performance for most operations.',
3816
3995
    branch_format='bzrlib.branch.BzrBranchFormat7',
3817
3996
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3997
    hidden=True,
3818
3998
    )
3819
3999
format_registry.register_metadir('1.9-rich-root',
3820
4000
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3822
4002
         '(needed for bzr-svn and bzr-git).',
3823
4003
    branch_format='bzrlib.branch.BzrBranchFormat7',
3824
4004
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
4005
    hidden=True,
3825
4006
    )
3826
4007
format_registry.register_metadir('1.14',
3827
4008
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3843
4024
        'to and from rich-root-pack (and anything compatible with '
3844
4025
        'rich-root-pack) format repositories. Repositories and branches in '
3845
4026
        'this format can only be read by bzr.dev. Please read '
3846
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
4027
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3847
4028
        'before use.',
3848
4029
    branch_format='bzrlib.branch.BzrBranchFormat7',
3849
4030
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3850
4031
    experimental=True,
3851
4032
    alias=True,
 
4033
    hidden=True,
3852
4034
    )
3853
4035
format_registry.register_metadir('development-subtree',
3854
4036
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3856
4038
        'from pack-0.92-subtree (and anything compatible with '
3857
4039
        'pack-0.92-subtree) format repositories. Repositories and branches in '
3858
4040
        'this format can only be read by bzr.dev. Please read '
3859
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
4041
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3860
4042
        'before use.',
3861
4043
    branch_format='bzrlib.branch.BzrBranchFormat7',
3862
4044
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3863
4045
    experimental=True,
 
4046
    hidden=True,
3864
4047
    alias=False, # Restore to being an alias when an actual development subtree format is added
3865
4048
                 # This current non-alias status is simply because we did not introduce a
3866
4049
                 # chk based subtree format.
3871
4054
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3872
4055
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3873
4056
        'Please read '
3874
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
4057
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3875
4058
        'before use.',
3876
4059
    branch_format='bzrlib.branch.BzrBranchFormat7',
3877
4060
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3883
4066
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
3884
4067
    help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
3885
4068
        'rich roots. Please read '
3886
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
 
4069
        'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3887
4070
        'before use.',
3888
4071
    branch_format='bzrlib.branch.BzrBranchFormat7',
3889
4072
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3910
4093
    branch_format='bzrlib.branch.BzrBranchFormat7',
3911
4094
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3912
4095
    alias=True,
 
4096
    hidden=True,
3913
4097
    help='Same as 2a.')
3914
4098
 
3915
4099
# The current format that is made on 'bzr init'.