253
232
t = _mod_transport.get_transport(url)
236
def find_bzrdirs(transport, evaluate=None, list_current=None):
237
"""Find bzrdirs recursively from current location.
239
This is intended primarily as a building block for more sophisticated
240
functionality, like finding trees under a directory, or finding
241
branches that use a given repository.
242
:param evaluate: An optional callable that yields recurse, value,
243
where recurse controls whether this bzrdir is recursed into
244
and value is the value to yield. By default, all bzrdirs
245
are recursed into, and the return value is the bzrdir.
246
:param list_current: if supplied, use this function to list the current
247
directory, instead of Transport.list_dir
248
:return: a generator of found bzrdirs, or whatever evaluate returns.
250
if list_current is None:
251
def list_current(transport):
252
return transport.list_dir('')
254
def evaluate(bzrdir):
257
pending = [transport]
258
while len(pending) > 0:
259
current_transport = pending.pop()
262
bzrdir = BzrDir.open_from_transport(current_transport)
263
except (errors.NotBranchError, errors.PermissionDenied):
266
recurse, value = evaluate(bzrdir)
269
subdirs = list_current(current_transport)
270
except (errors.NoSuchFile, errors.PermissionDenied):
273
for subdir in sorted(subdirs, reverse=True):
274
pending.append(current_transport.clone(subdir))
277
def find_branches(transport):
278
"""Find all branches under a transport.
280
This will find all branches below the transport, including branches
281
inside other branches. Where possible, it will use
282
Repository.find_branches.
284
To list all the branches that use a particular Repository, see
285
Repository.find_branches
287
def evaluate(bzrdir):
289
repository = bzrdir.open_repository()
290
except errors.NoRepositoryPresent:
293
return False, ([], repository)
294
return True, (bzrdir.list_branches(), None)
296
for branches, repo in BzrDir.find_bzrdirs(transport,
299
ret.extend(repo.find_branches())
300
if branches is not None:
305
def create_branch_and_repo(base, force_new_repo=False, format=None):
306
"""Create a new BzrDir, Branch and Repository at the url 'base'.
308
This will use the current default BzrDirFormat unless one is
309
specified, and use whatever
310
repository format that that uses via bzrdir.create_branch and
311
create_repository. If a shared repository is available that is used
314
The created Branch object is returned.
316
:param base: The URL to create the branch at.
317
:param force_new_repo: If True a new repository is always created.
318
:param format: If supplied, the format of branch to create. If not
319
supplied, the default is used.
321
bzrdir = BzrDir.create(base, format)
322
bzrdir._find_or_create_repository(force_new_repo)
323
return bzrdir.create_branch()
256
325
def determine_repository_policy(self, force_new_repo=False, stack_on=None,
257
326
stack_on_pwd=None, require_stacking=False):
258
327
"""Return an object representing a policy to use.
376
441
location of this control directory.
377
442
:param create_tree_if_local: If true, a working-tree will be created
378
443
when working locally.
379
:return: The created control directory
381
with contextlib.ExitStack() as stack:
382
fetch_spec_factory = fetch.FetchSpecFactory()
383
if revision_id is not None:
384
fetch_spec_factory.add_revision_ids([revision_id])
385
fetch_spec_factory.source_branch_stop_revision_id = revision_id
386
if possible_transports is None:
387
possible_transports = []
389
possible_transports = list(possible_transports) + [
391
target_transport = _mod_transport.get_transport(url,
393
target_transport.ensure_base()
394
cloning_format = self.cloning_metadir(stacked)
395
# Create/update the result branch
397
result = controldir.ControlDir.open_from_transport(
399
except errors.NotBranchError:
400
result = cloning_format.initialize_on_transport(target_transport)
401
source_branch, source_repository = self._find_source_repo(
402
stack, source_branch)
403
fetch_spec_factory.source_branch = source_branch
404
# if a stacked branch wasn't requested, we don't create one
405
# even if the origin was stacked
406
if stacked and source_branch is not None:
407
stacked_branch_url = self.root_transport.base
409
stacked_branch_url = None
410
repository_policy = result.determine_repository_policy(
411
force_new_repo, stacked_branch_url, require_stacking=stacked)
412
result_repo, is_new_repo = repository_policy.acquire_repository(
413
possible_transports=possible_transports)
414
stack.enter_context(result_repo.lock_write())
415
fetch_spec_factory.source_repo = source_repository
416
fetch_spec_factory.target_repo = result_repo
417
if stacked or (len(result_repo._fallback_repositories) != 0):
418
target_repo_kind = fetch.TargetRepoKinds.STACKED
420
target_repo_kind = fetch.TargetRepoKinds.EMPTY
422
target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
423
fetch_spec_factory.target_repo_kind = target_repo_kind
424
if source_repository is not None:
425
fetch_spec = fetch_spec_factory.make_fetch_spec()
426
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
428
if source_branch is None:
429
# this is for sprouting a controldir without a branch; is that
431
# Not especially, but it's part of the contract.
432
result_branch = result.create_branch()
433
if revision_id is not None:
434
result_branch.generate_revision_history(revision_id)
436
result_branch = source_branch.sprout(
437
result, revision_id=revision_id,
438
repository_policy=repository_policy, repository=result_repo)
439
mutter("created new branch %r" % (result_branch,))
441
# Create/update the result working tree
442
if (create_tree_if_local and not result.has_workingtree()
443
and isinstance(target_transport, local.LocalTransport)
444
and (result_repo is None or result_repo.make_working_trees())
445
and result.open_branch(
447
possible_transports=possible_transports).name == result_branch.name):
448
wt = result.create_workingtree(
449
accelerator_tree=accelerator_tree, hardlink=hardlink,
450
from_branch=result_branch)
451
with wt.lock_write():
452
if not wt.is_versioned(''):
454
wt.set_root_id(self.open_workingtree.path2id(''))
455
except errors.NoWorkingTree:
459
if recurse == 'down':
463
basis = tree.basis_tree()
464
stack.enter_context(basis.lock_read())
465
elif result_branch is not None:
466
basis = tree = result_branch.basis_tree()
467
elif source_branch is not None:
468
basis = tree = source_branch.basis_tree()
470
stack.enter_context(tree.lock_read())
471
subtrees = tree.iter_references()
474
for path in subtrees:
475
target = urlutils.join(url, urlutils.escape(path))
476
sublocation = tree.reference_parent(
477
path, branch=result_branch,
478
possible_transports=possible_transports)
479
if sublocation is None:
481
'Ignoring nested tree %s, parent location unknown.',
484
sublocation.controldir.sprout(
485
target, basis.get_reference_revision(path),
486
force_new_repo=force_new_repo, recurse=recurse,
445
operation = cleanup.OperationWithCleanups(self._sprout)
446
return operation.run(url, revision_id=revision_id,
447
force_new_repo=force_new_repo, recurse=recurse,
448
possible_transports=possible_transports,
449
accelerator_tree=accelerator_tree, hardlink=hardlink,
450
stacked=stacked, source_branch=source_branch,
451
create_tree_if_local=create_tree_if_local)
453
def _sprout(self, op, url, revision_id=None, force_new_repo=False,
454
recurse='down', possible_transports=None,
455
accelerator_tree=None, hardlink=False, stacked=False,
456
source_branch=None, create_tree_if_local=True):
457
add_cleanup = op.add_cleanup
458
fetch_spec_factory = fetch.FetchSpecFactory()
459
if revision_id is not None:
460
fetch_spec_factory.add_revision_ids([revision_id])
461
fetch_spec_factory.source_branch_stop_revision_id = revision_id
462
target_transport = _mod_transport.get_transport(url,
464
target_transport.ensure_base()
465
cloning_format = self.cloning_metadir(stacked)
466
# Create/update the result branch
467
result = cloning_format.initialize_on_transport(target_transport)
468
source_branch, source_repository = self._find_source_repo(
469
add_cleanup, source_branch)
470
fetch_spec_factory.source_branch = source_branch
471
# if a stacked branch wasn't requested, we don't create one
472
# even if the origin was stacked
473
if stacked and source_branch is not None:
474
stacked_branch_url = self.root_transport.base
476
stacked_branch_url = None
477
repository_policy = result.determine_repository_policy(
478
force_new_repo, stacked_branch_url, require_stacking=stacked)
479
result_repo, is_new_repo = repository_policy.acquire_repository()
480
add_cleanup(result_repo.lock_write().unlock)
481
fetch_spec_factory.source_repo = source_repository
482
fetch_spec_factory.target_repo = result_repo
483
if stacked or (len(result_repo._fallback_repositories) != 0):
484
target_repo_kind = fetch.TargetRepoKinds.STACKED
486
target_repo_kind = fetch.TargetRepoKinds.EMPTY
488
target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
489
fetch_spec_factory.target_repo_kind = target_repo_kind
490
if source_repository is not None:
491
fetch_spec = fetch_spec_factory.make_fetch_spec()
492
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
494
if source_branch is None:
495
# this is for sprouting a controldir without a branch; is that
497
# Not especially, but it's part of the contract.
498
result_branch = result.create_branch()
500
result_branch = source_branch.sprout(result,
501
revision_id=revision_id, repository_policy=repository_policy,
502
repository=result_repo)
503
mutter("created new branch %r" % (result_branch,))
505
# Create/update the result working tree
506
if (create_tree_if_local and
507
isinstance(target_transport, local.LocalTransport) and
508
(result_repo is None or result_repo.make_working_trees())):
509
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
510
hardlink=hardlink, from_branch=result_branch)
513
if wt.path2id('') is None:
515
wt.set_root_id(self.open_workingtree.get_root_id())
516
except errors.NoWorkingTree:
522
if recurse == 'down':
525
basis = wt.basis_tree()
526
elif result_branch is not None:
527
basis = result_branch.basis_tree()
528
elif source_branch is not None:
529
basis = source_branch.basis_tree()
530
if basis is not None:
531
add_cleanup(basis.lock_read().unlock)
532
subtrees = basis.iter_references()
535
for path, file_id in subtrees:
536
target = urlutils.join(url, urlutils.escape(path))
537
sublocation = source_branch.reference_parent(file_id, path)
538
sublocation.bzrdir.sprout(target,
539
basis.get_reference_revision(file_id, path),
540
force_new_repo=force_new_repo, recurse=recurse,
547
def create_branch_convenience(base, force_new_repo=False,
548
force_new_tree=None, format=None,
549
possible_transports=None):
550
"""Create a new BzrDir, Branch and Repository at the url 'base'.
552
This is a convenience function - it will use an existing repository
553
if possible, can be told explicitly whether to create a working tree or
556
This will use the current default BzrDirFormat unless one is
557
specified, and use whatever
558
repository format that that uses via bzrdir.create_branch and
559
create_repository. If a shared repository is available that is used
560
preferentially. Whatever repository is used, its tree creation policy
563
The created Branch object is returned.
564
If a working tree cannot be made due to base not being a file:// url,
565
no error is raised unless force_new_tree is True, in which case no
566
data is created on disk and NotLocalUrl is raised.
568
:param base: The URL to create the branch at.
569
:param force_new_repo: If True a new repository is always created.
570
:param force_new_tree: If True or False force creation of a tree or
571
prevent such creation respectively.
572
:param format: Override for the bzrdir format to create.
573
:param possible_transports: An optional reusable transports list.
576
# check for non local urls
577
t = _mod_transport.get_transport(base, possible_transports)
578
if not isinstance(t, local.LocalTransport):
579
raise errors.NotLocalUrl(base)
580
bzrdir = BzrDir.create(base, format, possible_transports)
581
repo = bzrdir._find_or_create_repository(force_new_repo)
582
result = bzrdir.create_branch()
583
if force_new_tree or (repo.make_working_trees() and
584
force_new_tree is None):
586
bzrdir.create_workingtree()
587
except errors.NotLocalUrl:
592
def create_standalone_workingtree(base, format=None):
593
"""Create a new BzrDir, WorkingTree, Branch and Repository at 'base'.
595
'base' must be a local path or a file:// url.
597
This will use the current default BzrDirFormat unless one is
598
specified, and use whatever
599
repository format that that uses for bzrdirformat.create_workingtree,
600
create_branch and create_repository.
602
:param format: Override for the bzrdir format to create.
603
:return: The WorkingTree object.
605
t = _mod_transport.get_transport(base)
606
if not isinstance(t, local.LocalTransport):
607
raise errors.NotLocalUrl(base)
608
bzrdir = BzrDir.create_branch_and_repo(base,
610
format=format).bzrdir
611
return bzrdir.create_workingtree()
613
@deprecated_method(deprecated_in((2, 3, 0)))
614
def generate_backup_name(self, base):
615
return self._available_backup_name(base)
490
617
def _available_backup_name(self, base):
491
618
"""Find a non-existing backup file name based on base.
493
See breezy.osutils.available_backup_name about race conditions.
620
See bzrlib.osutils.available_backup_name about race conditions.
495
622
return osutils.available_backup_name(base, self.root_transport.has)
666
794
def control_transport(self):
667
795
return self.transport
797
def is_control_filename(self, filename):
798
"""True if filename is the name of a path which is reserved for bzrdir's.
800
:param filename: A filename within the root transport of this bzrdir.
802
This is true IF and ONLY IF the filename is part of the namespace reserved
803
for bzr control dirs. Currently this is the '.bzr' directory in the root
804
of the root_transport.
806
# this might be better on the BzrDirFormat class because it refers to
807
# all the possible bzrdir disk formats.
808
# This method is tested via the workingtree is_control_filename tests-
809
# it was extracted from WorkingTree.is_control_filename. If the method's
810
# contract is extended beyond the current trivial implementation, please
811
# add new tests for it to the appropriate place.
812
return filename == '.bzr' or filename.startswith('.bzr/')
815
def open_unsupported(base):
816
"""Open a branch which is not supported."""
817
return BzrDir.open(base, _unsupported=True)
820
def open(base, _unsupported=False, possible_transports=None):
821
"""Open an existing bzrdir, rooted at 'base' (url).
823
:param _unsupported: a private parameter to the BzrDir class.
825
t = _mod_transport.get_transport(base, possible_transports)
826
return BzrDir.open_from_transport(t, _unsupported=_unsupported)
829
def open_from_transport(transport, _unsupported=False,
830
_server_formats=True):
831
"""Open a bzrdir within a particular directory.
833
:param transport: Transport containing the bzrdir.
834
:param _unsupported: private.
836
for hook in BzrDir.hooks['pre_open']:
838
# Keep initial base since 'transport' may be modified while following
840
base = transport.base
841
def find_format(transport):
842
return transport, controldir.ControlDirFormat.find_format(
843
transport, _server_formats=_server_formats)
845
def redirected(transport, e, redirection_notice):
846
redirected_transport = transport._redirected_to(e.source, e.target)
847
if redirected_transport is None:
848
raise errors.NotBranchError(base)
849
note('%s is%s redirected to %s',
850
transport.base, e.permanently, redirected_transport.base)
851
return redirected_transport
854
transport, format = do_catching_redirections(find_format,
857
except errors.TooManyRedirections:
858
raise errors.NotBranchError(base)
860
format.check_support_status(_unsupported)
861
return format.open(transport, _found=True)
864
def open_containing(url, possible_transports=None):
865
"""Open an existing branch which contains url.
867
:param url: url to search from.
868
See open_containing_from_transport for more detail.
870
transport = _mod_transport.get_transport(url, possible_transports)
871
return BzrDir.open_containing_from_transport(transport)
874
def open_containing_from_transport(a_transport):
875
"""Open an existing branch which contains a_transport.base.
877
This probes for a branch at a_transport, and searches upwards from there.
879
Basically we keep looking up until we find the control directory or
880
run into the root. If there isn't one, raises NotBranchError.
881
If there is one and it is either an unrecognised format or an unsupported
882
format, UnknownFormatError or UnsupportedFormatError are raised.
883
If there is one, it is returned, along with the unused portion of url.
885
:return: The BzrDir that contains the path, and a Unicode path
886
for the rest of the URL.
888
# this gets the normalised url back. I.e. '.' -> the full path.
889
url = a_transport.base
892
result = BzrDir.open_from_transport(a_transport)
893
return result, urlutils.unescape(a_transport.relpath(url))
894
except errors.NotBranchError, e:
897
new_t = a_transport.clone('..')
898
except errors.InvalidURLJoin:
899
# reached the root, whatever that may be
900
raise errors.NotBranchError(path=url)
901
if new_t.base == a_transport.base:
902
# reached the root, whatever that may be
903
raise errors.NotBranchError(path=url)
907
def open_tree_or_branch(klass, location):
908
"""Return the branch and working tree at a location.
910
If there is no tree at the location, tree will be None.
911
If there is no branch at the location, an exception will be
913
:return: (tree, branch)
915
bzrdir = klass.open(location)
916
return bzrdir._get_tree_branch()
919
def open_containing_tree_or_branch(klass, location):
920
"""Return the branch and working tree contained by a location.
922
Returns (tree, branch, relpath).
923
If there is no tree at containing the location, tree will be None.
924
If there is no branch containing the location, an exception will be
926
relpath is the portion of the path that is contained by the branch.
928
bzrdir, relpath = klass.open_containing(location)
929
tree, branch = bzrdir._get_tree_branch()
930
return tree, branch, relpath
933
def open_containing_tree_branch_or_repository(klass, location):
934
"""Return the working tree, branch and repo contained by a location.
936
Returns (tree, branch, repository, relpath).
937
If there is no tree containing the location, tree will be None.
938
If there is no branch containing the location, branch will be None.
939
If there is no repository containing the location, repository will be
941
relpath is the portion of the path that is contained by the innermost
944
If no tree, branch or repository is found, a NotBranchError is raised.
946
bzrdir, relpath = klass.open_containing(location)
948
tree, branch = bzrdir._get_tree_branch()
949
except errors.NotBranchError:
951
repo = bzrdir.find_repository()
952
return None, None, repo, relpath
953
except (errors.NoRepositoryPresent):
954
raise errors.NotBranchError(location)
955
return tree, branch, branch.repository, relpath
669
957
def _cloning_metadir(self):
670
958
"""Produce a metadir suitable for cloning with.
769
1075
raise NotImplementedError(self.get_workingtree_transport)
772
def create(cls, base, format=None, possible_transports=None):
773
"""Create a new BzrDir at the url 'base'.
775
:param format: If supplied, the format of branch to create. If not
776
supplied, the default is used.
777
:param possible_transports: If supplied, a list of transports that
778
can be reused to share a remote connection.
1078
class BzrDirHooks(hooks.Hooks):
1079
"""Hooks for BzrDir operations."""
1082
"""Create the default hooks."""
1083
hooks.Hooks.__init__(self, "bzrlib.bzrdir", "BzrDir.hooks")
1084
self.add_hook('pre_open',
1085
"Invoked before attempting to open a BzrDir with the transport "
1086
"that the open will use.", (1, 14))
1087
self.add_hook('post_repo_init',
1088
"Invoked after a repository has been initialized. "
1089
"post_repo_init is called with a "
1090
"bzrlib.bzrdir.RepoInitHookParams.",
1093
# install the default hooks
1094
BzrDir.hooks = BzrDirHooks()
1097
class RepoInitHookParams(object):
1098
"""Object holding parameters passed to *_repo_init hooks.
1100
There are 4 fields that hooks may wish to access:
1102
:ivar repository: Repository created
1103
:ivar format: Repository format
1104
:ivar bzrdir: The bzrdir for the repository
1105
:ivar shared: The repository is shared
1108
def __init__(self, repository, format, a_bzrdir, shared):
1109
"""Create a group of RepoInitHook parameters.
1111
:param repository: Repository created
1112
:param format: Repository format
1113
:param bzrdir: The bzrdir for the repository
1114
:param shared: The repository is shared
780
if cls is not BzrDir:
781
raise AssertionError("BzrDir.create always creates the "
782
"default format, not one of %r" % cls)
783
return controldir.ControlDir.create(
784
base, format=format, possible_transports=possible_transports)
1116
self.repository = repository
1117
self.format = format
1118
self.bzrdir = a_bzrdir
1119
self.shared = shared
1121
def __eq__(self, other):
1122
return self.__dict__ == other.__dict__
786
1124
def __repr__(self):
787
return "<%s at %r>" % (self.__class__.__name__, self.user_url)
789
def update_feature_flags(self, updated_flags):
790
"""Update the features required by this bzrdir.
792
:param updated_flags: Dictionary mapping feature names to necessities
793
A necessity can be None to indicate the feature should be removed
795
self.control_files.lock_write()
797
self._format._update_feature_flags(updated_flags)
798
self.transport.put_bytes('branch-format', self._format.as_string())
800
self.control_files.unlock()
1126
return "<%s for %s>" % (self.__class__.__name__,
1129
return "<%s for %s>" % (self.__class__.__name__,
803
1133
class BzrDirMeta1(BzrDir):
809
1139
present within a BzrDir.
812
def _get_branch_path(self, name):
813
"""Obtain the branch path to use.
815
This uses the API specified branch name first, and then falls back to
816
the branch name specified in the URL. If neither of those is specified,
817
it uses the default branch.
819
:param name: Optional branch name to use
820
:return: Relative path to branch
824
return urlutils.join('branches', urlutils.escape(name))
826
def _read_branch_list(self):
827
"""Read the branch list.
829
:return: List of branch names.
832
f = self.control_transport.get('branch-list')
833
except errors.NoSuchFile:
839
ret.append(name.rstrip(b"\n").decode('utf-8'))
844
def _write_branch_list(self, branches):
845
"""Write out the branch list.
847
:param branches: List of utf-8 branch names to write
849
self.transport.put_bytes(
851
b"".join([name.encode('utf-8') + b"\n" for name in branches]))
853
def __init__(self, _transport, _format):
854
super(BzrDirMeta1, self).__init__(_transport, _format)
855
self.control_files = lockable_files.LockableFiles(
856
self.control_transport, self._format._lock_file_name,
857
self._format._lock_class)
859
1142
def can_convert_format(self):
860
1143
"""See BzrDir.can_convert_format()."""
863
def create_branch(self, name=None, repository=None,
864
append_revisions_only=None):
865
"""See ControlDir.create_branch."""
867
name = self._get_selected_branch()
868
return self._format.get_branch_format().initialize(
869
self, name=name, repository=repository,
870
append_revisions_only=append_revisions_only)
1146
def create_branch(self, name=None, repository=None):
1147
"""See BzrDir.create_branch."""
1148
return self._format.get_branch_format().initialize(self, name=name,
1149
repository=repository)
872
1151
def destroy_branch(self, name=None):
873
"""See ControlDir.destroy_branch."""
875
name = self._get_selected_branch()
876
path = self._get_branch_path(name)
878
self.control_files.lock_write()
880
branches = self._read_branch_list()
882
branches.remove(name)
884
raise errors.NotBranchError(name)
885
self._write_branch_list(branches)
887
self.control_files.unlock()
889
self.transport.delete_tree(path)
890
except errors.NoSuchFile:
891
raise errors.NotBranchError(
892
path=urlutils.join(self.transport.base, path), controldir=self)
1152
"""See BzrDir.create_branch."""
1153
if name is not None:
1154
raise errors.NoColocatedBranchSupport(self)
1155
self.transport.delete_tree('branch')
894
1157
def create_repository(self, shared=False):
895
1158
"""See BzrDir.create_repository."""
929
1189
This might be a synthetic object for e.g. RemoteBranch and SVN.
931
from .branch import BranchFormatMetadir
932
return BranchFormatMetadir.find_format(self, name=name)
1191
from bzrlib.branch import BranchFormat
1192
return BranchFormat.find_format(self, name=name)
934
1194
def _get_mkdir_mode(self):
935
1195
"""Figure out the mode to use when creating a bzrdir subdir."""
936
temp_control = lockable_files.LockableFiles(
937
self.transport, '', lockable_files.TransportLock)
1196
temp_control = lockable_files.LockableFiles(self.transport, '',
1197
lockable_files.TransportLock)
938
1198
return temp_control._dir_mode
940
1200
def get_branch_reference(self, name=None):
941
1201
"""See BzrDir.get_branch_reference()."""
942
from .branch import BranchFormatMetadir
943
format = BranchFormatMetadir.find_format(self, name=name)
1202
from bzrlib.branch import BranchFormat
1203
format = BranchFormat.find_format(self, name=name)
944
1204
return format.get_reference(self, name=name)
946
def set_branch_reference(self, target_branch, name=None):
947
format = _mod_bzrbranch.BranchReferenceFormat()
948
if (self.control_url == target_branch.controldir.control_url
949
and name == target_branch.name):
950
raise controldir.BranchReferenceLoop(target_branch)
951
return format.initialize(self, target_branch=target_branch, name=name)
953
1206
def get_branch_transport(self, branch_format, name=None):
954
1207
"""See BzrDir.get_branch_transport()."""
956
name = self._get_selected_branch()
957
path = self._get_branch_path(name)
1208
if name is not None:
1209
raise errors.NoColocatedBranchSupport(self)
958
1210
# XXX: this shouldn't implicitly create the directory if it's just
959
1211
# promising to get a transport -- mbp 20090727
960
1212
if branch_format is None:
961
return self.transport.clone(path)
1213
return self.transport.clone('branch')
963
1215
branch_format.get_format_string()
964
1216
except NotImplementedError:
965
1217
raise errors.IncompatibleFormat(branch_format, self._format)
967
branches = self._read_branch_list()
968
if name not in branches:
969
self.control_files.lock_write()
971
branches = self._read_branch_list()
972
dirname = urlutils.dirname(name)
973
if dirname != u"" and dirname in branches:
974
raise errors.ParentBranchExists(name)
976
b.startswith(name + u"/") for b in branches]
977
if any(child_branches):
978
raise errors.AlreadyBranchError(name)
979
branches.append(name)
980
self._write_branch_list(branches)
982
self.control_files.unlock()
983
branch_transport = self.transport.clone(path)
984
mode = self._get_mkdir_mode()
985
branch_transport.create_prefix(mode=mode)
987
self.transport.mkdir(path, mode=mode)
1219
self.transport.mkdir('branch', mode=self._get_mkdir_mode())
988
1220
except errors.FileExists:
990
return self.transport.clone(path)
1222
return self.transport.clone('branch')
992
1224
def get_repository_transport(self, repository_format):
993
1225
"""See BzrDir.get_repository_transport()."""
1087
1296
def open_branch(self, name=None, unsupported=False,
1088
ignore_fallbacks=False, possible_transports=None):
1089
"""See ControlDir.open_branch."""
1091
name = self._get_selected_branch()
1297
ignore_fallbacks=False):
1298
"""See BzrDir.open_branch."""
1092
1299
format = self.find_branch_format(name=name)
1093
1300
format.check_support_status(unsupported)
1094
if possible_transports is None:
1095
possible_transports = []
1097
possible_transports = list(possible_transports)
1098
possible_transports.append(self.root_transport)
1099
1301
return format.open(self, name=name,
1100
_found=True, ignore_fallbacks=ignore_fallbacks,
1101
possible_transports=possible_transports)
1302
_found=True, ignore_fallbacks=ignore_fallbacks)
1103
1304
def open_repository(self, unsupported=False):
1104
1305
"""See BzrDir.open_repository."""
1105
from .repository import RepositoryFormatMetaDir
1106
format = RepositoryFormatMetaDir.find_format(self)
1306
from bzrlib.repository import RepositoryFormat
1307
format = RepositoryFormat.find_format(self)
1107
1308
format.check_support_status(unsupported)
1108
1309
return format.open(self, _found=True)
1110
1311
def open_workingtree(self, unsupported=False,
1111
recommend_upgrade=True):
1312
recommend_upgrade=True):
1112
1313
"""See BzrDir.open_workingtree."""
1113
from .workingtree import WorkingTreeFormatMetaDir
1114
format = WorkingTreeFormatMetaDir.find_format(self)
1314
from bzrlib.workingtree import WorkingTreeFormat
1315
format = WorkingTreeFormat.find_format(self)
1115
1316
format.check_support_status(unsupported, recommend_upgrade,
1116
basedir=self.root_transport.base)
1317
basedir=self.root_transport.base)
1117
1318
return format.open(self, _found=True)
1119
1320
def _get_config(self):
1120
1321
return config.TransportConfig(self.transport, 'control.conf')
1123
class BzrFormat(object):
1124
"""Base class for all formats of things living in metadirs.
1126
This class manages the format string that is stored in the 'format'
1127
or 'branch-format' file.
1129
All classes for (branch-, repository-, workingtree-) formats that
1130
live in meta directories and have their own 'format' file
1131
(i.e. different from .bzr/branch-format) derive from this class,
1132
as well as the relevant base class for their kind
1133
(BranchFormat, WorkingTreeFormat, RepositoryFormat).
1135
Each format is identified by a "format" or "branch-format" file with a
1136
single line containing the base format name and then an optional list of
1139
Feature flags are supported as of bzr 2.5. Setting feature flags on formats
1140
will render them inaccessible to older versions of bzr.
1142
:ivar features: Dictionary mapping feature names to their necessity
1145
_present_features = set()
1151
def register_feature(cls, name):
1152
"""Register a feature as being present.
1154
:param name: Name of the feature
1157
raise ValueError("spaces are not allowed in feature names")
1158
if name in cls._present_features:
1159
raise FeatureAlreadyRegistered(name)
1160
cls._present_features.add(name)
1163
def unregister_feature(cls, name):
1164
"""Unregister a feature."""
1165
cls._present_features.remove(name)
1167
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1169
for name, necessity in self.features.items():
1170
if name in self._present_features:
1172
if necessity == b"optional":
1173
mutter("ignoring optional missing feature %s", name)
1175
elif necessity == b"required":
1176
raise MissingFeature(name)
1178
mutter("treating unknown necessity as require for %s",
1180
raise MissingFeature(name)
1183
def get_format_string(cls):
1184
"""Return the ASCII format string that identifies this format."""
1185
raise NotImplementedError(cls.get_format_string)
1188
def from_string(cls, text):
1189
format_string = cls.get_format_string()
1190
if not text.startswith(format_string):
1191
raise AssertionError(
1192
"Invalid format header %r for %r" % (text, cls))
1193
lines = text[len(format_string):].splitlines()
1195
for lineno, line in enumerate(lines):
1197
(necessity, feature) = line.split(b" ", 1)
1199
raise errors.ParseFormatError(format=cls, lineno=lineno + 2,
1200
line=line, text=text)
1201
ret.features[feature] = necessity
1204
def as_string(self):
1205
"""Return the string representation of this format.
1207
lines = [self.get_format_string()]
1208
lines.extend([(item[1] + b" " + item[0] + b"\n")
1209
for item in sorted(self.features.items())])
1210
return b"".join(lines)
1213
def _find_format(klass, registry, kind, format_string):
1215
first_line = format_string[:format_string.index(b"\n") + 1]
1217
first_line = format_string
1219
cls = registry.get(first_line)
1324
class BzrProber(controldir.Prober):
1325
"""Prober for formats that use a .bzr/ control directory."""
1327
formats = registry.FormatRegistry(controldir.network_format_registry)
1328
"""The known .bzr formats."""
1331
@deprecated_method(deprecated_in((2, 4, 0)))
1332
def register_bzrdir_format(klass, format):
1333
klass.formats.register(format.get_format_string(), format)
1336
@deprecated_method(deprecated_in((2, 4, 0)))
1337
def unregister_bzrdir_format(klass, format):
1338
klass.formats.remove(format.get_format_string())
1341
def probe_transport(klass, transport):
1342
"""Return the .bzrdir style format present in a directory."""
1344
format_string = transport.get_bytes(".bzr/branch-format")
1345
except errors.NoSuchFile:
1346
raise errors.NotBranchError(path=transport.base)
1348
return klass.formats.get(format_string)
1220
1349
except KeyError:
1221
raise errors.UnknownFormatError(format=first_line, kind=kind)
1222
return cls.from_string(format_string)
1224
def network_name(self):
1225
"""A simple byte string uniquely identifying this format for RPC calls.
1227
Metadir branch formats use their format string.
1229
return self.as_string()
1231
def __eq__(self, other):
1232
return (self.__class__ is other.__class__
1233
and self.features == other.features)
1235
def _update_feature_flags(self, updated_flags):
1236
"""Update the feature flags in this format.
1238
:param updated_flags: Updated feature flags
1240
for name, necessity in updated_flags.items():
1241
if necessity is None:
1350
raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
1353
def known_formats(cls):
1355
for name, format in cls.formats.iteritems():
1356
if callable(format):
1362
controldir.ControlDirFormat.register_prober(BzrProber)
1365
class RemoteBzrProber(controldir.Prober):
1366
"""Prober for remote servers that provide a Bazaar smart server."""
1369
def probe_transport(klass, transport):
1370
"""Return a RemoteBzrDirFormat object if it looks possible."""
1372
medium = transport.get_smart_medium()
1373
except (NotImplementedError, AttributeError,
1374
errors.TransportNotPossible, errors.NoSmartMedium,
1375
errors.SmartProtocolError):
1376
# no smart server, so not a branch for this format type.
1377
raise errors.NotBranchError(path=transport.base)
1379
# Decline to open it if the server doesn't support our required
1380
# version (3) so that the VFS-based transport will do it.
1381
if medium.should_probe():
1243
del self.features[name]
1247
self.features[name] = necessity
1250
class BzrDirFormat(BzrFormat, controldir.ControlDirFormat):
1383
server_version = medium.protocol_version()
1384
except errors.SmartProtocolError:
1385
# Apparently there's no usable smart server there, even though
1386
# the medium supports the smart protocol.
1387
raise errors.NotBranchError(path=transport.base)
1388
if server_version != '2':
1389
raise errors.NotBranchError(path=transport.base)
1390
from bzrlib.remote import RemoteBzrDirFormat
1391
return RemoteBzrDirFormat()
1394
def known_formats(cls):
1395
from bzrlib.remote import RemoteBzrDirFormat
1396
return set([RemoteBzrDirFormat()])
1399
class BzrDirFormat(controldir.ControlDirFormat):
1251
1400
"""ControlDirFormat base class for .bzr/ directories.
1253
1402
Formats are placed in a dict by their format string for reference
1762
1840
def convert(self, to_convert, pb):
1763
1841
"""See Converter.convert()."""
1764
self.controldir = to_convert
1765
with ui.ui_factory.nested_progress_bar() as self.pb:
1768
self.step('checking repository format')
1770
repo = self.controldir.open_repository()
1771
except errors.NoRepositoryPresent:
1774
repo_fmt = self.target_format.repository_format
1775
if not isinstance(repo._format, repo_fmt.__class__):
1776
from ..repository import CopyConverter
1777
ui.ui_factory.note(gettext('starting repository conversion'))
1778
if not repo_fmt.supports_overriding_transport:
1779
raise AssertionError(
1780
"Repository in metadir does not support "
1781
"overriding transport")
1782
converter = CopyConverter(self.target_format.repository_format)
1783
converter.convert(repo, pb)
1784
for branch in self.controldir.list_branches():
1785
# TODO: conversions of Branch and Tree should be done by
1786
# InterXFormat lookups/some sort of registry.
1787
# Avoid circular imports
1842
self.bzrdir = to_convert
1843
self.pb = ui.ui_factory.nested_progress_bar()
1846
self.step('checking repository format')
1848
repo = self.bzrdir.open_repository()
1849
except errors.NoRepositoryPresent:
1852
if not isinstance(repo._format, self.target_format.repository_format.__class__):
1853
from bzrlib.repository import CopyConverter
1854
ui.ui_factory.note('starting repository conversion')
1855
converter = CopyConverter(self.target_format.repository_format)
1856
converter.convert(repo, pb)
1857
for branch in self.bzrdir.list_branches():
1858
# TODO: conversions of Branch and Tree should be done by
1859
# InterXFormat lookups/some sort of registry.
1860
# Avoid circular imports
1861
old = branch._format.__class__
1862
new = self.target_format.get_branch_format().__class__
1864
if (old == _mod_branch.BzrBranchFormat5 and
1865
new in (_mod_branch.BzrBranchFormat6,
1866
_mod_branch.BzrBranchFormat7,
1867
_mod_branch.BzrBranchFormat8)):
1868
branch_converter = _mod_branch.Converter5to6()
1869
elif (old == _mod_branch.BzrBranchFormat6 and
1870
new in (_mod_branch.BzrBranchFormat7,
1871
_mod_branch.BzrBranchFormat8)):
1872
branch_converter = _mod_branch.Converter6to7()
1873
elif (old == _mod_branch.BzrBranchFormat7 and
1874
new is _mod_branch.BzrBranchFormat8):
1875
branch_converter = _mod_branch.Converter7to8()
1877
raise errors.BadConversionTarget("No converter", new,
1879
branch_converter.convert(branch)
1880
branch = self.bzrdir.open_branch()
1788
1881
old = branch._format.__class__
1789
new = self.target_format.get_branch_format().__class__
1791
if (old == fullhistorybranch.BzrBranchFormat5
1792
and new in (_mod_bzrbranch.BzrBranchFormat6,
1793
_mod_bzrbranch.BzrBranchFormat7,
1794
_mod_bzrbranch.BzrBranchFormat8)):
1795
branch_converter = _mod_bzrbranch.Converter5to6()
1796
elif (old == _mod_bzrbranch.BzrBranchFormat6
1797
and new in (_mod_bzrbranch.BzrBranchFormat7,
1798
_mod_bzrbranch.BzrBranchFormat8)):
1799
branch_converter = _mod_bzrbranch.Converter6to7()
1800
elif (old == _mod_bzrbranch.BzrBranchFormat7
1801
and new is _mod_bzrbranch.BzrBranchFormat8):
1802
branch_converter = _mod_bzrbranch.Converter7to8()
1804
raise errors.BadConversionTarget("No converter", new,
1806
branch_converter.convert(branch)
1807
branch = self.controldir.open_branch()
1808
old = branch._format.__class__
1810
tree = self.controldir.open_workingtree(recommend_upgrade=False)
1811
except (errors.NoWorkingTree, errors.NotLocalUrl):
1814
# TODO: conversions of Branch and Tree should be done by
1815
# InterXFormat lookups
1816
if (isinstance(tree, workingtree_3.WorkingTree3)
1817
and not isinstance(tree, workingtree_4.DirStateWorkingTree)
1818
and isinstance(self.target_format.workingtree_format,
1819
workingtree_4.DirStateWorkingTreeFormat)):
1820
workingtree_4.Converter3to4().convert(tree)
1821
if (isinstance(tree, workingtree_4.DirStateWorkingTree)
1822
and not isinstance(tree, workingtree_4.WorkingTree5)
1823
and isinstance(self.target_format.workingtree_format,
1824
workingtree_4.WorkingTreeFormat5)):
1825
workingtree_4.Converter4to5().convert(tree)
1826
if (isinstance(tree, workingtree_4.DirStateWorkingTree)
1827
and not isinstance(tree, workingtree_4.WorkingTree6)
1828
and isinstance(self.target_format.workingtree_format,
1829
workingtree_4.WorkingTreeFormat6)):
1830
workingtree_4.Converter4or5to6().convert(tree)
1883
tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
1884
except (errors.NoWorkingTree, errors.NotLocalUrl):
1887
# TODO: conversions of Branch and Tree should be done by
1888
# InterXFormat lookups
1889
if (isinstance(tree, workingtree.WorkingTree3) and
1890
not isinstance(tree, workingtree_4.DirStateWorkingTree) and
1891
isinstance(self.target_format.workingtree_format,
1892
workingtree_4.DirStateWorkingTreeFormat)):
1893
workingtree_4.Converter3to4().convert(tree)
1894
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1895
not isinstance(tree, workingtree_4.WorkingTree5) and
1896
isinstance(self.target_format.workingtree_format,
1897
workingtree_4.WorkingTreeFormat5)):
1898
workingtree_4.Converter4to5().convert(tree)
1899
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1900
not isinstance(tree, workingtree_4.WorkingTree6) and
1901
isinstance(self.target_format.workingtree_format,
1902
workingtree_4.WorkingTreeFormat6)):
1903
workingtree_4.Converter4or5to6().convert(tree)
1831
1905
return to_convert
1834
class ConvertMetaToColo(controldir.Converter):
1835
"""Add colocated branch support."""
1837
def __init__(self, target_format):
1838
"""Create a converter.that upgrades a metadir to the colo format.
1840
:param target_format: The final metadir format that is desired.
1842
self.target_format = target_format
1844
def convert(self, to_convert, pb):
1845
"""See Converter.convert()."""
1846
to_convert.transport.put_bytes('branch-format',
1847
self.target_format.as_string())
1848
return BzrDir.open_from_transport(to_convert.root_transport)
1851
class ConvertMetaToColo(controldir.Converter):
1852
"""Convert a 'development-colo' bzrdir to a '2a' bzrdir."""
1854
def __init__(self, target_format):
1855
"""Create a converter that converts a 'development-colo' metadir
1858
:param target_format: The final metadir format that is desired.
1860
self.target_format = target_format
1862
def convert(self, to_convert, pb):
1863
"""See Converter.convert()."""
1864
to_convert.transport.put_bytes('branch-format',
1865
self.target_format.as_string())
1866
return BzrDir.open_from_transport(to_convert.root_transport)
1869
class CreateRepository(controldir.RepositoryAcquisitionPolicy):
1908
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
1911
class RepositoryAcquisitionPolicy(object):
1912
"""Abstract base class for repository acquisition policies.
1914
A repository acquisition policy decides how a BzrDir acquires a repository
1915
for a branch that is being created. The most basic policy decision is
1916
whether to create a new repository or use an existing one.
1918
def __init__(self, stack_on, stack_on_pwd, require_stacking):
1921
:param stack_on: A location to stack on
1922
:param stack_on_pwd: If stack_on is relative, the location it is
1924
:param require_stacking: If True, it is a failure to not stack.
1926
self._stack_on = stack_on
1927
self._stack_on_pwd = stack_on_pwd
1928
self._require_stacking = require_stacking
1930
def configure_branch(self, branch):
1931
"""Apply any configuration data from this policy to the branch.
1933
Default implementation sets repository stacking.
1935
if self._stack_on is None:
1937
if self._stack_on_pwd is None:
1938
stack_on = self._stack_on
1941
stack_on = urlutils.rebase_url(self._stack_on,
1944
except errors.InvalidRebaseURLs:
1945
stack_on = self._get_full_stack_on()
1947
branch.set_stacked_on_url(stack_on)
1948
except (errors.UnstackableBranchFormat,
1949
errors.UnstackableRepositoryFormat):
1950
if self._require_stacking:
1953
def requires_stacking(self):
1954
"""Return True if this policy requires stacking."""
1955
return self._stack_on is not None and self._require_stacking
1957
def _get_full_stack_on(self):
1958
"""Get a fully-qualified URL for the stack_on location."""
1959
if self._stack_on is None:
1961
if self._stack_on_pwd is None:
1962
return self._stack_on
1964
return urlutils.join(self._stack_on_pwd, self._stack_on)
1966
def _add_fallback(self, repository, possible_transports=None):
1967
"""Add a fallback to the supplied repository, if stacking is set."""
1968
stack_on = self._get_full_stack_on()
1969
if stack_on is None:
1972
stacked_dir = BzrDir.open(stack_on,
1973
possible_transports=possible_transports)
1974
except errors.JailBreak:
1975
# We keep the stacking details, but we are in the server code so
1976
# actually stacking is not needed.
1979
stacked_repo = stacked_dir.open_branch().repository
1980
except errors.NotBranchError:
1981
stacked_repo = stacked_dir.open_repository()
1983
repository.add_fallback_repository(stacked_repo)
1984
except errors.UnstackableRepositoryFormat:
1985
if self._require_stacking:
1988
self._require_stacking = True
1990
def acquire_repository(self, make_working_trees=None, shared=False):
1991
"""Acquire a repository for this bzrdir.
1993
Implementations may create a new repository or use a pre-exising
1995
:param make_working_trees: If creating a repository, set
1996
make_working_trees to this value (if non-None)
1997
:param shared: If creating a repository, make it shared if True
1998
:return: A repository, is_new_flag (True if the repository was
2001
raise NotImplemented(RepositoryAcquisitionPolicy.acquire_repository)
2004
class CreateRepository(RepositoryAcquisitionPolicy):
1870
2005
"""A policy of creating a new repository"""
1872
def __init__(self, controldir, stack_on=None, stack_on_pwd=None,
2007
def __init__(self, bzrdir, stack_on=None, stack_on_pwd=None,
1873
2008
require_stacking=False):
1876
:param controldir: The controldir to create the repository on.
2011
:param bzrdir: The bzrdir to create the repository on.
1877
2012
:param stack_on: A location to stack on
1878
2013
:param stack_on_pwd: If stack_on is relative, the location it is
1881
super(CreateRepository, self).__init__(
1882
stack_on, stack_on_pwd, require_stacking)
1883
self._controldir = controldir
2016
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2018
self._bzrdir = bzrdir
1885
def acquire_repository(self, make_working_trees=None, shared=False,
1886
possible_transports=None):
2020
def acquire_repository(self, make_working_trees=None, shared=False):
1887
2021
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
1889
Creates the desired repository in the controldir we already have.
2023
Creates the desired repository in the bzrdir we already have.
1891
if possible_transports is None:
1892
possible_transports = []
1894
possible_transports = list(possible_transports)
1895
possible_transports.append(self._controldir.root_transport)
1896
2025
stack_on = self._get_full_stack_on()
1898
format = self._controldir._format
2027
format = self._bzrdir._format
1899
2028
format.require_stacking(stack_on=stack_on,
1900
possible_transports=possible_transports)
2029
possible_transports=[self._bzrdir.root_transport])
1901
2030
if not self._require_stacking:
1902
2031
# We have picked up automatic stacking somewhere.
1903
note(gettext('Using default stacking branch {0} at {1}').format(
1904
self._stack_on, self._stack_on_pwd))
1905
repository = self._controldir.create_repository(shared=shared)
2032
note('Using default stacking branch %s at %s', self._stack_on,
2034
repository = self._bzrdir.create_repository(shared=shared)
1906
2035
self._add_fallback(repository,
1907
possible_transports=possible_transports)
2036
possible_transports=[self._bzrdir.transport])
1908
2037
if make_working_trees is not None:
1909
2038
repository.set_make_working_trees(make_working_trees)
1910
2039
return repository, True
1913
class UseExistingRepository(controldir.RepositoryAcquisitionPolicy):
2042
class UseExistingRepository(RepositoryAcquisitionPolicy):
1914
2043
"""A policy of reusing an existing repository"""
1916
2045
def __init__(self, repository, stack_on=None, stack_on_pwd=None,
1922
2051
:param stack_on_pwd: If stack_on is relative, the location it is
1925
super(UseExistingRepository, self).__init__(
1926
stack_on, stack_on_pwd, require_stacking)
2054
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
1927
2056
self._repository = repository
1929
def acquire_repository(self, make_working_trees=None, shared=False,
1930
possible_transports=None):
2058
def acquire_repository(self, make_working_trees=None, shared=False):
1931
2059
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
1933
2061
Returns an existing repository to use.
1935
if possible_transports is None:
1936
possible_transports = []
1938
possible_transports = list(possible_transports)
1939
possible_transports.append(self._repository.controldir.transport)
1940
2063
self._add_fallback(self._repository,
1941
possible_transports=possible_transports)
2064
possible_transports=[self._repository.bzrdir.transport])
1942
2065
return self._repository, False
1945
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
2068
def register_metadir(registry, key,
2069
repository_format, help, native=True, deprecated=False,
2075
"""Register a metadir subformat.
2077
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
2078
by the Repository/Branch/WorkingTreeformats.
2080
:param repository_format: The fully-qualified repository format class
2082
:param branch_format: Fully-qualified branch format class name as
2084
:param tree_format: Fully-qualified tree format class name as
2087
# This should be expanded to support setting WorkingTree and Branch
2088
# formats, once BzrDirMetaFormat1 supports that.
2089
def _load(full_name):
2090
mod_name, factory_name = full_name.rsplit('.', 1)
2092
factory = pyutils.get_named_object(mod_name, factory_name)
2093
except ImportError, e:
2094
raise ImportError('failed to load %s: %s' % (full_name, e))
2095
except AttributeError:
2096
raise AttributeError('no factory %s in module %r'
2097
% (full_name, sys.modules[mod_name]))
2101
bd = BzrDirMetaFormat1()
2102
if branch_format is not None:
2103
bd.set_branch_format(_load(branch_format))
2104
if tree_format is not None:
2105
bd.workingtree_format = _load(tree_format)
2106
if repository_format is not None:
2107
bd.repository_format = _load(repository_format)
2109
registry.register(key, helper, help, native, deprecated, hidden,
2110
experimental, alias)
2112
register_metadir(controldir.format_registry, 'knit',
2113
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2114
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
2115
branch_format='bzrlib.branch.BzrBranchFormat5',
2116
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
2119
register_metadir(controldir.format_registry, 'dirstate',
2120
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2121
help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
2122
'above when accessed over the network.',
2123
branch_format='bzrlib.branch.BzrBranchFormat5',
2124
# this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
2125
# directly from workingtree_4 triggers a circular import.
2126
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2129
register_metadir(controldir.format_registry, 'dirstate-tags',
2130
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2131
help='New in 0.15: Fast local operations and improved scaling for '
2132
'network operations. Additionally adds support for tags.'
2133
' Incompatible with bzr < 0.15.',
2134
branch_format='bzrlib.branch.BzrBranchFormat6',
2135
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2138
register_metadir(controldir.format_registry, 'rich-root',
2139
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
2140
help='New in 1.0. Better handling of tree roots. Incompatible with'
2142
branch_format='bzrlib.branch.BzrBranchFormat6',
2143
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2146
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
2147
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2148
help='New in 0.15: Fast local operations and improved scaling for '
2149
'network operations. Additionally adds support for versioning nested '
2150
'bzr branches. Incompatible with bzr < 0.15.',
2151
branch_format='bzrlib.branch.BzrBranchFormat6',
2152
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2156
register_metadir(controldir.format_registry, 'pack-0.92',
2157
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
2158
help='New in 0.92: Pack-based format with data compatible with '
2159
'dirstate-tags format repositories. Interoperates with '
2160
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2162
branch_format='bzrlib.branch.BzrBranchFormat6',
2163
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2165
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2166
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
2167
help='New in 0.92: Pack-based format with data compatible with '
2168
'dirstate-with-subtree format repositories. Interoperates with '
2169
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2171
branch_format='bzrlib.branch.BzrBranchFormat6',
2172
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2176
register_metadir(controldir.format_registry, 'rich-root-pack',
2177
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
2178
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
2179
'(needed for bzr-svn and bzr-git).',
2180
branch_format='bzrlib.branch.BzrBranchFormat6',
2181
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2184
register_metadir(controldir.format_registry, '1.6',
2185
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
2186
help='A format that allows a branch to indicate that there is another '
2187
'(stacked) repository that should be used to access data that is '
2188
'not present locally.',
2189
branch_format='bzrlib.branch.BzrBranchFormat7',
2190
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2193
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2194
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
2195
help='A variant of 1.6 that supports rich-root data '
2196
'(needed for bzr-svn and bzr-git).',
2197
branch_format='bzrlib.branch.BzrBranchFormat7',
2198
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2201
register_metadir(controldir.format_registry, '1.9',
2202
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2203
help='A repository format using B+tree indexes. These indexes '
2204
'are smaller in size, have smarter caching and provide faster '
2205
'performance for most operations.',
2206
branch_format='bzrlib.branch.BzrBranchFormat7',
2207
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2210
register_metadir(controldir.format_registry, '1.9-rich-root',
2211
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2212
help='A variant of 1.9 that supports rich-root data '
2213
'(needed for bzr-svn and bzr-git).',
2214
branch_format='bzrlib.branch.BzrBranchFormat7',
2215
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2218
register_metadir(controldir.format_registry, '1.14',
2219
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2220
help='A working-tree format that supports content filtering.',
2221
branch_format='bzrlib.branch.BzrBranchFormat7',
2222
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2224
register_metadir(controldir.format_registry, '1.14-rich-root',
2225
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2226
help='A variant of 1.14 that supports rich-root data '
2227
'(needed for bzr-svn and bzr-git).',
2228
branch_format='bzrlib.branch.BzrBranchFormat7',
2229
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2231
# The following un-numbered 'development' formats should always just be aliases.
2232
register_metadir(controldir.format_registry, 'development-subtree',
2233
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2aSubtree',
2234
help='Current development format, subtree variant. Can convert data to and '
2235
'from pack-0.92-subtree (and anything compatible with '
2236
'pack-0.92-subtree) format repositories. Repositories and branches in '
2237
'this format can only be read by bzr.dev. Please read '
2238
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2240
branch_format='bzrlib.branch.BzrBranchFormat7',
2241
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
2244
alias=False, # Restore to being an alias when an actual development subtree format is added
2245
# This current non-alias status is simply because we did not introduce a
2246
# chk based subtree format.
2248
register_metadir(controldir.format_registry, 'development5-subtree',
2249
'bzrlib.repofmt.knitpack_repo.RepositoryFormatPackDevelopment2Subtree',
2250
help='Development format, subtree variant. Can convert data to and '
2251
'from pack-0.92-subtree (and anything compatible with '
2252
'pack-0.92-subtree) format repositories. Repositories and branches in '
2253
'this format can only be read by bzr.dev. Please read '
2254
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2256
branch_format='bzrlib.branch.BzrBranchFormat7',
2257
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
2263
# And the development formats above will have aliased one of the following:
2265
# Finally, the current format.
2266
register_metadir(controldir.format_registry, '2a',
2267
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2268
help='First format for bzr 2.0 series.\n'
2269
'Uses group-compress storage.\n'
2270
'Provides rich roots which are a one-way transition.\n',
2271
# 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
2272
# 'rich roots. Supported by bzr 1.16 and later.',
2273
branch_format='bzrlib.branch.BzrBranchFormat7',
2274
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
2278
# The following format should be an alias for the rich root equivalent
2279
# of the default format
2280
register_metadir(controldir.format_registry, 'default-rich-root',
2281
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2282
branch_format='bzrlib.branch.BzrBranchFormat7',
2283
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
2288
# The current format that is made on 'bzr init'.
2289
format_name = config.GlobalConfig().get_user_option('default_format')
2290
if format_name is None:
2291
controldir.format_registry.set_default('2a')
2293
controldir.format_registry.set_default(format_name)
2295
# XXX 2010-08-20 JRV: There is still a lot of code relying on
2296
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc
2297
# get changed to ControlDir.create/ControlDir.open/etc this should be removed.
2298
format_registry = controldir.format_registry