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
2498
def convert(self, to_convert, pb):
2728
2499
"""See Converter.convert()."""
2729
2500
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)
2502
self.pb.note('starting upgrade from format 4 to 5')
2503
if isinstance(self.bzrdir.transport, local.LocalTransport):
2504
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2505
self._convert_to_weaves()
2506
return BzrDir.open(self.bzrdir.root_transport.base)
2742
2508
def _convert_to_weaves(self):
2743
ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2509
self.pb.note('note: upgrade may be faster if all store files are ungzipped first')
2745
2511
# TODO permissions
2746
2512
stat = self.bzrdir.transport.stat('weaves')
2984
2750
def convert(self, to_convert, pb):
2985
2751
"""See Converter.convert()."""
2986
2752
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)
2754
self.pb.note('starting upgrade from format 5 to 6')
2755
self._convert_to_prefixed()
2756
return BzrDir.open(self.bzrdir.root_transport.base)
2995
2758
def _convert_to_prefixed(self):
2996
2759
from bzrlib.store import TransportStore
2997
2760
self.bzrdir.transport.delete('branch-format')
2998
2761
for store_name in ["weaves", "revision-store"]:
2999
ui.ui_factory.note("adding prefixes to %s" % store_name)
2762
self.pb.note("adding prefixes to %s" % store_name)
3000
2763
store_transport = self.bzrdir.transport.clone(store_name)
3001
2764
store = TransportStore(store_transport, prefixed=True)
3002
2765
for urlfilename in store_transport.list_dir('.'):
3360
3110
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
3361
3111
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
3114
args.append(self._serialize_NoneTrueFalse(use_existing_dir))
3372
3115
args.append(self._serialize_NoneTrueFalse(create_prefix))
3384
3127
args.append(self._serialize_NoneString(repo_format_name))
3385
3128
args.append(self._serialize_NoneTrueFalse(make_working_trees))
3386
3129
args.append(self._serialize_NoneTrueFalse(shared_repo))
3387
request_network_name = self._network_name or \
3130
if self._network_name is None:
3131
self._network_name = \
3388
3132
BzrDirFormat.get_default_format().network_name()
3390
response = client.call('BzrDirFormat.initialize_ex_1.16',
3391
request_network_name, path, *args)
3134
response = client.call('BzrDirFormat.initialize_ex',
3135
self.network_name(), path, *args)
3392
3136
except errors.UnknownSmartMethod:
3393
client._medium._remember_remote_is_before((1,16))
3394
3137
local_dir_format = BzrDirMetaFormat1()
3395
3138
self._supply_sub_formats_to(local_dir_format)
3396
3139
return local_dir_format.initialize_on_transport_ex(transport,
3422
3163
repo_bzr = bzrdir
3423
3164
final_stack = response[8] or None
3424
3165
final_stack_pwd = response[9] or None
3426
final_stack_pwd = urlutils.join(
3427
transport.base, final_stack_pwd)
3428
3166
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
3167
policy = UseExistingRepository(remote_repo, final_stack,
3438
3168
final_stack_pwd, require_stacking)
3439
3169
policy.acquire_repository()
3441
3171
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
3173
return remote_repo, bzrdir, require_stacking, policy
3450
3175
def _open(self, transport):
3788
3508
stack_on = self._get_full_stack_on()
3510
# Stacking is desired. requested by the target, but does the place it
3511
# points at support stacking? If it doesn't then we should
3512
# not implicitly upgrade. We check this here.
3790
3513
format = self._bzrdir._format
3791
format.require_stacking(stack_on=stack_on,
3792
possible_transports=[self._bzrdir.root_transport])
3514
if not (format.repository_format.supports_external_lookups
3515
and format.get_branch_format().supports_stacking()):
3516
# May need to upgrade - but only do if the target also
3517
# supports stacking. Note that this currently wastes
3518
# network round trips to check - but we only do this
3519
# when the source can't stack so it will fade away
3520
# as people do upgrade.
3521
branch_format = None
3524
target_dir = BzrDir.open(stack_on,
3525
possible_transports=[self._bzrdir.root_transport])
3526
except errors.NotBranchError:
3527
# Nothing there, don't change formats
3529
except errors.JailBreak:
3530
# stack_on is inaccessible, JFDI.
3531
if format.repository_format.rich_root_data:
3532
repo_format = pack_repo.RepositoryFormatKnitPack6RichRoot()
3534
repo_format = pack_repo.RepositoryFormatKnitPack6()
3535
branch_format = branch.BzrBranchFormat7()
3538
target_branch = target_dir.open_branch()
3539
except errors.NotBranchError:
3540
# No branch, don't change formats
3543
branch_format = target_branch._format
3544
repo_format = target_branch.repository._format
3545
if not (branch_format.supports_stacking()
3546
and repo_format.supports_external_lookups):
3547
# Doesn't stack itself, don't force an upgrade
3548
branch_format = None
3550
if branch_format and repo_format:
3551
# Does support stacking, use its format.
3552
format.repository_format = repo_format
3553
format.set_branch_format(branch_format)
3554
note('Source format does not support stacking, '
3555
'using format: \'%s\'\n %s\n',
3556
branch_format.get_format_description(),
3557
repo_format.get_format_description())
3793
3558
if not self._require_stacking:
3794
3559
# We have picked up automatic stacking somewhere.
3795
3560
note('Using default stacking branch %s at %s', self._stack_on,
3838
3603
format_registry.register('weave', BzrDirFormat6,
3839
3604
'Pre-0.8 format. Slower than knit and does not'
3840
3605
' support checkouts or shared repositories.',
3842
3606
deprecated=True)
3843
3607
format_registry.register_metadir('metaweave',
3844
3608
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3845
3609
'Transitional format in 0.8. Slower than knit.',
3846
3610
branch_format='bzrlib.branch.BzrBranchFormat5',
3847
3611
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3849
3612
deprecated=True)
3850
3613
format_registry.register_metadir('knit',
3851
3614
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3852
3615
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
3853
3616
branch_format='bzrlib.branch.BzrBranchFormat5',
3854
3617
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3856
3618
deprecated=True)
3857
3619
format_registry.register_metadir('dirstate',
3858
3620
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
4003
3759
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
4004
3760
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',
3762
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3764
branch_format='bzrlib.branch.BzrBranchFormat7',
3765
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
4035
3767
experimental=True,
4038
3770
# The following format should be an alias for the rich root equivalent
4039
3771
# of the default format
4040
3772
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',
3773
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3774
help='Default format, rich root variant. (needed for bzr-svn and bzr-git).',
3775
branch_format='bzrlib.branch.BzrBranchFormat6',
3776
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
4048
3779
# The current format that is made on 'bzr init'.
4049
format_registry.set_default('2a')
3780
format_registry.set_default('pack-0.92')