91
class ControlComponent(object):
92
"""Abstract base class for control directory components.
94
This provides interfaces that are common across bzrdirs,
95
repositories, branches, and workingtree control directories.
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
103
This can be used as a mixin and is intended to fit with
108
def control_transport(self):
109
raise NotImplementedError
112
def control_url(self):
113
return self.control_transport.base
116
def user_transport(self):
117
raise NotImplementedError
121
return self.user_transport.base
124
class BzrDir(ControlComponent):
125
91
"""A .bzr control diretory.
127
93
BzrDir instances let you create or open any of the things that can be
294
260
# copied, and finally if we are copying up to a specific
295
261
# revision_id then we can use the pending-ancestry-result which
296
262
# 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
263
if (result_repo.bzrdir.root_transport.base ==
264
result.root_transport.base and not require_stacking and
299
265
revision_id is not None):
300
266
fetch_spec = graph.PendingAncestryResult(
301
267
[revision_id], local_repo)
388
354
for subdir in sorted(subdirs, reverse=True):
389
355
pending.append(current_transport.clone(subdir))
391
def list_branches(self):
392
"""Return a sequence of all branches local to this control directory.
396
return [self.open_branch()]
397
except errors.NotBranchError:
401
358
def find_branches(transport):
402
359
"""Find all branches under a transport.
414
371
except errors.NoRepositoryPresent:
417
return False, ([], repository)
418
return True, (bzrdir.list_branches(), None)
420
for branches, repo in BzrDir.find_bzrdirs(transport,
374
return False, (None, repository)
376
branch = bzrdir.open_branch()
377
except errors.NotBranchError:
378
return True, (None, None)
380
return True, (branch, None)
382
for branch, repo in BzrDir.find_bzrdirs(transport, evaluate=evaluate):
422
383
if repo is not None:
423
ret.extend(repo.find_branches())
424
if branches is not None:
384
branches.extend(repo.find_branches())
385
if branch is not None:
386
branches.append(branch)
428
389
def destroy_repository(self):
429
390
"""Destroy the repository in this BzrDir"""
430
391
raise NotImplementedError(self.destroy_repository)
432
def create_branch(self, name=None):
393
def create_branch(self):
433
394
"""Create a branch in this BzrDir.
435
:param name: Name of the colocated branch to create, None for
438
396
The bzrdir's format will control what branch format is created.
439
397
For more control see BranchFormatXX.create(a_bzrdir).
441
399
raise NotImplementedError(self.create_branch)
443
def destroy_branch(self, name=None):
444
"""Destroy a branch in this BzrDir.
446
:param name: Name of the branch to destroy, None for the default
401
def destroy_branch(self):
402
"""Destroy the branch in this BzrDir"""
449
403
raise NotImplementedError(self.destroy_branch)
499
453
except errors.NoRepositoryPresent:
500
454
repository = None
502
if (found_bzrdir.user_url != self.user_url
503
and not repository.is_shared()):
456
if ((found_bzrdir.root_transport.base !=
457
self.root_transport.base) and not repository.is_shared()):
504
458
# Don't look higher, can't use a higher shared repo.
505
459
repository = None
621
575
:return: Tuple with old path name and new path name
623
def name_gen(base='backup.bzr'):
625
name = "%s.~%d~" % (base, counter)
626
while self.root_transport.has(name):
628
name = "%s.~%d~" % (base, counter)
631
backup_dir=name_gen()
632
577
pb = ui.ui_factory.nested_progress_bar()
634
579
# FIXME: bug 300001 -- the backup fails if the backup directory
636
581
# a new backup directory.
638
583
old_path = self.root_transport.abspath('.bzr')
639
new_path = self.root_transport.abspath(backup_dir)
584
new_path = self.root_transport.abspath('backup.bzr')
640
585
ui.ui_factory.note('making backup of %s\n to %s' % (old_path, new_path,))
641
self.root_transport.copy_tree('.bzr', backup_dir)
586
self.root_transport.copy_tree('.bzr', 'backup.bzr')
642
587
return (old_path, new_path)
704
649
next_transport = found_bzrdir.root_transport.clone('..')
705
if (found_bzrdir.user_url == next_transport.base):
650
if (found_bzrdir.root_transport.base == next_transport.base):
706
651
# top of the file system
708
653
# find the next containing bzrdir
725
670
repository = found_bzrdir.open_repository()
726
671
except errors.NoRepositoryPresent:
727
672
return None, False
728
if found_bzrdir.user_url == self.user_url:
673
if found_bzrdir.root_transport.base == self.root_transport.base:
729
674
return repository, True
730
675
elif repository.is_shared():
731
676
return repository, True
749
def get_branch_transport(self, branch_format, name=None):
694
def get_branch_transport(self, branch_format):
750
695
"""Get the transport for use by branch format in this BzrDir.
752
697
Note that bzr dirs that do not support format strings will raise
847
792
:param _transport: the transport this dir is based at.
849
794
self._format = _format
850
# these are also under the more standard names of
851
# control_transport and user_transport
852
795
self.transport = _transport.clone('.bzr')
853
796
self.root_transport = _transport
854
797
self._mode_check_done = False
857
def user_transport(self):
858
return self.root_transport
861
def control_transport(self):
862
return self.transport
864
799
def is_control_filename(self, filename):
865
800
"""True if filename is the name of a path which is reserved for bzrdir's.
940
875
BzrDir._check_supported(format, _unsupported)
941
876
return format.open(transport, _found=True)
943
def open_branch(self, name=None, unsupported=False,
944
ignore_fallbacks=False):
878
def open_branch(self, unsupported=False, ignore_fallbacks=False):
945
879
"""Open the branch object at this BzrDir if one is present.
947
881
If unsupported is True, then no longer supported branch formats can
1086
1020
raise NotImplementedError(self.open_workingtree)
1088
def has_branch(self, name=None):
1022
def has_branch(self):
1089
1023
"""Tell if this bzrdir contains a branch.
1091
1025
Note: if you're going to open the branch, you should just go ahead
1373
1307
self.create_hook(hooks.HookPoint('pre_open',
1374
1308
"Invoked before attempting to open a BzrDir with the transport "
1375
1309
"that the open will use.", (1, 14), None))
1376
self.create_hook(hooks.HookPoint('post_repo_init',
1377
"Invoked after a repository has been initialized. "
1378
"post_repo_init is called with a "
1379
"bzrlib.bzrdir.RepoInitHookParams.",
1382
1311
# install the default hooks
1383
1312
BzrDir.hooks = BzrDirHooks()
1386
class RepoInitHookParams(object):
1387
"""Object holding parameters passed to *_repo_init hooks.
1389
There are 4 fields that hooks may wish to access:
1391
:ivar repository: Repository created
1392
:ivar format: Repository format
1393
:ivar bzrdir: The bzrdir for the repository
1394
:ivar shared: The repository is shared
1397
def __init__(self, repository, format, a_bzrdir, shared):
1398
"""Create a group of RepoInitHook parameters.
1400
:param repository: Repository created
1401
:param format: Repository format
1402
:param bzrdir: The bzrdir for the repository
1403
:param shared: The repository is shared
1405
self.repository = repository
1406
self.format = format
1407
self.bzrdir = a_bzrdir
1408
self.shared = shared
1410
def __eq__(self, other):
1411
return self.__dict__ == other.__dict__
1415
return "<%s for %s>" % (self.__class__.__name__,
1418
return "<%s for %s>" % (self.__class__.__name__,
1422
1315
class BzrDirPreSplitOut(BzrDir):
1423
1316
"""A common class for the all-in-one formats."""
1463
1356
tree.clone(result)
1466
def create_branch(self, name=None):
1359
def create_branch(self):
1467
1360
"""See BzrDir.create_branch."""
1468
return self._format.get_branch_format().initialize(self, name=name)
1361
return self._format.get_branch_format().initialize(self)
1470
def destroy_branch(self, name=None):
1363
def destroy_branch(self):
1471
1364
"""See BzrDir.destroy_branch."""
1472
1365
raise errors.UnsupportedOperation(self.destroy_branch, self)
1529
1422
raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1532
def get_branch_transport(self, branch_format, name=None):
1425
def get_branch_transport(self, branch_format):
1533
1426
"""See BzrDir.get_branch_transport()."""
1534
if name is not None:
1535
raise errors.NoColocatedBranchSupport(self)
1536
1427
if branch_format is None:
1537
1428
return self.transport
1571
1462
format = BzrDirFormat.get_default_format()
1572
1463
return not isinstance(self._format, format.__class__)
1574
def open_branch(self, name=None, unsupported=False,
1575
ignore_fallbacks=False):
1465
def open_branch(self, unsupported=False, ignore_fallbacks=False):
1576
1466
"""See BzrDir.open_branch."""
1577
1467
from bzrlib.branch import BzrBranchFormat4
1578
1468
format = BzrBranchFormat4()
1579
1469
self._check_supported(format, unsupported)
1580
return format.open(self, name, _found=True)
1470
return format.open(self, _found=True)
1582
1472
def sprout(self, url, revision_id=None, force_new_repo=False,
1583
1473
possible_transports=None, accelerator_tree=None,
1700
1590
"""See BzrDir.can_convert_format()."""
1703
def create_branch(self, name=None):
1593
def create_branch(self):
1704
1594
"""See BzrDir.create_branch."""
1705
return self._format.get_branch_format().initialize(self, name=name)
1595
return self._format.get_branch_format().initialize(self)
1707
def destroy_branch(self, name=None):
1597
def destroy_branch(self):
1708
1598
"""See BzrDir.create_branch."""
1709
if name is not None:
1710
raise errors.NoColocatedBranchSupport(self)
1711
1599
self.transport.delete_tree('branch')
1713
1601
def create_repository(self, shared=False):
1756
1644
format = BranchFormat.find_format(self)
1757
1645
return format.get_reference(self)
1759
def get_branch_transport(self, branch_format, name=None):
1647
def get_branch_transport(self, branch_format):
1760
1648
"""See BzrDir.get_branch_transport()."""
1761
if name is not None:
1762
raise errors.NoColocatedBranchSupport(self)
1763
1649
# XXX: this shouldn't implicitly create the directory if it's just
1764
1650
# promising to get a transport -- mbp 20090727
1765
1651
if branch_format is None:
1837
1723
except errors.NoRepositoryPresent:
1839
for branch in self.list_branches():
1840
if not isinstance(branch._format,
1726
if not isinstance(self.open_branch()._format,
1841
1727
format.get_branch_format().__class__):
1842
1728
# the branch needs an upgrade.
1730
except errors.NotBranchError:
1845
1733
my_wt = self.open_workingtree(recommend_upgrade=False)
1846
1734
if not isinstance(my_wt._format,
1854
def open_branch(self, name=None, unsupported=False,
1855
ignore_fallbacks=False):
1742
def open_branch(self, unsupported=False, ignore_fallbacks=False):
1856
1743
"""See BzrDir.open_branch."""
1857
1744
format = self.find_branch_format()
1858
1745
self._check_supported(format, unsupported)
1859
return format.open(self, name=name,
1860
_found=True, ignore_fallbacks=ignore_fallbacks)
1746
return format.open(self, _found=True, ignore_fallbacks=ignore_fallbacks)
1862
1748
def open_repository(self, unsupported=False):
1863
1749
"""See BzrDir.open_repository."""
1895
1781
Once a format is deprecated, just deprecate the initialize and open
1896
1782
methods on the format class. Do not deprecate the object, as the
1897
1783
object will be created every system load.
1899
:cvar colocated_branches: Whether this formats supports colocated branches.
1902
1786
_default_format = None
1920
1804
_lock_file_name = 'branch-lock'
1922
colocated_branches = False
1923
"""Whether co-located branches are supported for this control dir format.
1926
1806
# _lock_class must be set in subclasses to the lock type, typ.
1927
1807
# TransportLock or LockDir
2727
2607
def convert(self, to_convert, pb):
2728
2608
"""See Converter.convert()."""
2729
2609
self.bzrdir = to_convert
2731
warnings.warn("pb parameter to convert() is deprecated")
2732
self.pb = ui.ui_factory.nested_progress_bar()
2734
ui.ui_factory.note('starting upgrade from format 4 to 5')
2735
if isinstance(self.bzrdir.transport, local.LocalTransport):
2736
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2737
self._convert_to_weaves()
2738
return BzrDir.open(self.bzrdir.user_url)
2611
ui.ui_factory.note('starting upgrade from format 4 to 5')
2612
if isinstance(self.bzrdir.transport, local.LocalTransport):
2613
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2614
self._convert_to_weaves()
2615
return BzrDir.open(self.bzrdir.root_transport.base)
2742
2617
def _convert_to_weaves(self):
2743
2618
ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2984
2859
def convert(self, to_convert, pb):
2985
2860
"""See Converter.convert()."""
2986
2861
self.bzrdir = to_convert
2987
pb = ui.ui_factory.nested_progress_bar()
2989
ui.ui_factory.note('starting upgrade from format 5 to 6')
2990
self._convert_to_prefixed()
2991
return BzrDir.open(self.bzrdir.user_url)
2863
ui.ui_factory.note('starting upgrade from format 5 to 6')
2864
self._convert_to_prefixed()
2865
return BzrDir.open(self.bzrdir.root_transport.base)
2995
2867
def _convert_to_prefixed(self):
2996
2868
from bzrlib.store import TransportStore
3029
2901
from bzrlib.repofmt.weaverepo import RepositoryFormat7
3030
2902
from bzrlib.branch import BzrBranchFormat5
3031
2903
self.bzrdir = to_convert
3032
self.pb = ui.ui_factory.nested_progress_bar()
3034
2906
self.total = 20 # the steps we know about
3035
2907
self.garbage_inventories = []
3115
2987
'branch-format',
3116
2988
BzrDirMetaFormat1().get_format_string(),
3117
2989
mode=self.file_mode)
3119
return BzrDir.open(self.bzrdir.user_url)
2990
return BzrDir.open(self.bzrdir.root_transport.base)
3121
2992
def make_lock(self, name):
3122
2993
"""Make a lock for the new control dir name."""
3157
3028
def convert(self, to_convert, pb):
3158
3029
"""See Converter.convert()."""
3159
3030
self.bzrdir = to_convert
3160
self.pb = ui.ui_factory.nested_progress_bar()
3163
3034
self.step('checking repository format')
3171
3042
ui.ui_factory.note('starting repository conversion')
3172
3043
converter = CopyConverter(self.target_format.repository_format)
3173
3044
converter.convert(repo, pb)
3174
for branch in self.bzrdir.list_branches():
3046
branch = self.bzrdir.open_branch()
3047
except errors.NotBranchError:
3175
3050
# TODO: conversions of Branch and Tree should be done by
3176
3051
# InterXFormat lookups/some sort of registry.
3177
3052
# Avoid circular imports
3704
3578
stack_on = urlutils.rebase_url(self._stack_on,
3705
3579
self._stack_on_pwd,
3580
branch.bzrdir.root_transport.base)
3707
3581
except errors.InvalidRebaseURLs:
3708
3582
stack_on = self._get_full_stack_on()
3896
3770
help='New in 0.92: Pack-based format with data compatible with '
3897
3771
'dirstate-tags format repositories. Interoperates with '
3898
3772
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3773
'Previously called knitpack-experimental. '
3774
'For more information, see '
3775
'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
3900
3776
branch_format='bzrlib.branch.BzrBranchFormat6',
3901
3777
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3905
3781
help='New in 0.92: Pack-based format with data compatible with '
3906
3782
'dirstate-with-subtree format repositories. Interoperates with '
3907
3783
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3784
'Previously called knitpack-experimental. '
3785
'For more information, see '
3786
'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
3909
3787
branch_format='bzrlib.branch.BzrBranchFormat6',
3910
3788
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3973
3851
'to and from rich-root-pack (and anything compatible with '
3974
3852
'rich-root-pack) format repositories. Repositories and branches in '
3975
3853
'this format can only be read by bzr.dev. Please read '
3976
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3854
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3978
3856
branch_format='bzrlib.branch.BzrBranchFormat7',
3979
3857
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3987
3865
'from pack-0.92-subtree (and anything compatible with '
3988
3866
'pack-0.92-subtree) format repositories. Repositories and branches in '
3989
3867
'this format can only be read by bzr.dev. Please read '
3990
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3868
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3992
3870
branch_format='bzrlib.branch.BzrBranchFormat7',
3993
3871
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
4003
3881
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
4004
3882
help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
4006
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3884
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
4008
3886
branch_format='bzrlib.branch.BzrBranchFormat7',
4009
3887
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
4015
3893
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
4016
3894
help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
4017
3895
'rich roots. Please read '
4018
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3896
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
4020
3898
branch_format='bzrlib.branch.BzrBranchFormat7',
4021
3899
tree_format='bzrlib.workingtree.WorkingTreeFormat6',