390
495
policy = self.determine_repository_policy(force_new_repo)
391
496
return policy.acquire_repository()[0]
393
def _find_source_repo(self, add_cleanup, source_branch):
394
"""Find the source branch and repo for a sprout operation.
396
This is helper intended for use by _sprout.
398
:returns: (source_branch, source_repository). Either or both may be
399
None. If not None, they will be read-locked (and their unlock(s)
400
scheduled via the add_cleanup param).
402
if source_branch is not None:
403
add_cleanup(source_branch.lock_read().unlock)
404
return source_branch, source_branch.repository
406
source_branch = self.open_branch()
407
source_repository = source_branch.repository
408
except errors.NotBranchError:
411
source_repository = self.open_repository()
412
except errors.NoRepositoryPresent:
413
source_repository = None
415
add_cleanup(source_repository.lock_read().unlock)
417
add_cleanup(source_branch.lock_read().unlock)
418
return source_branch, source_repository
420
def sprout(self, url, revision_id=None, force_new_repo=False,
421
recurse='down', possible_transports=None,
422
accelerator_tree=None, hardlink=False, stacked=False,
423
source_branch=None, create_tree_if_local=True):
424
"""Create a copy of this controldir prepared for use as a new line of
427
If url's last component does not exist, it will be created.
429
Attributes related to the identity of the source branch like
430
branch nickname will be cleaned, a working tree is created
431
whether one existed before or not; and a local branch is always
434
if revision_id is not None, then the clone operation may tune
435
itself to download less data.
437
:param accelerator_tree: A tree which can be used for retrieving file
438
contents more quickly than the revision tree, i.e. a workingtree.
439
The revision tree will be used for cases where accelerator_tree's
440
content is different.
441
:param hardlink: If true, hard-link files from accelerator_tree,
443
:param stacked: If true, create a stacked branch referring to the
444
location of this control directory.
445
:param create_tree_if_local: If true, a working-tree will be created
446
when working locally.
448
operation = cleanup.OperationWithCleanups(self._sprout)
449
return operation.run(url, revision_id=revision_id,
450
force_new_repo=force_new_repo, recurse=recurse,
451
possible_transports=possible_transports,
452
accelerator_tree=accelerator_tree, hardlink=hardlink,
453
stacked=stacked, source_branch=source_branch,
454
create_tree_if_local=create_tree_if_local)
456
def _sprout(self, op, url, revision_id=None, force_new_repo=False,
457
recurse='down', possible_transports=None,
458
accelerator_tree=None, hardlink=False, stacked=False,
459
source_branch=None, create_tree_if_local=True):
460
add_cleanup = op.add_cleanup
461
fetch_spec_factory = fetch.FetchSpecFactory()
462
if revision_id is not None:
463
fetch_spec_factory.add_revision_ids([revision_id])
464
fetch_spec_factory.source_branch_stop_revision_id = revision_id
465
target_transport = _mod_transport.get_transport(url,
467
target_transport.ensure_base()
468
cloning_format = self.cloning_metadir(stacked)
469
# Create/update the result branch
470
result = cloning_format.initialize_on_transport(target_transport)
471
source_branch, source_repository = self._find_source_repo(
472
add_cleanup, source_branch)
473
fetch_spec_factory.source_branch = source_branch
474
# if a stacked branch wasn't requested, we don't create one
475
# even if the origin was stacked
476
if stacked and source_branch is not None:
477
stacked_branch_url = self.root_transport.base
479
stacked_branch_url = None
480
repository_policy = result.determine_repository_policy(
481
force_new_repo, stacked_branch_url, require_stacking=stacked)
482
result_repo, is_new_repo = repository_policy.acquire_repository()
483
add_cleanup(result_repo.lock_write().unlock)
484
fetch_spec_factory.source_repo = source_repository
485
fetch_spec_factory.target_repo = result_repo
486
if stacked or (len(result_repo._fallback_repositories) != 0):
487
target_repo_kind = fetch.TargetRepoKinds.STACKED
489
target_repo_kind = fetch.TargetRepoKinds.EMPTY
491
target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
492
fetch_spec_factory.target_repo_kind = target_repo_kind
493
if source_repository is not None:
494
fetch_spec = fetch_spec_factory.make_fetch_spec()
495
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
497
if source_branch is None:
498
# this is for sprouting a controldir without a branch; is that
500
# Not especially, but it's part of the contract.
501
result_branch = result.create_branch()
503
result_branch = source_branch.sprout(result,
504
revision_id=revision_id, repository_policy=repository_policy,
505
repository=result_repo)
506
mutter("created new branch %r" % (result_branch,))
508
# Create/update the result working tree
509
if (create_tree_if_local and
510
isinstance(target_transport, local.LocalTransport) and
511
(result_repo is None or result_repo.make_working_trees())):
512
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
513
hardlink=hardlink, from_branch=result_branch)
516
if wt.path2id('') is None:
518
wt.set_root_id(self.open_workingtree.get_root_id())
519
except errors.NoWorkingTree:
525
if recurse == 'down':
528
basis = wt.basis_tree()
529
elif result_branch is not None:
530
basis = result_branch.basis_tree()
531
elif source_branch is not None:
532
basis = source_branch.basis_tree()
533
if basis is not None:
534
add_cleanup(basis.lock_read().unlock)
535
subtrees = basis.iter_references()
538
for path, file_id in subtrees:
539
target = urlutils.join(url, urlutils.escape(path))
540
sublocation = source_branch.reference_parent(file_id, path)
541
sublocation.bzrdir.sprout(target,
542
basis.get_reference_revision(file_id, path),
543
force_new_repo=force_new_repo, recurse=recurse,
548
499
def create_branch_convenience(base, force_new_repo=False,
549
500
force_new_tree=None, format=None,
1020
1128
format.require_stacking()
1024
def create(cls, base, format=None, possible_transports=None):
1025
"""Create a new BzrDir at the url 'base'.
1027
:param format: If supplied, the format of branch to create. If not
1028
supplied, the default is used.
1029
:param possible_transports: If supplied, a list of transports that
1030
can be reused to share a remote connection.
1032
if cls is not BzrDir:
1033
raise AssertionError("BzrDir.create always creates the"
1034
"default format, not one of %r" % cls)
1035
t = _mod_transport.get_transport(base, possible_transports)
1038
format = controldir.ControlDirFormat.get_default_format()
1039
return format.initialize_on_transport(t)
1041
def get_branch_transport(self, branch_format, name=None):
1042
"""Get the transport for use by branch format in this BzrDir.
1044
Note that bzr dirs that do not support format strings will raise
1045
IncompatibleFormat if the branch format they are given has
1046
a format string, and vice versa.
1048
If branch_format is None, the transport is returned with no
1049
checking. If it is not None, then the returned transport is
1050
guaranteed to point to an existing directory ready for use.
1052
raise NotImplementedError(self.get_branch_transport)
1054
def get_repository_transport(self, repository_format):
1055
"""Get the transport for use by repository format in this BzrDir.
1057
Note that bzr dirs that do not support format strings will raise
1058
IncompatibleFormat if the repository format they are given has
1059
a format string, and vice versa.
1061
If repository_format is None, the transport is returned with no
1062
checking. If it is not None, then the returned transport is
1063
guaranteed to point to an existing directory ready for use.
1065
raise NotImplementedError(self.get_repository_transport)
1067
def get_workingtree_transport(self, tree_format):
1068
"""Get the transport for use by workingtree format in this BzrDir.
1070
Note that bzr dirs that do not support format strings will raise
1071
IncompatibleFormat if the workingtree format they are given has a
1072
format string, and vice versa.
1074
If workingtree_format is None, the transport is returned with no
1075
checking. If it is not None, then the returned transport is
1076
guaranteed to point to an existing directory ready for use.
1078
raise NotImplementedError(self.get_workingtree_transport)
1131
def checkout_metadir(self):
1132
return self.cloning_metadir()
1134
def sprout(self, url, revision_id=None, force_new_repo=False,
1135
recurse='down', possible_transports=None,
1136
accelerator_tree=None, hardlink=False, stacked=False,
1137
source_branch=None, create_tree_if_local=True):
1138
"""Create a copy of this bzrdir prepared for use as a new line of
1141
If url's last component does not exist, it will be created.
1143
Attributes related to the identity of the source branch like
1144
branch nickname will be cleaned, a working tree is created
1145
whether one existed before or not; and a local branch is always
1148
if revision_id is not None, then the clone operation may tune
1149
itself to download less data.
1150
:param accelerator_tree: A tree which can be used for retrieving file
1151
contents more quickly than the revision tree, i.e. a workingtree.
1152
The revision tree will be used for cases where accelerator_tree's
1153
content is different.
1154
:param hardlink: If true, hard-link files from accelerator_tree,
1156
:param stacked: If true, create a stacked branch referring to the
1157
location of this control directory.
1158
:param create_tree_if_local: If true, a working-tree will be created
1159
when working locally.
1161
target_transport = get_transport(url, possible_transports)
1162
target_transport.ensure_base()
1163
cloning_format = self.cloning_metadir(stacked)
1164
# Create/update the result branch
1165
result = cloning_format.initialize_on_transport(target_transport)
1166
# if a stacked branch wasn't requested, we don't create one
1167
# even if the origin was stacked
1168
stacked_branch_url = None
1169
if source_branch is not None:
1171
stacked_branch_url = self.root_transport.base
1172
source_repository = source_branch.repository
1175
source_branch = self.open_branch()
1176
source_repository = source_branch.repository
1178
stacked_branch_url = self.root_transport.base
1179
except errors.NotBranchError:
1180
source_branch = None
1182
source_repository = self.open_repository()
1183
except errors.NoRepositoryPresent:
1184
source_repository = None
1185
repository_policy = result.determine_repository_policy(
1186
force_new_repo, stacked_branch_url, require_stacking=stacked)
1187
result_repo, is_new_repo = repository_policy.acquire_repository()
1188
if is_new_repo and revision_id is not None and not stacked:
1189
fetch_spec = graph.PendingAncestryResult(
1190
[revision_id], source_repository)
1193
if source_repository is not None:
1194
# Fetch while stacked to prevent unstacked fetch from
1196
if fetch_spec is None:
1197
result_repo.fetch(source_repository, revision_id=revision_id)
1199
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
1201
if source_branch is None:
1202
# this is for sprouting a bzrdir without a branch; is that
1204
# Not especially, but it's part of the contract.
1205
result_branch = result.create_branch()
1207
result_branch = source_branch.sprout(result,
1208
revision_id=revision_id, repository_policy=repository_policy)
1209
mutter("created new branch %r" % (result_branch,))
1211
# Create/update the result working tree
1212
if (create_tree_if_local and
1213
isinstance(target_transport, local.LocalTransport) and
1214
(result_repo is None or result_repo.make_working_trees())):
1215
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
1219
if wt.path2id('') is None:
1221
wt.set_root_id(self.open_workingtree.get_root_id())
1222
except errors.NoWorkingTree:
1228
if recurse == 'down':
1230
basis = wt.basis_tree()
1232
subtrees = basis.iter_references()
1233
elif result_branch is not None:
1234
basis = result_branch.basis_tree()
1236
subtrees = basis.iter_references()
1237
elif source_branch is not None:
1238
basis = source_branch.basis_tree()
1240
subtrees = basis.iter_references()
1245
for path, file_id in subtrees:
1246
target = urlutils.join(url, urlutils.escape(path))
1247
sublocation = source_branch.reference_parent(file_id, path)
1248
sublocation.bzrdir.sprout(target,
1249
basis.get_reference_revision(file_id, path),
1250
force_new_repo=force_new_repo, recurse=recurse,
1253
if basis is not None:
1257
def push_branch(self, source, revision_id=None, overwrite=False,
1258
remember=False, create_prefix=False):
1259
"""Push the source branch into this BzrDir."""
1261
# If we can open a branch, use its direct repository, otherwise see
1262
# if there is a repository without a branch.
1264
br_to = self.open_branch()
1265
except errors.NotBranchError:
1266
# Didn't find a branch, can we find a repository?
1267
repository_to = self.find_repository()
1269
# Found a branch, so we must have found a repository
1270
repository_to = br_to.repository
1272
push_result = PushResult()
1273
push_result.source_branch = source
1275
# We have a repository but no branch, copy the revisions, and then
1277
repository_to.fetch(source.repository, revision_id=revision_id)
1278
br_to = source.clone(self, revision_id=revision_id)
1279
if source.get_push_location() is None or remember:
1280
source.set_push_location(br_to.base)
1281
push_result.stacked_on = None
1282
push_result.branch_push_result = None
1283
push_result.old_revno = None
1284
push_result.old_revid = _mod_revision.NULL_REVISION
1285
push_result.target_branch = br_to
1286
push_result.master_branch = None
1287
push_result.workingtree_updated = False
1289
# We have successfully opened the branch, remember if necessary:
1290
if source.get_push_location() is None or remember:
1291
source.set_push_location(br_to.base)
1293
tree_to = self.open_workingtree()
1294
except errors.NotLocalUrl:
1295
push_result.branch_push_result = source.push(br_to,
1296
overwrite, stop_revision=revision_id)
1297
push_result.workingtree_updated = False
1298
except errors.NoWorkingTree:
1299
push_result.branch_push_result = source.push(br_to,
1300
overwrite, stop_revision=revision_id)
1301
push_result.workingtree_updated = None # Not applicable
1303
tree_to.lock_write()
1305
push_result.branch_push_result = source.push(
1306
tree_to.branch, overwrite, stop_revision=revision_id)
1310
push_result.workingtree_updated = True
1311
push_result.old_revno = push_result.branch_push_result.old_revno
1312
push_result.old_revid = push_result.branch_push_result.old_revid
1313
push_result.target_branch = \
1314
push_result.branch_push_result.target_branch
1081
1318
class BzrDirHooks(hooks.Hooks):
1084
1321
def __init__(self):
1085
1322
"""Create the default hooks."""
1086
hooks.Hooks.__init__(self, "bzrlib.bzrdir", "BzrDir.hooks")
1087
self.add_hook('pre_open',
1323
hooks.Hooks.__init__(self)
1324
self.create_hook(hooks.HookPoint('pre_open',
1088
1325
"Invoked before attempting to open a BzrDir with the transport "
1089
"that the open will use.", (1, 14))
1090
self.add_hook('post_repo_init',
1091
"Invoked after a repository has been initialized. "
1092
"post_repo_init is called with a "
1093
"bzrlib.bzrdir.RepoInitHookParams.",
1326
"that the open will use.", (1, 14), None))
1096
1328
# install the default hooks
1097
1329
BzrDir.hooks = BzrDirHooks()
1100
class RepoInitHookParams(object):
1101
"""Object holding parameters passed to `*_repo_init` hooks.
1103
There are 4 fields that hooks may wish to access:
1105
:ivar repository: Repository created
1106
:ivar format: Repository format
1107
:ivar bzrdir: The bzrdir for the repository
1108
:ivar shared: The repository is shared
1111
def __init__(self, repository, format, a_bzrdir, shared):
1112
"""Create a group of RepoInitHook parameters.
1114
:param repository: Repository created
1115
:param format: Repository format
1116
:param bzrdir: The bzrdir for the repository
1117
:param shared: The repository is shared
1332
class BzrDirPreSplitOut(BzrDir):
1333
"""A common class for the all-in-one formats."""
1335
def __init__(self, _transport, _format):
1336
"""See BzrDir.__init__."""
1337
super(BzrDirPreSplitOut, self).__init__(_transport, _format)
1338
self._control_files = lockable_files.LockableFiles(
1339
self.get_branch_transport(None),
1340
self._format._lock_file_name,
1341
self._format._lock_class)
1343
def break_lock(self):
1344
"""Pre-splitout bzrdirs do not suffer from stale locks."""
1345
raise NotImplementedError(self.break_lock)
1347
def cloning_metadir(self, require_stacking=False):
1348
"""Produce a metadir suitable for cloning with."""
1349
if require_stacking:
1350
return format_registry.make_bzrdir('1.6')
1351
return self._format.__class__()
1353
def clone(self, url, revision_id=None, force_new_repo=False,
1354
preserve_stacking=False):
1355
"""See BzrDir.clone().
1357
force_new_repo has no effect, since this family of formats always
1358
require a new repository.
1359
preserve_stacking has no effect, since no source branch using this
1360
family of formats can be stacked, so there is no stacking to preserve.
1119
self.repository = repository
1120
self.format = format
1121
self.bzrdir = a_bzrdir
1122
self.shared = shared
1124
def __eq__(self, other):
1125
return self.__dict__ == other.__dict__
1129
return "<%s for %s>" % (self.__class__.__name__,
1362
self._make_tail(url)
1363
result = self._format._initialize_for_clone(url)
1364
self.open_repository().clone(result, revision_id=revision_id)
1365
from_branch = self.open_branch()
1366
from_branch.clone(result, revision_id=revision_id)
1368
tree = self.open_workingtree()
1369
except errors.NotLocalUrl:
1370
# make a new one, this format always has to have one.
1371
result._init_workingtree()
1132
return "<%s for %s>" % (self.__class__.__name__,
1376
def create_branch(self):
1377
"""See BzrDir.create_branch."""
1378
return self._format.get_branch_format().initialize(self)
1380
def destroy_branch(self):
1381
"""See BzrDir.destroy_branch."""
1382
raise errors.UnsupportedOperation(self.destroy_branch, self)
1384
def create_repository(self, shared=False):
1385
"""See BzrDir.create_repository."""
1387
raise errors.IncompatibleFormat('shared repository', self._format)
1388
return self.open_repository()
1390
def destroy_repository(self):
1391
"""See BzrDir.destroy_repository."""
1392
raise errors.UnsupportedOperation(self.destroy_repository, self)
1394
def create_workingtree(self, revision_id=None, from_branch=None,
1395
accelerator_tree=None, hardlink=False):
1396
"""See BzrDir.create_workingtree."""
1397
# The workingtree is sometimes created when the bzrdir is created,
1398
# but not when cloning.
1400
# this looks buggy but is not -really-
1401
# because this format creates the workingtree when the bzrdir is
1403
# clone and sprout will have set the revision_id
1404
# and that will have set it for us, its only
1405
# specific uses of create_workingtree in isolation
1406
# that can do wonky stuff here, and that only
1407
# happens for creating checkouts, which cannot be
1408
# done on this format anyway. So - acceptable wart.
1410
warning("can't support hardlinked working trees in %r"
1413
result = self.open_workingtree(recommend_upgrade=False)
1414
except errors.NoSuchFile:
1415
result = self._init_workingtree()
1416
if revision_id is not None:
1417
if revision_id == _mod_revision.NULL_REVISION:
1418
result.set_parent_ids([])
1420
result.set_parent_ids([revision_id])
1423
def _init_workingtree(self):
1424
from bzrlib.workingtree import WorkingTreeFormat2
1426
return WorkingTreeFormat2().initialize(self)
1427
except errors.NotLocalUrl:
1428
# Even though we can't access the working tree, we need to
1429
# create its control files.
1430
return WorkingTreeFormat2()._stub_initialize_on_transport(
1431
self.transport, self._control_files._file_mode)
1433
def destroy_workingtree(self):
1434
"""See BzrDir.destroy_workingtree."""
1435
raise errors.UnsupportedOperation(self.destroy_workingtree, self)
1437
def destroy_workingtree_metadata(self):
1438
"""See BzrDir.destroy_workingtree_metadata."""
1439
raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1442
def get_branch_transport(self, branch_format):
1443
"""See BzrDir.get_branch_transport()."""
1444
if branch_format is None:
1445
return self.transport
1447
branch_format.get_format_string()
1448
except NotImplementedError:
1449
return self.transport
1450
raise errors.IncompatibleFormat(branch_format, self._format)
1452
def get_repository_transport(self, repository_format):
1453
"""See BzrDir.get_repository_transport()."""
1454
if repository_format is None:
1455
return self.transport
1457
repository_format.get_format_string()
1458
except NotImplementedError:
1459
return self.transport
1460
raise errors.IncompatibleFormat(repository_format, self._format)
1462
def get_workingtree_transport(self, workingtree_format):
1463
"""See BzrDir.get_workingtree_transport()."""
1464
if workingtree_format is None:
1465
return self.transport
1467
workingtree_format.get_format_string()
1468
except NotImplementedError:
1469
return self.transport
1470
raise errors.IncompatibleFormat(workingtree_format, self._format)
1472
def needs_format_conversion(self, format=None):
1473
"""See BzrDir.needs_format_conversion()."""
1474
# if the format is not the same as the system default,
1475
# an upgrade is needed.
1477
symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
1478
% 'needs_format_conversion(format=None)')
1479
format = BzrDirFormat.get_default_format()
1480
return not isinstance(self._format, format.__class__)
1482
def open_branch(self, unsupported=False, ignore_fallbacks=False):
1483
"""See BzrDir.open_branch."""
1484
from bzrlib.branch import BzrBranchFormat4
1485
format = BzrBranchFormat4()
1486
self._check_supported(format, unsupported)
1487
return format.open(self, _found=True)
1489
def sprout(self, url, revision_id=None, force_new_repo=False,
1490
possible_transports=None, accelerator_tree=None,
1491
hardlink=False, stacked=False, create_tree_if_local=True,
1492
source_branch=None):
1493
"""See BzrDir.sprout()."""
1494
if source_branch is not None:
1495
my_branch = self.open_branch()
1496
if source_branch.base != my_branch.base:
1497
raise AssertionError(
1498
"source branch %r is not within %r with branch %r" %
1499
(source_branch, self, my_branch))
1501
raise errors.UnstackableBranchFormat(
1502
self._format, self.root_transport.base)
1503
if not create_tree_if_local:
1504
raise errors.MustHaveWorkingTree(
1505
self._format, self.root_transport.base)
1506
from bzrlib.workingtree import WorkingTreeFormat2
1507
self._make_tail(url)
1508
result = self._format._initialize_for_clone(url)
1510
self.open_repository().clone(result, revision_id=revision_id)
1511
except errors.NoRepositoryPresent:
1514
self.open_branch().sprout(result, revision_id=revision_id)
1515
except errors.NotBranchError:
1518
# we always want a working tree
1519
WorkingTreeFormat2().initialize(result,
1520
accelerator_tree=accelerator_tree,
1525
class BzrDir4(BzrDirPreSplitOut):
1526
"""A .bzr version 4 control object.
1528
This is a deprecated format and may be removed after sept 2006.
1531
def create_repository(self, shared=False):
1532
"""See BzrDir.create_repository."""
1533
return self._format.repository_format.initialize(self, shared)
1535
def needs_format_conversion(self, format=None):
1536
"""Format 4 dirs are always in need of conversion."""
1538
symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
1539
% 'needs_format_conversion(format=None)')
1542
def open_repository(self):
1543
"""See BzrDir.open_repository."""
1544
from bzrlib.repofmt.weaverepo import RepositoryFormat4
1545
return RepositoryFormat4().open(self, _found=True)
1548
class BzrDir5(BzrDirPreSplitOut):
1549
"""A .bzr version 5 control object.
1551
This is a deprecated format and may be removed after sept 2006.
1554
def has_workingtree(self):
1555
"""See BzrDir.has_workingtree."""
1558
def open_repository(self):
1559
"""See BzrDir.open_repository."""
1560
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1561
return RepositoryFormat5().open(self, _found=True)
1563
def open_workingtree(self, _unsupported=False,
1564
recommend_upgrade=True):
1565
"""See BzrDir.create_workingtree."""
1566
from bzrlib.workingtree import WorkingTreeFormat2
1567
wt_format = WorkingTreeFormat2()
1568
# we don't warn here about upgrades; that ought to be handled for the
1570
return wt_format.open(self, _found=True)
1573
class BzrDir6(BzrDirPreSplitOut):
1574
"""A .bzr version 6 control object.
1576
This is a deprecated format and may be removed after sept 2006.
1579
def has_workingtree(self):
1580
"""See BzrDir.has_workingtree."""
1583
def open_repository(self):
1584
"""See BzrDir.open_repository."""
1585
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1586
return RepositoryFormat6().open(self, _found=True)
1588
def open_workingtree(self, _unsupported=False,
1589
recommend_upgrade=True):
1590
"""See BzrDir.create_workingtree."""
1591
# we don't warn here about upgrades; that ought to be handled for the
1593
from bzrlib.workingtree import WorkingTreeFormat2
1594
return WorkingTreeFormat2().open(self, _found=True)
1136
1597
class BzrDirMeta1(BzrDir):
2163
def unregister_format(klass, format):
2164
del klass._formats[format.get_format_string()]
2167
def unregister_control_format(klass, format):
2168
klass._control_formats.remove(format)
2171
class BzrDirFormat4(BzrDirFormat):
2172
"""Bzr dir format 4.
2174
This format is a combined format for working tree, branch and repository.
2176
- Format 1 working trees [always]
2177
- Format 4 branches [always]
2178
- Format 4 repositories [always]
2180
This format is deprecated: it indexes texts using a text it which is
2181
removed in format 5; write support for this format has been removed.
2184
_lock_class = lockable_files.TransportLock
2186
def get_format_string(self):
2187
"""See BzrDirFormat.get_format_string()."""
2188
return "Bazaar-NG branch, format 0.0.4\n"
2190
def get_format_description(self):
2191
"""See BzrDirFormat.get_format_description()."""
2192
return "All-in-one format 4"
2194
def get_converter(self, format=None):
2195
"""See BzrDirFormat.get_converter()."""
2196
# there is one and only one upgrade path here.
2197
return ConvertBzrDir4To5()
2199
def initialize_on_transport(self, transport):
2200
"""Format 4 branches cannot be created."""
2201
raise errors.UninitializableFormat(self)
2203
def is_supported(self):
2204
"""Format 4 is not supported.
2206
It is not supported because the model changed from 4 to 5 and the
2207
conversion logic is expensive - so doing it on the fly was not
2212
def network_name(self):
2213
return self.get_format_string()
2215
def _open(self, transport):
2216
"""See BzrDirFormat._open."""
2217
return BzrDir4(transport, self)
2219
def __return_repository_format(self):
2220
"""Circular import protection."""
2221
from bzrlib.repofmt.weaverepo import RepositoryFormat4
2222
return RepositoryFormat4()
2223
repository_format = property(__return_repository_format)
2226
class BzrDirFormatAllInOne(BzrDirFormat):
2227
"""Common class for formats before meta-dirs."""
2229
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
2230
create_prefix=False, force_new_repo=False, stacked_on=None,
2231
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
2233
"""See BzrDirFormat.initialize_on_transport_ex."""
2234
require_stacking = (stacked_on is not None)
2235
# Format 5 cannot stack, but we've been asked to - actually init
2237
if require_stacking:
2238
format = BzrDirMetaFormat1()
2239
return format.initialize_on_transport_ex(transport,
2240
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2241
force_new_repo=force_new_repo, stacked_on=stacked_on,
2242
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2243
make_working_trees=make_working_trees, shared_repo=shared_repo)
2244
return BzrDirFormat.initialize_on_transport_ex(self, transport,
2245
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2246
force_new_repo=force_new_repo, stacked_on=stacked_on,
2247
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2248
make_working_trees=make_working_trees, shared_repo=shared_repo)
2251
class BzrDirFormat5(BzrDirFormatAllInOne):
2252
"""Bzr control format 5.
2254
This format is a combined format for working tree, branch and repository.
2256
- Format 2 working trees [always]
2257
- Format 4 branches [always]
2258
- Format 5 repositories [always]
2259
Unhashed stores in the repository.
2262
_lock_class = lockable_files.TransportLock
2264
def get_format_string(self):
2265
"""See BzrDirFormat.get_format_string()."""
2266
return "Bazaar-NG branch, format 5\n"
2268
def get_branch_format(self):
2269
from bzrlib import branch
2270
return branch.BzrBranchFormat4()
2272
def get_format_description(self):
2273
"""See BzrDirFormat.get_format_description()."""
2274
return "All-in-one format 5"
2276
def get_converter(self, format=None):
2277
"""See BzrDirFormat.get_converter()."""
2278
# there is one and only one upgrade path here.
2279
return ConvertBzrDir5To6()
2281
def _initialize_for_clone(self, url):
2282
return self.initialize_on_transport(get_transport(url), _cloning=True)
2284
def initialize_on_transport(self, transport, _cloning=False):
2285
"""Format 5 dirs always have working tree, branch and repository.
2287
Except when they are being cloned.
2289
from bzrlib.branch import BzrBranchFormat4
2290
from bzrlib.repofmt.weaverepo import RepositoryFormat5
2291
result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
2292
RepositoryFormat5().initialize(result, _internal=True)
2294
branch = BzrBranchFormat4().initialize(result)
2295
result._init_workingtree()
2298
def network_name(self):
2299
return self.get_format_string()
2301
def _open(self, transport):
2302
"""See BzrDirFormat._open."""
2303
return BzrDir5(transport, self)
2305
def __return_repository_format(self):
2306
"""Circular import protection."""
2307
from bzrlib.repofmt.weaverepo import RepositoryFormat5
2308
return RepositoryFormat5()
2309
repository_format = property(__return_repository_format)
2312
class BzrDirFormat6(BzrDirFormatAllInOne):
2313
"""Bzr control format 6.
2315
This format is a combined format for working tree, branch and repository.
2317
- Format 2 working trees [always]
2318
- Format 4 branches [always]
2319
- Format 6 repositories [always]
2322
_lock_class = lockable_files.TransportLock
2324
def get_format_string(self):
2325
"""See BzrDirFormat.get_format_string()."""
2326
return "Bazaar-NG branch, format 6\n"
2328
def get_format_description(self):
2329
"""See BzrDirFormat.get_format_description()."""
2330
return "All-in-one format 6"
2332
def get_branch_format(self):
2333
from bzrlib import branch
2334
return branch.BzrBranchFormat4()
2336
def get_converter(self, format=None):
2337
"""See BzrDirFormat.get_converter()."""
2338
# there is one and only one upgrade path here.
2339
return ConvertBzrDir6ToMeta()
2341
def _initialize_for_clone(self, url):
2342
return self.initialize_on_transport(get_transport(url), _cloning=True)
2344
def initialize_on_transport(self, transport, _cloning=False):
2345
"""Format 6 dirs always have working tree, branch and repository.
2347
Except when they are being cloned.
2349
from bzrlib.branch import BzrBranchFormat4
2350
from bzrlib.repofmt.weaverepo import RepositoryFormat6
2351
result = super(BzrDirFormat6, self).initialize_on_transport(transport)
2352
RepositoryFormat6().initialize(result, _internal=True)
2354
branch = BzrBranchFormat4().initialize(result)
2355
result._init_workingtree()
2358
def network_name(self):
2359
return self.get_format_string()
2361
def _open(self, transport):
2362
"""See BzrDirFormat._open."""
2363
return BzrDir6(transport, self)
2365
def __return_repository_format(self):
2366
"""Circular import protection."""
2367
from bzrlib.repofmt.weaverepo import RepositoryFormat6
2368
return RepositoryFormat6()
2369
repository_format = property(__return_repository_format)
1615
2372
class BzrDirMetaFormat1(BzrDirFormat):
1616
2373
"""Bzr meta control format 1
1618
2375
This is the first format with split out working tree, branch and repository
1623
- Format 3 working trees [optional]
1624
- Format 5 branches [optional]
1625
- Format 7 repositories [optional]
2378
- Format 3 working trees [optional]
2379
- Format 5 branches [optional]
2380
- Format 7 repositories [optional]
1628
2383
_lock_class = lockdir.LockDir
1630
fixed_components = False
1632
2385
def __init__(self):
1633
2386
self._workingtree_format = None
1634
2387
self._branch_format = None
1825
2574
__set_workingtree_format)
2577
network_format_registry = registry.FormatRegistry()
2578
"""Registry of formats indexed by their network name.
2580
The network name for a BzrDirFormat is an identifier that can be used when
2581
referring to formats with smart server operations. See
2582
BzrDirFormat.network_name() for more detail.
2586
# Register bzr control format
2587
BzrDirFormat.register_control_format(BzrDirFormat)
1828
2589
# Register bzr formats
1829
BzrProber.formats.register(BzrDirMetaFormat1.get_format_string(),
1831
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1834
class ConvertMetaToMeta(controldir.Converter):
2590
BzrDirFormat.register_format(BzrDirFormat4())
2591
BzrDirFormat.register_format(BzrDirFormat5())
2592
BzrDirFormat.register_format(BzrDirFormat6())
2593
__default_format = BzrDirMetaFormat1()
2594
BzrDirFormat.register_format(__default_format)
2595
BzrDirFormat._default_format = __default_format
2598
class Converter(object):
2599
"""Converts a disk format object from one format to another."""
2601
def convert(self, to_convert, pb):
2602
"""Perform the conversion of to_convert, giving feedback via pb.
2604
:param to_convert: The disk object to convert.
2605
:param pb: a progress bar to use for progress information.
2608
def step(self, message):
2609
"""Update the pb by a step."""
2611
self.pb.update(message, self.count, self.total)
2614
class ConvertBzrDir4To5(Converter):
2615
"""Converts format 4 bzr dirs to format 5."""
2618
super(ConvertBzrDir4To5, self).__init__()
2619
self.converted_revs = set()
2620
self.absent_revisions = set()
2624
def convert(self, to_convert, pb):
2625
"""See Converter.convert()."""
2626
self.bzrdir = to_convert
2628
warnings.warn("pb parameter to convert() is deprecated")
2629
self.pb = ui.ui_factory.nested_progress_bar()
2631
ui.ui_factory.note('starting upgrade from format 4 to 5')
2632
if isinstance(self.bzrdir.transport, local.LocalTransport):
2633
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2634
self._convert_to_weaves()
2635
return BzrDir.open(self.bzrdir.root_transport.base)
2639
def _convert_to_weaves(self):
2640
ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2643
stat = self.bzrdir.transport.stat('weaves')
2644
if not S_ISDIR(stat.st_mode):
2645
self.bzrdir.transport.delete('weaves')
2646
self.bzrdir.transport.mkdir('weaves')
2647
except errors.NoSuchFile:
2648
self.bzrdir.transport.mkdir('weaves')
2649
# deliberately not a WeaveFile as we want to build it up slowly.
2650
self.inv_weave = Weave('inventory')
2651
# holds in-memory weaves for all files
2652
self.text_weaves = {}
2653
self.bzrdir.transport.delete('branch-format')
2654
self.branch = self.bzrdir.open_branch()
2655
self._convert_working_inv()
2656
rev_history = self.branch.revision_history()
2657
# to_read is a stack holding the revisions we still need to process;
2658
# appending to it adds new highest-priority revisions
2659
self.known_revisions = set(rev_history)
2660
self.to_read = rev_history[-1:]
2662
rev_id = self.to_read.pop()
2663
if (rev_id not in self.revisions
2664
and rev_id not in self.absent_revisions):
2665
self._load_one_rev(rev_id)
2667
to_import = self._make_order()
2668
for i, rev_id in enumerate(to_import):
2669
self.pb.update('converting revision', i, len(to_import))
2670
self._convert_one_rev(rev_id)
2672
self._write_all_weaves()
2673
self._write_all_revs()
2674
ui.ui_factory.note('upgraded to weaves:')
2675
ui.ui_factory.note(' %6d revisions and inventories' % len(self.revisions))
2676
ui.ui_factory.note(' %6d revisions not present' % len(self.absent_revisions))
2677
ui.ui_factory.note(' %6d texts' % self.text_count)
2678
self._cleanup_spare_files_after_format4()
2679
self.branch._transport.put_bytes(
2681
BzrDirFormat5().get_format_string(),
2682
mode=self.bzrdir._get_file_mode())
2684
def _cleanup_spare_files_after_format4(self):
2685
# FIXME working tree upgrade foo.
2686
for n in 'merged-patches', 'pending-merged-patches':
2688
## assert os.path.getsize(p) == 0
2689
self.bzrdir.transport.delete(n)
2690
except errors.NoSuchFile:
2692
self.bzrdir.transport.delete_tree('inventory-store')
2693
self.bzrdir.transport.delete_tree('text-store')
2695
def _convert_working_inv(self):
2696
inv = xml4.serializer_v4.read_inventory(
2697
self.branch._transport.get('inventory'))
2698
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv, working=True)
2699
self.branch._transport.put_bytes('inventory', new_inv_xml,
2700
mode=self.bzrdir._get_file_mode())
2702
def _write_all_weaves(self):
2703
controlweaves = WeaveStore(self.bzrdir.transport, prefixed=False)
2704
weave_transport = self.bzrdir.transport.clone('weaves')
2705
weaves = WeaveStore(weave_transport, prefixed=False)
2706
transaction = WriteTransaction()
2710
for file_id, file_weave in self.text_weaves.items():
2711
self.pb.update('writing weave', i, len(self.text_weaves))
2712
weaves._put_weave(file_id, file_weave, transaction)
2714
self.pb.update('inventory', 0, 1)
2715
controlweaves._put_weave('inventory', self.inv_weave, transaction)
2716
self.pb.update('inventory', 1, 1)
2720
def _write_all_revs(self):
2721
"""Write all revisions out in new form."""
2722
self.bzrdir.transport.delete_tree('revision-store')
2723
self.bzrdir.transport.mkdir('revision-store')
2724
revision_transport = self.bzrdir.transport.clone('revision-store')
2726
from bzrlib.xml5 import serializer_v5
2727
from bzrlib.repofmt.weaverepo import RevisionTextStore
2728
revision_store = RevisionTextStore(revision_transport,
2729
serializer_v5, False, versionedfile.PrefixMapper(),
2730
lambda:True, lambda:True)
2732
for i, rev_id in enumerate(self.converted_revs):
2733
self.pb.update('write revision', i, len(self.converted_revs))
2734
text = serializer_v5.write_revision_to_string(
2735
self.revisions[rev_id])
2737
revision_store.add_lines(key, None, osutils.split_lines(text))
2741
def _load_one_rev(self, rev_id):
2742
"""Load a revision object into memory.
2744
Any parents not either loaded or abandoned get queued to be
2746
self.pb.update('loading revision',
2747
len(self.revisions),
2748
len(self.known_revisions))
2749
if not self.branch.repository.has_revision(rev_id):
2751
ui.ui_factory.note('revision {%s} not present in branch; '
2752
'will be converted as a ghost' %
2754
self.absent_revisions.add(rev_id)
2756
rev = self.branch.repository.get_revision(rev_id)
2757
for parent_id in rev.parent_ids:
2758
self.known_revisions.add(parent_id)
2759
self.to_read.append(parent_id)
2760
self.revisions[rev_id] = rev
2762
def _load_old_inventory(self, rev_id):
2763
old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
2764
inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2765
inv.revision_id = rev_id
2766
rev = self.revisions[rev_id]
2769
def _load_updated_inventory(self, rev_id):
2770
inv_xml = self.inv_weave.get_text(rev_id)
2771
inv = xml5.serializer_v5.read_inventory_from_string(inv_xml, rev_id)
2774
def _convert_one_rev(self, rev_id):
2775
"""Convert revision and all referenced objects to new format."""
2776
rev = self.revisions[rev_id]
2777
inv = self._load_old_inventory(rev_id)
2778
present_parents = [p for p in rev.parent_ids
2779
if p not in self.absent_revisions]
2780
self._convert_revision_contents(rev, inv, present_parents)
2781
self._store_new_inv(rev, inv, present_parents)
2782
self.converted_revs.add(rev_id)
2784
def _store_new_inv(self, rev, inv, present_parents):
2785
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
2786
new_inv_sha1 = sha_string(new_inv_xml)
2787
self.inv_weave.add_lines(rev.revision_id,
2789
new_inv_xml.splitlines(True))
2790
rev.inventory_sha1 = new_inv_sha1
2792
def _convert_revision_contents(self, rev, inv, present_parents):
2793
"""Convert all the files within a revision.
2795
Also upgrade the inventory to refer to the text revision ids."""
2796
rev_id = rev.revision_id
2797
mutter('converting texts of revision {%s}',
2799
parent_invs = map(self._load_updated_inventory, present_parents)
2800
entries = inv.iter_entries()
2802
for path, ie in entries:
2803
self._convert_file_version(rev, ie, parent_invs)
2805
def _convert_file_version(self, rev, ie, parent_invs):
2806
"""Convert one version of one file.
2808
The file needs to be added into the weave if it is a merge
2809
of >=2 parents or if it's changed from its parent.
2811
file_id = ie.file_id
2812
rev_id = rev.revision_id
2813
w = self.text_weaves.get(file_id)
2816
self.text_weaves[file_id] = w
2817
text_changed = False
2818
parent_candiate_entries = ie.parent_candidates(parent_invs)
2819
heads = graph.Graph(self).heads(parent_candiate_entries.keys())
2820
# XXX: Note that this is unordered - and this is tolerable because
2821
# the previous code was also unordered.
2822
previous_entries = dict((head, parent_candiate_entries[head]) for head
2824
self.snapshot_ie(previous_entries, ie, w, rev_id)
2827
def get_parent_map(self, revision_ids):
2828
"""See graph.StackedParentsProvider.get_parent_map"""
2829
return dict((revision_id, self.revisions[revision_id])
2830
for revision_id in revision_ids
2831
if revision_id in self.revisions)
2833
def snapshot_ie(self, previous_revisions, ie, w, rev_id):
2834
# TODO: convert this logic, which is ~= snapshot to
2835
# a call to:. This needs the path figured out. rather than a work_tree
2836
# a v4 revision_tree can be given, or something that looks enough like
2837
# one to give the file content to the entry if it needs it.
2838
# and we need something that looks like a weave store for snapshot to
2840
#ie.snapshot(rev, PATH, previous_revisions, REVISION_TREE, InMemoryWeaveStore(self.text_weaves))
2841
if len(previous_revisions) == 1:
2842
previous_ie = previous_revisions.values()[0]
2843
if ie._unchanged(previous_ie):
2844
ie.revision = previous_ie.revision
2847
text = self.branch.repository._text_store.get(ie.text_id)
2848
file_lines = text.readlines()
2849
w.add_lines(rev_id, previous_revisions, file_lines)
2850
self.text_count += 1
2852
w.add_lines(rev_id, previous_revisions, [])
2853
ie.revision = rev_id
2855
def _make_order(self):
2856
"""Return a suitable order for importing revisions.
2858
The order must be such that an revision is imported after all
2859
its (present) parents.
2861
todo = set(self.revisions.keys())
2862
done = self.absent_revisions.copy()
2865
# scan through looking for a revision whose parents
2867
for rev_id in sorted(list(todo)):
2868
rev = self.revisions[rev_id]
2869
parent_ids = set(rev.parent_ids)
2870
if parent_ids.issubset(done):
2871
# can take this one now
2872
order.append(rev_id)
2878
class ConvertBzrDir5To6(Converter):
2879
"""Converts format 5 bzr dirs to format 6."""
2881
def convert(self, to_convert, pb):
2882
"""See Converter.convert()."""
2883
self.bzrdir = to_convert
2884
pb = ui.ui_factory.nested_progress_bar()
2886
ui.ui_factory.note('starting upgrade from format 5 to 6')
2887
self._convert_to_prefixed()
2888
return BzrDir.open(self.bzrdir.root_transport.base)
2892
def _convert_to_prefixed(self):
2893
from bzrlib.store import TransportStore
2894
self.bzrdir.transport.delete('branch-format')
2895
for store_name in ["weaves", "revision-store"]:
2896
ui.ui_factory.note("adding prefixes to %s" % store_name)
2897
store_transport = self.bzrdir.transport.clone(store_name)
2898
store = TransportStore(store_transport, prefixed=True)
2899
for urlfilename in store_transport.list_dir('.'):
2900
filename = urlutils.unescape(urlfilename)
2901
if (filename.endswith(".weave") or
2902
filename.endswith(".gz") or
2903
filename.endswith(".sig")):
2904
file_id, suffix = os.path.splitext(filename)
2908
new_name = store._mapper.map((file_id,)) + suffix
2909
# FIXME keep track of the dirs made RBC 20060121
2911
store_transport.move(filename, new_name)
2912
except errors.NoSuchFile: # catches missing dirs strangely enough
2913
store_transport.mkdir(osutils.dirname(new_name))
2914
store_transport.move(filename, new_name)
2915
self.bzrdir.transport.put_bytes(
2917
BzrDirFormat6().get_format_string(),
2918
mode=self.bzrdir._get_file_mode())
2921
class ConvertBzrDir6ToMeta(Converter):
2922
"""Converts format 6 bzr dirs to metadirs."""
2924
def convert(self, to_convert, pb):
2925
"""See Converter.convert()."""
2926
from bzrlib.repofmt.weaverepo import RepositoryFormat7
2927
from bzrlib.branch import BzrBranchFormat5
2928
self.bzrdir = to_convert
2929
self.pb = ui.ui_factory.nested_progress_bar()
2931
self.total = 20 # the steps we know about
2932
self.garbage_inventories = []
2933
self.dir_mode = self.bzrdir._get_dir_mode()
2934
self.file_mode = self.bzrdir._get_file_mode()
2936
ui.ui_factory.note('starting upgrade from format 6 to metadir')
2937
self.bzrdir.transport.put_bytes(
2939
"Converting to format 6",
2940
mode=self.file_mode)
2941
# its faster to move specific files around than to open and use the apis...
2942
# first off, nuke ancestry.weave, it was never used.
2944
self.step('Removing ancestry.weave')
2945
self.bzrdir.transport.delete('ancestry.weave')
2946
except errors.NoSuchFile:
2948
# find out whats there
2949
self.step('Finding branch files')
2950
last_revision = self.bzrdir.open_branch().last_revision()
2951
bzrcontents = self.bzrdir.transport.list_dir('.')
2952
for name in bzrcontents:
2953
if name.startswith('basis-inventory.'):
2954
self.garbage_inventories.append(name)
2955
# create new directories for repository, working tree and branch
2956
repository_names = [('inventory.weave', True),
2957
('revision-store', True),
2959
self.step('Upgrading repository ')
2960
self.bzrdir.transport.mkdir('repository', mode=self.dir_mode)
2961
self.make_lock('repository')
2962
# we hard code the formats here because we are converting into
2963
# the meta format. The meta format upgrader can take this to a
2964
# future format within each component.
2965
self.put_format('repository', RepositoryFormat7())
2966
for entry in repository_names:
2967
self.move_entry('repository', entry)
2969
self.step('Upgrading branch ')
2970
self.bzrdir.transport.mkdir('branch', mode=self.dir_mode)
2971
self.make_lock('branch')
2972
self.put_format('branch', BzrBranchFormat5())
2973
branch_files = [('revision-history', True),
2974
('branch-name', True),
2976
for entry in branch_files:
2977
self.move_entry('branch', entry)
2979
checkout_files = [('pending-merges', True),
2980
('inventory', True),
2981
('stat-cache', False)]
2982
# If a mandatory checkout file is not present, the branch does not have
2983
# a functional checkout. Do not create a checkout in the converted
2985
for name, mandatory in checkout_files:
2986
if mandatory and name not in bzrcontents:
2987
has_checkout = False
2991
if not has_checkout:
2992
ui.ui_factory.note('No working tree.')
2993
# If some checkout files are there, we may as well get rid of them.
2994
for name, mandatory in checkout_files:
2995
if name in bzrcontents:
2996
self.bzrdir.transport.delete(name)
2998
from bzrlib.workingtree import WorkingTreeFormat3
2999
self.step('Upgrading working tree')
3000
self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
3001
self.make_lock('checkout')
3003
'checkout', WorkingTreeFormat3())
3004
self.bzrdir.transport.delete_multi(
3005
self.garbage_inventories, self.pb)
3006
for entry in checkout_files:
3007
self.move_entry('checkout', entry)
3008
if last_revision is not None:
3009
self.bzrdir.transport.put_bytes(
3010
'checkout/last-revision', last_revision)
3011
self.bzrdir.transport.put_bytes(
3013
BzrDirMetaFormat1().get_format_string(),
3014
mode=self.file_mode)
3016
return BzrDir.open(self.bzrdir.root_transport.base)
3018
def make_lock(self, name):
3019
"""Make a lock for the new control dir name."""
3020
self.step('Make %s lock' % name)
3021
ld = lockdir.LockDir(self.bzrdir.transport,
3023
file_modebits=self.file_mode,
3024
dir_modebits=self.dir_mode)
3027
def move_entry(self, new_dir, entry):
3028
"""Move then entry name into new_dir."""
3030
mandatory = entry[1]
3031
self.step('Moving %s' % name)
3033
self.bzrdir.transport.move(name, '%s/%s' % (new_dir, name))
3034
except errors.NoSuchFile:
3038
def put_format(self, dirname, format):
3039
self.bzrdir.transport.put_bytes('%s/format' % dirname,
3040
format.get_format_string(),
3044
class ConvertMetaToMeta(Converter):
1835
3045
"""Converts the components of metadirs."""
1837
3047
def __init__(self, target_format):
1909
3120
return to_convert
1912
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
3123
# This is not in remote.py because it's relatively small, and needs to be
3124
# registered. Putting it in remote.py creates a circular import problem.
3125
# we can make it a lazy object if the control formats is turned into something
3127
class RemoteBzrDirFormat(BzrDirMetaFormat1):
3128
"""Format representing bzrdirs accessed via a smart server"""
3131
BzrDirMetaFormat1.__init__(self)
3132
# XXX: It's a bit ugly that the network name is here, because we'd
3133
# like to believe that format objects are stateless or at least
3134
# immutable, However, we do at least avoid mutating the name after
3135
# it's returned. See <https://bugs.edge.launchpad.net/bzr/+bug/504102>
3136
self._network_name = None
3139
return "%s(_network_name=%r)" % (self.__class__.__name__,
3142
def get_format_description(self):
3143
if self._network_name:
3144
real_format = network_format_registry.get(self._network_name)
3145
return 'Remote: ' + real_format.get_format_description()
3146
return 'bzr remote bzrdir'
3148
def get_format_string(self):
3149
raise NotImplementedError(self.get_format_string)
3151
def network_name(self):
3152
if self._network_name:
3153
return self._network_name
3155
raise AssertionError("No network name set.")
3158
def probe_transport(klass, transport):
3159
"""Return a RemoteBzrDirFormat object if it looks possible."""
3161
medium = transport.get_smart_medium()
3162
except (NotImplementedError, AttributeError,
3163
errors.TransportNotPossible, errors.NoSmartMedium,
3164
errors.SmartProtocolError):
3165
# no smart server, so not a branch for this format type.
3166
raise errors.NotBranchError(path=transport.base)
3168
# Decline to open it if the server doesn't support our required
3169
# version (3) so that the VFS-based transport will do it.
3170
if medium.should_probe():
3172
server_version = medium.protocol_version()
3173
except errors.SmartProtocolError:
3174
# Apparently there's no usable smart server there, even though
3175
# the medium supports the smart protocol.
3176
raise errors.NotBranchError(path=transport.base)
3177
if server_version != '2':
3178
raise errors.NotBranchError(path=transport.base)
3181
def initialize_on_transport(self, transport):
3183
# hand off the request to the smart server
3184
client_medium = transport.get_smart_medium()
3185
except errors.NoSmartMedium:
3186
# TODO: lookup the local format from a server hint.
3187
local_dir_format = BzrDirMetaFormat1()
3188
return local_dir_format.initialize_on_transport(transport)
3189
client = _SmartClient(client_medium)
3190
path = client.remote_path_from_transport(transport)
3192
response = client.call('BzrDirFormat.initialize', path)
3193
except errors.ErrorFromSmartServer, err:
3194
remote._translate_error(err, path=path)
3195
if response[0] != 'ok':
3196
raise errors.SmartProtocolError('unexpected response code %s' % (response,))
3197
format = RemoteBzrDirFormat()
3198
self._supply_sub_formats_to(format)
3199
return remote.RemoteBzrDir(transport, format)
3201
def parse_NoneTrueFalse(self, arg):
3208
raise AssertionError("invalid arg %r" % arg)
3210
def _serialize_NoneTrueFalse(self, arg):
3217
def _serialize_NoneString(self, arg):
3220
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
3221
create_prefix=False, force_new_repo=False, stacked_on=None,
3222
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
3225
# hand off the request to the smart server
3226
client_medium = transport.get_smart_medium()
3227
except errors.NoSmartMedium:
3230
# Decline to open it if the server doesn't support our required
3231
# version (3) so that the VFS-based transport will do it.
3232
if client_medium.should_probe():
3234
server_version = client_medium.protocol_version()
3235
if server_version != '2':
3239
except errors.SmartProtocolError:
3240
# Apparently there's no usable smart server there, even though
3241
# the medium supports the smart protocol.
3246
client = _SmartClient(client_medium)
3247
path = client.remote_path_from_transport(transport)
3248
if client_medium._is_remote_before((1, 16)):
3251
# TODO: lookup the local format from a server hint.
3252
local_dir_format = BzrDirMetaFormat1()
3253
self._supply_sub_formats_to(local_dir_format)
3254
return local_dir_format.initialize_on_transport_ex(transport,
3255
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
3256
force_new_repo=force_new_repo, stacked_on=stacked_on,
3257
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
3258
make_working_trees=make_working_trees, shared_repo=shared_repo,
3260
return self._initialize_on_transport_ex_rpc(client, path, transport,
3261
use_existing_dir, create_prefix, force_new_repo, stacked_on,
3262
stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
3264
def _initialize_on_transport_ex_rpc(self, client, path, transport,
3265
use_existing_dir, create_prefix, force_new_repo, stacked_on,
3266
stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
3268
args.append(self._serialize_NoneTrueFalse(use_existing_dir))
3269
args.append(self._serialize_NoneTrueFalse(create_prefix))
3270
args.append(self._serialize_NoneTrueFalse(force_new_repo))
3271
args.append(self._serialize_NoneString(stacked_on))
3272
# stack_on_pwd is often/usually our transport
3275
stack_on_pwd = transport.relpath(stack_on_pwd)
3276
if not stack_on_pwd:
3278
except errors.PathNotChild:
3280
args.append(self._serialize_NoneString(stack_on_pwd))
3281
args.append(self._serialize_NoneString(repo_format_name))
3282
args.append(self._serialize_NoneTrueFalse(make_working_trees))
3283
args.append(self._serialize_NoneTrueFalse(shared_repo))
3284
request_network_name = self._network_name or \
3285
BzrDirFormat.get_default_format().network_name()
3287
response = client.call('BzrDirFormat.initialize_ex_1.16',
3288
request_network_name, path, *args)
3289
except errors.UnknownSmartMethod:
3290
client._medium._remember_remote_is_before((1,16))
3291
local_dir_format = BzrDirMetaFormat1()
3292
self._supply_sub_formats_to(local_dir_format)
3293
return local_dir_format.initialize_on_transport_ex(transport,
3294
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
3295
force_new_repo=force_new_repo, stacked_on=stacked_on,
3296
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
3297
make_working_trees=make_working_trees, shared_repo=shared_repo,
3299
except errors.ErrorFromSmartServer, err:
3300
remote._translate_error(err, path=path)
3301
repo_path = response[0]
3302
bzrdir_name = response[6]
3303
require_stacking = response[7]
3304
require_stacking = self.parse_NoneTrueFalse(require_stacking)
3305
format = RemoteBzrDirFormat()
3306
format._network_name = bzrdir_name
3307
self._supply_sub_formats_to(format)
3308
bzrdir = remote.RemoteBzrDir(transport, format, _client=client)
3310
repo_format = remote.response_tuple_to_repo_format(response[1:])
3311
if repo_path == '.':
3314
repo_bzrdir_format = RemoteBzrDirFormat()
3315
repo_bzrdir_format._network_name = response[5]
3316
repo_bzr = remote.RemoteBzrDir(transport.clone(repo_path),
3320
final_stack = response[8] or None
3321
final_stack_pwd = response[9] or None
3323
final_stack_pwd = urlutils.join(
3324
transport.base, final_stack_pwd)
3325
remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
3326
if len(response) > 10:
3327
# Updated server verb that locks remotely.
3328
repo_lock_token = response[10] or None
3329
remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
3331
remote_repo.dont_leave_lock_in_place()
3333
remote_repo.lock_write()
3334
policy = UseExistingRepository(remote_repo, final_stack,
3335
final_stack_pwd, require_stacking)
3336
policy.acquire_repository()
3340
bzrdir._format.set_branch_format(self.get_branch_format())
3341
if require_stacking:
3342
# The repo has already been created, but we need to make sure that
3343
# we'll make a stackable branch.
3344
bzrdir._format.require_stacking(_skip_repo=True)
3345
return remote_repo, bzrdir, require_stacking, policy
3347
def _open(self, transport):
3348
return remote.RemoteBzrDir(transport, self)
3350
def __eq__(self, other):
3351
if not isinstance(other, RemoteBzrDirFormat):
3353
return self.get_format_description() == other.get_format_description()
3355
def __return_repository_format(self):
3356
# Always return a RemoteRepositoryFormat object, but if a specific bzr
3357
# repository format has been asked for, tell the RemoteRepositoryFormat
3358
# that it should use that for init() etc.
3359
result = remote.RemoteRepositoryFormat()
3360
custom_format = getattr(self, '_repository_format', None)
3362
if isinstance(custom_format, remote.RemoteRepositoryFormat):
3363
return custom_format
3365
# We will use the custom format to create repositories over the
3366
# wire; expose its details like rich_root_data for code to
3368
result._custom_format = custom_format
3371
def get_branch_format(self):
3372
result = BzrDirMetaFormat1.get_branch_format(self)
3373
if not isinstance(result, remote.RemoteBranchFormat):
3374
new_result = remote.RemoteBranchFormat()
3375
new_result._custom_format = result
3377
self.set_branch_format(new_result)
3381
repository_format = property(__return_repository_format,
3382
BzrDirMetaFormat1._set_repository_format) #.im_func)
3385
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
3388
class BzrDirFormatInfo(object):
3390
def __init__(self, native, deprecated, hidden, experimental):
3391
self.deprecated = deprecated
3392
self.native = native
3393
self.hidden = hidden
3394
self.experimental = experimental
3397
class BzrDirFormatRegistry(registry.Registry):
3398
"""Registry of user-selectable BzrDir subformats.
3400
Differs from BzrDirFormat._control_formats in that it provides sub-formats,
3401
e.g. BzrDirMeta1 with weave repository. Also, it's more user-oriented.
3405
"""Create a BzrDirFormatRegistry."""
3406
self._aliases = set()
3407
self._registration_order = list()
3408
super(BzrDirFormatRegistry, self).__init__()
3411
"""Return a set of the format names which are aliases."""
3412
return frozenset(self._aliases)
3414
def register_metadir(self, key,
3415
repository_format, help, native=True, deprecated=False,
3421
"""Register a metadir subformat.
3423
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
3424
by the Repository/Branch/WorkingTreeformats.
3426
:param repository_format: The fully-qualified repository format class
3428
:param branch_format: Fully-qualified branch format class name as
3430
:param tree_format: Fully-qualified tree format class name as
3433
# This should be expanded to support setting WorkingTree and Branch
3434
# formats, once BzrDirMetaFormat1 supports that.
3435
def _load(full_name):
3436
mod_name, factory_name = full_name.rsplit('.', 1)
3438
mod = __import__(mod_name, globals(), locals(),
3440
except ImportError, e:
3441
raise ImportError('failed to load %s: %s' % (full_name, e))
3443
factory = getattr(mod, factory_name)
3444
except AttributeError:
3445
raise AttributeError('no factory %s in module %r'
3450
bd = BzrDirMetaFormat1()
3451
if branch_format is not None:
3452
bd.set_branch_format(_load(branch_format))
3453
if tree_format is not None:
3454
bd.workingtree_format = _load(tree_format)
3455
if repository_format is not None:
3456
bd.repository_format = _load(repository_format)
3458
self.register(key, helper, help, native, deprecated, hidden,
3459
experimental, alias)
3461
def register(self, key, factory, help, native=True, deprecated=False,
3462
hidden=False, experimental=False, alias=False):
3463
"""Register a BzrDirFormat factory.
3465
The factory must be a callable that takes one parameter: the key.
3466
It must produce an instance of the BzrDirFormat when called.
3468
This function mainly exists to prevent the info object from being
3471
registry.Registry.register(self, key, factory, help,
3472
BzrDirFormatInfo(native, deprecated, hidden, experimental))
3474
self._aliases.add(key)
3475
self._registration_order.append(key)
3477
def register_lazy(self, key, module_name, member_name, help, native=True,
3478
deprecated=False, hidden=False, experimental=False, alias=False):
3479
registry.Registry.register_lazy(self, key, module_name, member_name,
3480
help, BzrDirFormatInfo(native, deprecated, hidden, experimental))
3482
self._aliases.add(key)
3483
self._registration_order.append(key)
3485
def set_default(self, key):
3486
"""Set the 'default' key to be a clone of the supplied key.
3488
This method must be called once and only once.
3490
registry.Registry.register(self, 'default', self.get(key),
3491
self.get_help(key), info=self.get_info(key))
3492
self._aliases.add('default')
3494
def set_default_repository(self, key):
3495
"""Set the FormatRegistry default and Repository default.
3497
This is a transitional method while Repository.set_default_format
3500
if 'default' in self:
3501
self.remove('default')
3502
self.set_default(key)
3503
format = self.get('default')()
3505
def make_bzrdir(self, key):
3506
return self.get(key)()
3508
def help_topic(self, topic):
3510
default_realkey = None
3511
default_help = self.get_help('default')
3513
for key in self._registration_order:
3514
if key == 'default':
3516
help = self.get_help(key)
3517
if help == default_help:
3518
default_realkey = key
3520
help_pairs.append((key, help))
3522
def wrapped(key, help, info):
3524
help = '(native) ' + help
3525
return ':%s:\n%s\n\n' % (key,
3526
textwrap.fill(help, initial_indent=' ',
3527
subsequent_indent=' ',
3528
break_long_words=False))
3529
if default_realkey is not None:
3530
output += wrapped(default_realkey, '(default) %s' % default_help,
3531
self.get_info('default'))
3532
deprecated_pairs = []
3533
experimental_pairs = []
3534
for key, help in help_pairs:
3535
info = self.get_info(key)
3538
elif info.deprecated:
3539
deprecated_pairs.append((key, help))
3540
elif info.experimental:
3541
experimental_pairs.append((key, help))
3543
output += wrapped(key, help, info)
3544
output += "\nSee :doc:`formats-help` for more about storage formats."
3546
if len(experimental_pairs) > 0:
3547
other_output += "Experimental formats are shown below.\n\n"
3548
for key, help in experimental_pairs:
3549
info = self.get_info(key)
3550
other_output += wrapped(key, help, info)
3553
"No experimental formats are available.\n\n"
3554
if len(deprecated_pairs) > 0:
3555
other_output += "\nDeprecated formats are shown below.\n\n"
3556
for key, help in deprecated_pairs:
3557
info = self.get_info(key)
3558
other_output += wrapped(key, help, info)
3561
"\nNo deprecated formats are available.\n\n"
3563
"\nSee :doc:`formats-help` for more about storage formats."
3565
if topic == 'other-formats':
1915
3571
class RepositoryAcquisitionPolicy(object):
2070
3725
return self._repository, False
2073
def register_metadir(registry, key,
2074
repository_format, help, native=True, deprecated=False,
2080
"""Register a metadir subformat.
2082
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
2083
by the Repository/Branch/WorkingTreeformats.
2085
:param repository_format: The fully-qualified repository format class
2087
:param branch_format: Fully-qualified branch format class name as
2089
:param tree_format: Fully-qualified tree format class name as
2092
# This should be expanded to support setting WorkingTree and Branch
2093
# formats, once BzrDirMetaFormat1 supports that.
2094
def _load(full_name):
2095
mod_name, factory_name = full_name.rsplit('.', 1)
2097
factory = pyutils.get_named_object(mod_name, factory_name)
2098
except ImportError, e:
2099
raise ImportError('failed to load %s: %s' % (full_name, e))
2100
except AttributeError:
2101
raise AttributeError('no factory %s in module %r'
2102
% (full_name, sys.modules[mod_name]))
2106
bd = BzrDirMetaFormat1()
2107
if branch_format is not None:
2108
bd.set_branch_format(_load(branch_format))
2109
if tree_format is not None:
2110
bd.workingtree_format = _load(tree_format)
2111
if repository_format is not None:
2112
bd.repository_format = _load(repository_format)
2114
registry.register(key, helper, help, native, deprecated, hidden,
2115
experimental, alias)
2117
register_metadir(controldir.format_registry, 'knit',
3728
# Please register new formats after old formats so that formats
3729
# appear in chronological order and format descriptions can build
3731
format_registry = BzrDirFormatRegistry()
3732
# The pre-0.8 formats have their repository format network name registered in
3733
# repository.py. MetaDir formats have their repository format network name
3734
# inferred from their disk format string.
3735
format_registry.register('weave', BzrDirFormat6,
3736
'Pre-0.8 format. Slower than knit and does not'
3737
' support checkouts or shared repositories.',
3740
format_registry.register_metadir('metaweave',
3741
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3742
'Transitional format in 0.8. Slower than knit.',
3743
branch_format='bzrlib.branch.BzrBranchFormat5',
3744
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3747
format_registry.register_metadir('knit',
2118
3748
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2119
3749
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
2120
3750
branch_format='bzrlib.branch.BzrBranchFormat5',
2121
tree_format='bzrlib.workingtree_3.WorkingTreeFormat3',
3751
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
2123
3753
deprecated=True)
2124
register_metadir(controldir.format_registry, 'dirstate',
3754
format_registry.register_metadir('dirstate',
2125
3755
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2126
3756
help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
2127
3757
'above when accessed over the network.',
2128
3758
branch_format='bzrlib.branch.BzrBranchFormat5',
2129
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3759
# this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
3760
# directly from workingtree_4 triggers a circular import.
3761
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2131
3763
deprecated=True)
2132
register_metadir(controldir.format_registry, 'dirstate-tags',
3764
format_registry.register_metadir('dirstate-tags',
2133
3765
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2134
3766
help='New in 0.15: Fast local operations and improved scaling for '
2135
3767
'network operations. Additionally adds support for tags.'
2136
3768
' Incompatible with bzr < 0.15.',
2137
3769
branch_format='bzrlib.branch.BzrBranchFormat6',
2138
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3770
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2140
3772
deprecated=True)
2141
register_metadir(controldir.format_registry, 'rich-root',
3773
format_registry.register_metadir('rich-root',
2142
3774
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
2143
3775
help='New in 1.0. Better handling of tree roots. Incompatible with'
2145
3777
branch_format='bzrlib.branch.BzrBranchFormat6',
2146
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3778
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2148
3780
deprecated=True)
2149
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
3781
format_registry.register_metadir('dirstate-with-subtree',
2150
3782
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2151
3783
help='New in 0.15: Fast local operations and improved scaling for '
2152
3784
'network operations. Additionally adds support for versioning nested '
2153
3785
'bzr branches. Incompatible with bzr < 0.15.',
2154
3786
branch_format='bzrlib.branch.BzrBranchFormat6',
2155
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3787
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2156
3788
experimental=True,
2159
register_metadir(controldir.format_registry, 'pack-0.92',
2160
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
3791
format_registry.register_metadir('pack-0.92',
3792
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
2161
3793
help='New in 0.92: Pack-based format with data compatible with '
2162
3794
'dirstate-tags format repositories. Interoperates with '
2163
3795
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2165
3797
branch_format='bzrlib.branch.BzrBranchFormat6',
2166
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3798
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2168
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2169
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
3800
format_registry.register_metadir('pack-0.92-subtree',
3801
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
2170
3802
help='New in 0.92: Pack-based format with data compatible with '
2171
3803
'dirstate-with-subtree format repositories. Interoperates with '
2172
3804
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2174
3806
branch_format='bzrlib.branch.BzrBranchFormat6',
2175
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3807
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2177
3809
experimental=True,
2179
register_metadir(controldir.format_registry, 'rich-root-pack',
2180
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
3811
format_registry.register_metadir('rich-root-pack',
3812
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
2181
3813
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
2182
3814
'(needed for bzr-svn and bzr-git).',
2183
3815
branch_format='bzrlib.branch.BzrBranchFormat6',
2184
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3816
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2187
register_metadir(controldir.format_registry, '1.6',
2188
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
3819
format_registry.register_metadir('1.6',
3820
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
2189
3821
help='A format that allows a branch to indicate that there is another '
2190
3822
'(stacked) repository that should be used to access data that is '
2191
3823
'not present locally.',
2192
3824
branch_format='bzrlib.branch.BzrBranchFormat7',
2193
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3825
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2196
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2197
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
3828
format_registry.register_metadir('1.6.1-rich-root',
3829
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
2198
3830
help='A variant of 1.6 that supports rich-root data '
2199
3831
'(needed for bzr-svn and bzr-git).',
2200
3832
branch_format='bzrlib.branch.BzrBranchFormat7',
2201
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3833
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2204
register_metadir(controldir.format_registry, '1.9',
2205
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
3836
format_registry.register_metadir('1.9',
3837
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
2206
3838
help='A repository format using B+tree indexes. These indexes '
2207
3839
'are smaller in size, have smarter caching and provide faster '
2208
3840
'performance for most operations.',
2209
3841
branch_format='bzrlib.branch.BzrBranchFormat7',
2210
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3842
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2213
register_metadir(controldir.format_registry, '1.9-rich-root',
2214
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
3845
format_registry.register_metadir('1.9-rich-root',
3846
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
2215
3847
help='A variant of 1.9 that supports rich-root data '
2216
3848
'(needed for bzr-svn and bzr-git).',
2217
3849
branch_format='bzrlib.branch.BzrBranchFormat7',
2218
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3850
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2221
register_metadir(controldir.format_registry, '1.14',
2222
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
3853
format_registry.register_metadir('1.14',
3854
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
2223
3855
help='A working-tree format that supports content filtering.',
2224
3856
branch_format='bzrlib.branch.BzrBranchFormat7',
2225
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
3857
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2227
register_metadir(controldir.format_registry, '1.14-rich-root',
2228
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
3859
format_registry.register_metadir('1.14-rich-root',
3860
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
2229
3861
help='A variant of 1.14 that supports rich-root data '
2230
3862
'(needed for bzr-svn and bzr-git).',
2231
3863
branch_format='bzrlib.branch.BzrBranchFormat7',
2232
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
3864
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2234
3866
# The following un-numbered 'development' formats should always just be aliases.
2235
register_metadir(controldir.format_registry, 'development-subtree',
2236
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2aSubtree',
3867
format_registry.register_metadir('development-rich-root',
3868
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3869
help='Current development format. Supports rich roots. Can convert data '
3870
'to and from rich-root-pack (and anything compatible with '
3871
'rich-root-pack) format repositories. Repositories and branches in '
3872
'this format can only be read by bzr.dev. Please read '
3873
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3875
branch_format='bzrlib.branch.BzrBranchFormat7',
3876
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3881
format_registry.register_metadir('development-subtree',
3882
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
2237
3883
help='Current development format, subtree variant. Can convert data to and '
2238
3884
'from pack-0.92-subtree (and anything compatible with '
2239
3885
'pack-0.92-subtree) format repositories. Repositories and branches in '