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
287
246
repo_format_name=repo_format_name,
288
247
make_working_trees=make_working_trees, shared_repo=want_shared)
289
248
if repo_format_name:
291
# If the result repository is in the same place as the
292
# resulting bzr dir, it will have no content, further if the
293
# result is not stacked then we know all content should be
294
# copied, and finally if we are copying up to a specific
295
# revision_id then we can use the pending-ancestry-result which
296
# 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
299
revision_id is not None):
300
fetch_spec = graph.PendingAncestryResult(
301
[revision_id], local_repo)
302
result_repo.fetch(local_repo, fetch_spec=fetch_spec)
304
result_repo.fetch(local_repo, revision_id=revision_id)
249
# If the result repository is in the same place as the resulting
250
# bzr dir, it will have no content, further if the result is not stacked
251
# then we know all content should be copied, and finally if we are
252
# copying up to a specific revision_id then we can use the
253
# pending-ancestry-result which does not require traversing all of
254
# history to describe it.
255
if (result_repo.bzrdir.root_transport.base ==
256
result.root_transport.base and not require_stacking and
257
revision_id is not None):
258
fetch_spec = graph.PendingAncestryResult(
259
[revision_id], local_repo)
260
result_repo.fetch(local_repo, fetch_spec=fetch_spec)
262
result_repo.fetch(local_repo, revision_id=revision_id)
308
if result_repo is not None:
309
raise AssertionError('result_repo not None(%r)' % result_repo)
310
265
# 1 if there is a branch present
311
266
# make sure its content is available in the target repository
414
360
except errors.NoRepositoryPresent:
417
return False, ([], repository)
418
return True, (bzrdir.list_branches(), None)
420
for branches, repo in BzrDir.find_bzrdirs(transport,
363
return False, (None, repository)
365
branch = bzrdir.open_branch()
366
except errors.NotBranchError:
367
return True, (None, None)
369
return True, (branch, None)
371
for branch, repo in BzrDir.find_bzrdirs(transport, evaluate=evaluate):
422
372
if repo is not None:
423
ret.extend(repo.find_branches())
424
if branches is not None:
373
branches.extend(repo.find_branches())
374
if branch is not None:
375
branches.append(branch)
428
378
def destroy_repository(self):
429
379
"""Destroy the repository in this BzrDir"""
430
380
raise NotImplementedError(self.destroy_repository)
432
def create_branch(self, name=None):
382
def create_branch(self):
433
383
"""Create a branch in this BzrDir.
435
:param name: Name of the colocated branch to create, None for
438
385
The bzrdir's format will control what branch format is created.
439
386
For more control see BranchFormatXX.create(a_bzrdir).
441
388
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
390
def destroy_branch(self):
391
"""Destroy the branch in this BzrDir"""
449
392
raise NotImplementedError(self.destroy_branch)
621
564
: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
566
pb = ui.ui_factory.nested_progress_bar()
634
568
# FIXME: bug 300001 -- the backup fails if the backup directory
635
569
# already exists, but it should instead either remove it or make
636
570
# a new backup directory.
572
# FIXME: bug 262450 -- the backup directory should have the same
573
# permissions as the .bzr directory (probably a bug in copy_tree)
638
574
old_path = self.root_transport.abspath('.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)
575
new_path = self.root_transport.abspath('backup.bzr')
576
pb.note('making backup of %s' % (old_path,))
577
pb.note(' to %s' % (new_path,))
578
self.root_transport.copy_tree('.bzr', 'backup.bzr')
642
579
return (old_path, new_path)
1373
1299
self.create_hook(hooks.HookPoint('pre_open',
1374
1300
"Invoked before attempting to open a BzrDir with the transport "
1375
1301
"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
1303
# install the default hooks
1383
1304
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
1307
class BzrDirPreSplitOut(BzrDir):
1423
1308
"""A common class for the all-in-one formats."""
1571
1451
format = BzrDirFormat.get_default_format()
1572
1452
return not isinstance(self._format, format.__class__)
1574
def open_branch(self, name=None, unsupported=False,
1575
ignore_fallbacks=False):
1454
def open_branch(self, unsupported=False, ignore_fallbacks=False):
1576
1455
"""See BzrDir.open_branch."""
1577
1456
from bzrlib.branch import BzrBranchFormat4
1578
1457
format = BzrBranchFormat4()
1579
1458
self._check_supported(format, unsupported)
1580
return format.open(self, name, _found=True)
1459
return format.open(self, _found=True)
1582
1461
def sprout(self, url, revision_id=None, force_new_repo=False,
1583
1462
possible_transports=None, accelerator_tree=None,
2511
2353
def set_branch_format(self, format):
2512
2354
self._branch_format = format
2514
def require_stacking(self, stack_on=None, possible_transports=None,
2516
"""We have a request to stack, try to ensure the formats support it.
2518
:param stack_on: If supplied, it is the URL to a branch that we want to
2519
stack on. Check to see if that format supports stacking before
2522
# Stacking is desired. requested by the target, but does the place it
2523
# points at support stacking? If it doesn't then we should
2524
# not implicitly upgrade. We check this here.
2525
new_repo_format = None
2526
new_branch_format = None
2528
# a bit of state for get_target_branch so that we don't try to open it
2529
# 2 times, for both repo *and* branch
2530
target = [None, False, None] # target_branch, checked, upgrade anyway
2531
def get_target_branch():
2533
# We've checked, don't check again
2535
if stack_on is None:
2536
# No target format, that means we want to force upgrading
2537
target[:] = [None, True, True]
2540
target_dir = BzrDir.open(stack_on,
2541
possible_transports=possible_transports)
2542
except errors.NotBranchError:
2543
# Nothing there, don't change formats
2544
target[:] = [None, True, False]
2546
except errors.JailBreak:
2547
# JailBreak, JFDI and upgrade anyway
2548
target[:] = [None, True, True]
2551
target_branch = target_dir.open_branch()
2552
except errors.NotBranchError:
2553
# No branch, don't upgrade formats
2554
target[:] = [None, True, False]
2556
target[:] = [target_branch, True, False]
2559
if (not _skip_repo and
2560
not self.repository_format.supports_external_lookups):
2561
# We need to upgrade the Repository.
2562
target_branch, _, do_upgrade = get_target_branch()
2563
if target_branch is None:
2564
# We don't have a target branch, should we upgrade anyway?
2566
# stack_on is inaccessible, JFDI.
2567
# TODO: bad monkey, hard-coded formats...
2568
if self.repository_format.rich_root_data:
2569
new_repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
2571
new_repo_format = pack_repo.RepositoryFormatKnitPack5()
2573
# If the target already supports stacking, then we know the
2574
# project is already able to use stacking, so auto-upgrade
2576
new_repo_format = target_branch.repository._format
2577
if not new_repo_format.supports_external_lookups:
2578
# target doesn't, source doesn't, so don't auto upgrade
2580
new_repo_format = None
2581
if new_repo_format is not None:
2582
self.repository_format = new_repo_format
2583
note('Source repository format does not support stacking,'
2584
' using format:\n %s',
2585
new_repo_format.get_format_description())
2356
def require_stacking(self):
2587
2357
if not self.get_branch_format().supports_stacking():
2588
# We just checked the repo, now lets check if we need to
2589
# upgrade the branch format
2590
target_branch, _, do_upgrade = get_target_branch()
2591
if target_branch is None:
2593
# TODO: bad monkey, hard-coded formats...
2594
new_branch_format = branch.BzrBranchFormat7()
2358
# We need to make a stacked branch, but the default format for the
2359
# target doesn't support stacking. So force a branch that *can*
2361
from bzrlib.branch import BzrBranchFormat7
2362
branch_format = BzrBranchFormat7()
2363
self.set_branch_format(branch_format)
2364
mutter("using %r for stacking" % (branch_format,))
2365
from bzrlib.repofmt import pack_repo
2366
if self.repository_format.rich_root_data:
2367
bzrdir_format_name = '1.6.1-rich-root'
2368
repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
2596
new_branch_format = target_branch._format
2597
if not new_branch_format.supports_stacking():
2598
new_branch_format = None
2599
if new_branch_format is not None:
2600
# Does support stacking, use its format.
2601
self.set_branch_format(new_branch_format)
2602
note('Source branch format does not support stacking,'
2603
' using format:\n %s',
2604
new_branch_format.get_format_description())
2370
bzrdir_format_name = '1.6'
2371
repo_format = pack_repo.RepositoryFormatKnitPack5()
2372
note('Source format does not support stacking, using format:'
2374
bzrdir_format_name, repo_format.get_format_description())
2375
self.repository_format = repo_format
2606
2377
def get_converter(self, format=None):
2607
2378
"""See BzrDirFormat.get_converter()."""
2727
2493
def convert(self, to_convert, pb):
2728
2494
"""See Converter.convert()."""
2729
2495
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)
2497
self.pb.note('starting upgrade from format 4 to 5')
2498
if isinstance(self.bzrdir.transport, local.LocalTransport):
2499
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2500
self._convert_to_weaves()
2501
return BzrDir.open(self.bzrdir.root_transport.base)
2742
2503
def _convert_to_weaves(self):
2743
ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2504
self.pb.note('note: upgrade may be faster if all store files are ungzipped first')
2745
2506
# TODO permissions
2746
2507
stat = self.bzrdir.transport.stat('weaves')
2984
2745
def convert(self, to_convert, pb):
2985
2746
"""See Converter.convert()."""
2986
2747
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)
2749
self.pb.note('starting upgrade from format 5 to 6')
2750
self._convert_to_prefixed()
2751
return BzrDir.open(self.bzrdir.root_transport.base)
2995
2753
def _convert_to_prefixed(self):
2996
2754
from bzrlib.store import TransportStore
2997
2755
self.bzrdir.transport.delete('branch-format')
2998
2756
for store_name in ["weaves", "revision-store"]:
2999
ui.ui_factory.note("adding prefixes to %s" % store_name)
2757
self.pb.note("adding prefixes to %s" % store_name)
3000
2758
store_transport = self.bzrdir.transport.clone(store_name)
3001
2759
store = TransportStore(store_transport, prefixed=True)
3002
2760
for urlfilename in store_transport.list_dir('.'):
3181
2942
while old != new:
3182
2943
if (old == _mod_branch.BzrBranchFormat5 and
3183
2944
new in (_mod_branch.BzrBranchFormat6,
3184
_mod_branch.BzrBranchFormat7,
3185
_mod_branch.BzrBranchFormat8)):
2945
_mod_branch.BzrBranchFormat7)):
3186
2946
branch_converter = _mod_branch.Converter5to6()
3187
2947
elif (old == _mod_branch.BzrBranchFormat6 and
3188
new in (_mod_branch.BzrBranchFormat7,
3189
_mod_branch.BzrBranchFormat8)):
2948
new == _mod_branch.BzrBranchFormat7):
3190
2949
branch_converter = _mod_branch.Converter6to7()
3191
elif (old == _mod_branch.BzrBranchFormat7 and
3192
new is _mod_branch.BzrBranchFormat8):
3193
branch_converter = _mod_branch.Converter7to8()
3195
raise errors.BadConversionTarget("No converter", new,
2951
raise errors.BadConversionTarget("No converter", new)
3197
2952
branch_converter.convert(branch)
3198
2953
branch = self.bzrdir.open_branch()
3199
2954
old = branch._format.__class__
3360
3100
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
3361
3101
make_working_trees=make_working_trees, shared_repo=shared_repo,
3363
return self._initialize_on_transport_ex_rpc(client, path, transport,
3364
use_existing_dir, create_prefix, force_new_repo, stacked_on,
3365
stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
3367
def _initialize_on_transport_ex_rpc(self, client, path, transport,
3368
use_existing_dir, create_prefix, force_new_repo, stacked_on,
3369
stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
3371
3104
args.append(self._serialize_NoneTrueFalse(use_existing_dir))
3372
3105
args.append(self._serialize_NoneTrueFalse(create_prefix))
3384
3117
args.append(self._serialize_NoneString(repo_format_name))
3385
3118
args.append(self._serialize_NoneTrueFalse(make_working_trees))
3386
3119
args.append(self._serialize_NoneTrueFalse(shared_repo))
3387
request_network_name = self._network_name or \
3120
if self._network_name is None:
3121
self._network_name = \
3388
3122
BzrDirFormat.get_default_format().network_name()
3390
response = client.call('BzrDirFormat.initialize_ex_1.16',
3391
request_network_name, path, *args)
3124
response = client.call('BzrDirFormat.initialize_ex',
3125
self.network_name(), path, *args)
3392
3126
except errors.UnknownSmartMethod:
3393
client._medium._remember_remote_is_before((1,16))
3394
3127
local_dir_format = BzrDirMetaFormat1()
3395
3128
self._supply_sub_formats_to(local_dir_format)
3396
3129
return local_dir_format.initialize_on_transport_ex(transport,
3422
3153
repo_bzr = bzrdir
3423
3154
final_stack = response[8] or None
3424
3155
final_stack_pwd = response[9] or None
3426
final_stack_pwd = urlutils.join(
3427
transport.base, final_stack_pwd)
3428
3156
remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
3429
if len(response) > 10:
3430
# Updated server verb that locks remotely.
3431
repo_lock_token = response[10] or None
3432
remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
3434
remote_repo.dont_leave_lock_in_place()
3436
remote_repo.lock_write()
3437
3157
policy = UseExistingRepository(remote_repo, final_stack,
3438
3158
final_stack_pwd, require_stacking)
3439
3159
policy.acquire_repository()
3441
3161
remote_repo = None
3443
bzrdir._format.set_branch_format(self.get_branch_format())
3444
if require_stacking:
3445
# The repo has already been created, but we need to make sure that
3446
# we'll make a stackable branch.
3447
bzrdir._format.require_stacking(_skip_repo=True)
3448
3163
return remote_repo, bzrdir, require_stacking, policy
3450
3165
def _open(self, transport):
3788
3498
stack_on = self._get_full_stack_on()
3500
# Stacking is desired. requested by the target, but does the place it
3501
# points at support stacking? If it doesn't then we should
3502
# not implicitly upgrade. We check this here.
3790
3503
format = self._bzrdir._format
3791
format.require_stacking(stack_on=stack_on,
3792
possible_transports=[self._bzrdir.root_transport])
3504
if not (format.repository_format.supports_external_lookups
3505
and format.get_branch_format().supports_stacking()):
3506
# May need to upgrade - but only do if the target also
3507
# supports stacking. Note that this currently wastes
3508
# network round trips to check - but we only do this
3509
# when the source can't stack so it will fade away
3510
# as people do upgrade.
3511
branch_format = None
3514
target_dir = BzrDir.open(stack_on,
3515
possible_transports=[self._bzrdir.root_transport])
3516
except errors.NotBranchError:
3517
# Nothing there, don't change formats
3519
except errors.JailBreak:
3520
# stack_on is inaccessible, JFDI.
3521
if format.repository_format.rich_root_data:
3522
repo_format = pack_repo.RepositoryFormatKnitPack6RichRoot()
3524
repo_format = pack_repo.RepositoryFormatKnitPack6()
3525
branch_format = branch.BzrBranchFormat7()
3528
target_branch = target_dir.open_branch()
3529
except errors.NotBranchError:
3530
# No branch, don't change formats
3533
branch_format = target_branch._format
3534
repo_format = target_branch.repository._format
3535
if not (branch_format.supports_stacking()
3536
and repo_format.supports_external_lookups):
3537
# Doesn't stack itself, don't force an upgrade
3538
branch_format = None
3540
if branch_format and repo_format:
3541
# Does support stacking, use its format.
3542
format.repository_format = repo_format
3543
format.set_branch_format(branch_format)
3544
note('Source format does not support stacking, '
3545
'using format: \'%s\'\n %s\n',
3546
branch_format.get_format_description(),
3547
repo_format.get_format_description())
3793
3548
if not self._require_stacking:
3794
3549
# We have picked up automatic stacking somewhere.
3795
3550
note('Using default stacking branch %s at %s', self._stack_on,
3838
3593
format_registry.register('weave', BzrDirFormat6,
3839
3594
'Pre-0.8 format. Slower than knit and does not'
3840
3595
' support checkouts or shared repositories.',
3842
3596
deprecated=True)
3843
3597
format_registry.register_metadir('metaweave',
3844
3598
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3845
3599
'Transitional format in 0.8. Slower than knit.',
3846
3600
branch_format='bzrlib.branch.BzrBranchFormat5',
3847
3601
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3849
3602
deprecated=True)
3850
3603
format_registry.register_metadir('knit',
3851
3604
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3852
3605
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
3853
3606
branch_format='bzrlib.branch.BzrBranchFormat5',
3854
3607
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3856
3608
deprecated=True)
3857
3609
format_registry.register_metadir('dirstate',
3858
3610
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
4003
3749
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
4004
3750
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 '
4008
branch_format='bzrlib.branch.BzrBranchFormat7',
4009
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
4014
format_registry.register_metadir('development7-rich-root',
4015
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
4016
help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
4017
'rich roots. Please read '
4018
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
4020
branch_format='bzrlib.branch.BzrBranchFormat7',
4021
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
4026
format_registry.register_metadir('2a',
4027
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
4028
help='First format for bzr 2.0 series.\n'
4029
'Uses group-compress storage.\n'
4030
'Provides rich roots which are a one-way transition.\n',
4031
# 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
4032
# 'rich roots. Supported by bzr 1.16 and later.',
4033
branch_format='bzrlib.branch.BzrBranchFormat7',
4034
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3752
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3754
branch_format='bzrlib.branch.BzrBranchFormat7',
3755
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
4035
3757
experimental=True,
4038
3760
# The following format should be an alias for the rich root equivalent
4039
3761
# of the default format
4040
3762
format_registry.register_metadir('default-rich-root',
4041
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
4042
branch_format='bzrlib.branch.BzrBranchFormat7',
4043
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3763
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3764
help='Default format, rich root variant. (needed for bzr-svn and bzr-git).',
3765
branch_format='bzrlib.branch.BzrBranchFormat6',
3766
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
4048
3769
# The current format that is made on 'bzr init'.
4049
format_registry.set_default('2a')
3770
format_registry.set_default('pack-0.92')