1
# Copyright (C) 2006-2011 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
"""BzrDir logic. The BzrDir is the basic control directory used by bzr.
19
At format 7 this was split out into Branch, Repository and Checkout control
22
Note: This module has a lot of ``open`` functions/methods that return
23
references to in-memory objects. As a rule, there are no matching ``close``
24
methods. To free any associated resources, simply stop referencing the
28
from __future__ import absolute_import
32
from bzrlib.lazy_import import lazy_import
33
lazy_import(globals(), """
36
branch as _mod_branch,
47
revision as _mod_revision,
48
transport as _mod_transport,
56
from bzrlib.repofmt import knitpack_repo
57
from bzrlib.transport import (
58
do_catching_redirections,
61
from bzrlib.i18n import gettext
64
from bzrlib.trace import (
74
from bzrlib.symbol_versioning import (
80
class BzrDir(controldir.ControlDir):
81
"""A .bzr control diretory.
83
BzrDir instances let you create or open any of the things that can be
84
found within .bzr - checkouts, branches and repositories.
87
the transport which this bzr dir is rooted at (i.e. file:///.../.bzr/)
89
a transport connected to the directory this bzr was opened from
90
(i.e. the parent directory holding the .bzr directory).
92
Everything in the bzrdir should have the same file permissions.
94
:cvar hooks: An instance of BzrDirHooks.
98
"""Invoke break_lock on the first object in the bzrdir.
100
If there is a tree, the tree is opened and break_lock() called.
101
Otherwise, branch is tried, and finally repository.
103
# XXX: This seems more like a UI function than something that really
104
# belongs in this class.
106
thing_to_unlock = self.open_workingtree()
107
except (errors.NotLocalUrl, errors.NoWorkingTree):
109
thing_to_unlock = self.open_branch()
110
except errors.NotBranchError:
112
thing_to_unlock = self.open_repository()
113
except errors.NoRepositoryPresent:
115
thing_to_unlock.break_lock()
117
def check_conversion_target(self, target_format):
118
"""Check that a bzrdir as a whole can be converted to a new format."""
119
# The only current restriction is that the repository content can be
120
# fetched compatibly with the target.
121
target_repo_format = target_format.repository_format
123
self.open_repository()._format.check_conversion_target(
125
except errors.NoRepositoryPresent:
126
# No repo, no problem.
129
def clone_on_transport(self, transport, revision_id=None,
130
force_new_repo=False, preserve_stacking=False, stacked_on=None,
131
create_prefix=False, use_existing_dir=True, no_tree=False):
132
"""Clone this bzrdir and its contents to transport verbatim.
134
:param transport: The transport for the location to produce the clone
135
at. If the target directory does not exist, it will be created.
136
:param revision_id: The tip revision-id to use for any branch or
137
working tree. If not None, then the clone operation may tune
138
itself to download less data.
139
:param force_new_repo: Do not use a shared repository for the target,
140
even if one is available.
141
:param preserve_stacking: When cloning a stacked branch, stack the
142
new branch on top of the other branch's stacked-on branch.
143
:param create_prefix: Create any missing directories leading up to
145
:param use_existing_dir: Use an existing directory if one exists.
146
:param no_tree: If set to true prevents creation of a working tree.
148
# Overview: put together a broad description of what we want to end up
149
# with; then make as few api calls as possible to do it.
151
# We may want to create a repo/branch/tree, if we do so what format
152
# would we want for each:
153
require_stacking = (stacked_on is not None)
154
format = self.cloning_metadir(require_stacking)
156
# Figure out what objects we want:
158
local_repo = self.find_repository()
159
except errors.NoRepositoryPresent:
162
local_branch = self.open_branch()
163
except errors.NotBranchError:
166
# enable fallbacks when branch is not a branch reference
167
if local_branch.repository.has_same_location(local_repo):
168
local_repo = local_branch.repository
169
if preserve_stacking:
171
stacked_on = local_branch.get_stacked_on_url()
172
except (errors.UnstackableBranchFormat,
173
errors.UnstackableRepositoryFormat,
176
# Bug: We create a metadir without knowing if it can support stacking,
177
# we should look up the policy needs first, or just use it as a hint,
180
make_working_trees = local_repo.make_working_trees() and not no_tree
181
want_shared = local_repo.is_shared()
182
repo_format_name = format.repository_format.network_name()
184
make_working_trees = False
186
repo_format_name = None
188
result_repo, result, require_stacking, repository_policy = \
189
format.initialize_on_transport_ex(transport,
190
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
191
force_new_repo=force_new_repo, stacked_on=stacked_on,
192
stack_on_pwd=self.root_transport.base,
193
repo_format_name=repo_format_name,
194
make_working_trees=make_working_trees, shared_repo=want_shared)
197
# If the result repository is in the same place as the
198
# resulting bzr dir, it will have no content, further if the
199
# result is not stacked then we know all content should be
200
# copied, and finally if we are copying up to a specific
201
# revision_id then we can use the pending-ancestry-result which
202
# does not require traversing all of history to describe it.
203
if (result_repo.user_url == result.user_url
204
and not require_stacking and
205
revision_id is not None):
206
fetch_spec = vf_search.PendingAncestryResult(
207
[revision_id], local_repo)
208
result_repo.fetch(local_repo, fetch_spec=fetch_spec)
210
result_repo.fetch(local_repo, revision_id=revision_id)
214
if result_repo is not None:
215
raise AssertionError('result_repo not None(%r)' % result_repo)
216
# 1 if there is a branch present
217
# make sure its content is available in the target repository
219
if local_branch is not None:
220
result_branch = local_branch.clone(result, revision_id=revision_id,
221
repository_policy=repository_policy)
223
# Cheaper to check if the target is not local, than to try making
225
result.root_transport.local_abspath('.')
226
if result_repo is None or result_repo.make_working_trees():
227
self.open_workingtree().clone(result, revision_id=revision_id)
228
except (errors.NoWorkingTree, errors.NotLocalUrl):
232
# TODO: This should be given a Transport, and should chdir up; otherwise
233
# this will open a new connection.
234
def _make_tail(self, url):
235
t = _mod_transport.get_transport(url)
238
def determine_repository_policy(self, force_new_repo=False, stack_on=None,
239
stack_on_pwd=None, require_stacking=False):
240
"""Return an object representing a policy to use.
242
This controls whether a new repository is created, and the format of
243
that repository, or some existing shared repository used instead.
245
If stack_on is supplied, will not seek a containing shared repo.
247
:param force_new_repo: If True, require a new repository to be created.
248
:param stack_on: If supplied, the location to stack on. If not
249
supplied, a default_stack_on location may be used.
250
:param stack_on_pwd: If stack_on is relative, the location it is
253
def repository_policy(found_bzrdir):
256
config = found_bzrdir.get_config()
258
stack_on = config.get_default_stack_on()
259
if stack_on is not None:
260
stack_on_pwd = found_bzrdir.user_url
262
# does it have a repository ?
264
repository = found_bzrdir.open_repository()
265
except errors.NoRepositoryPresent:
268
if (found_bzrdir.user_url != self.user_url
269
and not repository.is_shared()):
270
# Don't look higher, can't use a higher shared repo.
278
return UseExistingRepository(repository, stack_on,
279
stack_on_pwd, require_stacking=require_stacking), True
281
return CreateRepository(self, stack_on, stack_on_pwd,
282
require_stacking=require_stacking), True
284
if not force_new_repo:
286
policy = self._find_containing(repository_policy)
287
if policy is not None:
291
return UseExistingRepository(self.open_repository(),
292
stack_on, stack_on_pwd,
293
require_stacking=require_stacking)
294
except errors.NoRepositoryPresent:
296
return CreateRepository(self, stack_on, stack_on_pwd,
297
require_stacking=require_stacking)
299
def _find_or_create_repository(self, force_new_repo):
300
"""Create a new repository if needed, returning the repository."""
301
policy = self.determine_repository_policy(force_new_repo)
302
return policy.acquire_repository()[0]
304
def _find_source_repo(self, add_cleanup, source_branch):
305
"""Find the source branch and repo for a sprout operation.
307
This is helper intended for use by _sprout.
309
:returns: (source_branch, source_repository). Either or both may be
310
None. If not None, they will be read-locked (and their unlock(s)
311
scheduled via the add_cleanup param).
313
if source_branch is not None:
314
add_cleanup(source_branch.lock_read().unlock)
315
return source_branch, source_branch.repository
317
source_branch = self.open_branch()
318
source_repository = source_branch.repository
319
except errors.NotBranchError:
322
source_repository = self.open_repository()
323
except errors.NoRepositoryPresent:
324
source_repository = None
326
add_cleanup(source_repository.lock_read().unlock)
328
add_cleanup(source_branch.lock_read().unlock)
329
return source_branch, source_repository
331
def sprout(self, url, revision_id=None, force_new_repo=False,
332
recurse='down', possible_transports=None,
333
accelerator_tree=None, hardlink=False, stacked=False,
334
source_branch=None, create_tree_if_local=True):
335
"""Create a copy of this controldir prepared for use as a new line of
338
If url's last component does not exist, it will be created.
340
Attributes related to the identity of the source branch like
341
branch nickname will be cleaned, a working tree is created
342
whether one existed before or not; and a local branch is always
345
if revision_id is not None, then the clone operation may tune
346
itself to download less data.
348
:param accelerator_tree: A tree which can be used for retrieving file
349
contents more quickly than the revision tree, i.e. a workingtree.
350
The revision tree will be used for cases where accelerator_tree's
351
content is different.
352
:param hardlink: If true, hard-link files from accelerator_tree,
354
:param stacked: If true, create a stacked branch referring to the
355
location of this control directory.
356
:param create_tree_if_local: If true, a working-tree will be created
357
when working locally.
358
:return: The created control directory
360
operation = cleanup.OperationWithCleanups(self._sprout)
361
return operation.run(url, revision_id=revision_id,
362
force_new_repo=force_new_repo, recurse=recurse,
363
possible_transports=possible_transports,
364
accelerator_tree=accelerator_tree, hardlink=hardlink,
365
stacked=stacked, source_branch=source_branch,
366
create_tree_if_local=create_tree_if_local)
368
def _sprout(self, op, url, revision_id=None, force_new_repo=False,
369
recurse='down', possible_transports=None,
370
accelerator_tree=None, hardlink=False, stacked=False,
371
source_branch=None, create_tree_if_local=True):
372
add_cleanup = op.add_cleanup
373
fetch_spec_factory = fetch.FetchSpecFactory()
374
if revision_id is not None:
375
fetch_spec_factory.add_revision_ids([revision_id])
376
fetch_spec_factory.source_branch_stop_revision_id = revision_id
377
if possible_transports is None:
378
possible_transports = []
380
possible_transports = list(possible_transports) + [
382
target_transport = _mod_transport.get_transport(url,
384
target_transport.ensure_base()
385
cloning_format = self.cloning_metadir(stacked)
386
# Create/update the result branch
388
result = controldir.ControlDir.open_from_transport(target_transport)
389
except errors.NotBranchError:
390
result = cloning_format.initialize_on_transport(target_transport)
391
source_branch, source_repository = self._find_source_repo(
392
add_cleanup, source_branch)
393
fetch_spec_factory.source_branch = source_branch
394
# if a stacked branch wasn't requested, we don't create one
395
# even if the origin was stacked
396
if stacked and source_branch is not None:
397
stacked_branch_url = self.root_transport.base
399
stacked_branch_url = None
400
repository_policy = result.determine_repository_policy(
401
force_new_repo, stacked_branch_url, require_stacking=stacked)
402
result_repo, is_new_repo = repository_policy.acquire_repository(
403
possible_transports=possible_transports)
404
add_cleanup(result_repo.lock_write().unlock)
405
fetch_spec_factory.source_repo = source_repository
406
fetch_spec_factory.target_repo = result_repo
407
if stacked or (len(result_repo._fallback_repositories) != 0):
408
target_repo_kind = fetch.TargetRepoKinds.STACKED
410
target_repo_kind = fetch.TargetRepoKinds.EMPTY
412
target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
413
fetch_spec_factory.target_repo_kind = target_repo_kind
414
if source_repository is not None:
415
fetch_spec = fetch_spec_factory.make_fetch_spec()
416
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
418
if source_branch is None:
419
# this is for sprouting a controldir without a branch; is that
421
# Not especially, but it's part of the contract.
422
result_branch = result.create_branch()
424
result_branch = source_branch.sprout(result,
425
revision_id=revision_id, repository_policy=repository_policy,
426
repository=result_repo)
427
mutter("created new branch %r" % (result_branch,))
429
# Create/update the result working tree
430
if (create_tree_if_local and not result.has_workingtree() and
431
isinstance(target_transport, local.LocalTransport) and
432
(result_repo is None or result_repo.make_working_trees())):
433
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
434
hardlink=hardlink, from_branch=result_branch)
437
if wt.path2id('') is None:
439
wt.set_root_id(self.open_workingtree.get_root_id())
440
except errors.NoWorkingTree:
446
if recurse == 'down':
449
basis = wt.basis_tree()
450
elif result_branch is not None:
451
basis = result_branch.basis_tree()
452
elif source_branch is not None:
453
basis = source_branch.basis_tree()
454
if basis is not None:
455
add_cleanup(basis.lock_read().unlock)
456
subtrees = basis.iter_references()
459
for path, file_id in subtrees:
460
target = urlutils.join(url, urlutils.escape(path))
461
sublocation = source_branch.reference_parent(file_id, path)
462
sublocation.bzrdir.sprout(target,
463
basis.get_reference_revision(file_id, path),
464
force_new_repo=force_new_repo, recurse=recurse,
468
def _available_backup_name(self, base):
469
"""Find a non-existing backup file name based on base.
471
See bzrlib.osutils.available_backup_name about race conditions.
473
return osutils.available_backup_name(base, self.root_transport.has)
475
def backup_bzrdir(self):
476
"""Backup this bzr control directory.
478
:return: Tuple with old path name and new path name
481
pb = ui.ui_factory.nested_progress_bar()
483
old_path = self.root_transport.abspath('.bzr')
484
backup_dir = self._available_backup_name('backup.bzr')
485
new_path = self.root_transport.abspath(backup_dir)
486
ui.ui_factory.note(gettext('making backup of {0}\n to {1}').format(
487
urlutils.unescape_for_display(old_path, 'utf-8'),
488
urlutils.unescape_for_display(new_path, 'utf-8')))
489
self.root_transport.copy_tree('.bzr', backup_dir)
490
return (old_path, new_path)
494
def retire_bzrdir(self, limit=10000):
495
"""Permanently disable the bzrdir.
497
This is done by renaming it to give the user some ability to recover
498
if there was a problem.
500
This will have horrible consequences if anyone has anything locked or
502
:param limit: number of times to retry
507
to_path = '.bzr.retired.%d' % i
508
self.root_transport.rename('.bzr', to_path)
509
note(gettext("renamed {0} to {1}").format(
510
self.root_transport.abspath('.bzr'), to_path))
512
except (errors.TransportError, IOError, errors.PathError):
519
def _find_containing(self, evaluate):
520
"""Find something in a containing control directory.
522
This method will scan containing control dirs, until it finds what
523
it is looking for, decides that it will never find it, or runs out
524
of containing control directories to check.
526
It is used to implement find_repository and
527
determine_repository_policy.
529
:param evaluate: A function returning (value, stop). If stop is True,
530
the value will be returned.
534
result, stop = evaluate(found_bzrdir)
537
next_transport = found_bzrdir.root_transport.clone('..')
538
if (found_bzrdir.user_url == next_transport.base):
539
# top of the file system
541
# find the next containing bzrdir
543
found_bzrdir = self.open_containing_from_transport(
545
except errors.NotBranchError:
548
def find_repository(self):
549
"""Find the repository that should be used.
551
This does not require a branch as we use it to find the repo for
552
new branches as well as to hook existing branches up to their
555
def usable_repository(found_bzrdir):
556
# does it have a repository ?
558
repository = found_bzrdir.open_repository()
559
except errors.NoRepositoryPresent:
561
if found_bzrdir.user_url == self.user_url:
562
return repository, True
563
elif repository.is_shared():
564
return repository, True
568
found_repo = self._find_containing(usable_repository)
569
if found_repo is None:
570
raise errors.NoRepositoryPresent(self)
573
def _find_creation_modes(self):
574
"""Determine the appropriate modes for files and directories.
576
They're always set to be consistent with the base directory,
577
assuming that this transport allows setting modes.
579
# TODO: Do we need or want an option (maybe a config setting) to turn
580
# this off or override it for particular locations? -- mbp 20080512
581
if self._mode_check_done:
583
self._mode_check_done = True
585
st = self.transport.stat('.')
586
except errors.TransportNotPossible:
587
self._dir_mode = None
588
self._file_mode = None
590
# Check the directory mode, but also make sure the created
591
# directories and files are read-write for this user. This is
592
# mostly a workaround for filesystems which lie about being able to
593
# write to a directory (cygwin & win32)
594
if (st.st_mode & 07777 == 00000):
595
# FTP allows stat but does not return dir/file modes
596
self._dir_mode = None
597
self._file_mode = None
599
self._dir_mode = (st.st_mode & 07777) | 00700
600
# Remove the sticky and execute bits for files
601
self._file_mode = self._dir_mode & ~07111
603
def _get_file_mode(self):
604
"""Return Unix mode for newly created files, or None.
606
if not self._mode_check_done:
607
self._find_creation_modes()
608
return self._file_mode
610
def _get_dir_mode(self):
611
"""Return Unix mode for newly created directories, or None.
613
if not self._mode_check_done:
614
self._find_creation_modes()
615
return self._dir_mode
617
def get_config(self):
618
"""Get configuration for this BzrDir."""
619
return config.BzrDirConfig(self)
621
def _get_config(self):
622
"""By default, no configuration is available."""
625
def __init__(self, _transport, _format):
626
"""Initialize a Bzr control dir object.
628
Only really common logic should reside here, concrete classes should be
629
made with varying behaviours.
631
:param _format: the format that is creating this BzrDir instance.
632
:param _transport: the transport this dir is based at.
634
self._format = _format
635
# these are also under the more standard names of
636
# control_transport and user_transport
637
self.transport = _transport.clone('.bzr')
638
self.root_transport = _transport
639
self._mode_check_done = False
642
def user_transport(self):
643
return self.root_transport
646
def control_transport(self):
647
return self.transport
649
def is_control_filename(self, filename):
650
"""True if filename is the name of a path which is reserved for bzrdir's.
652
:param filename: A filename within the root transport of this bzrdir.
654
This is true IF and ONLY IF the filename is part of the namespace reserved
655
for bzr control dirs. Currently this is the '.bzr' directory in the root
656
of the root_transport.
658
# this might be better on the BzrDirFormat class because it refers to
659
# all the possible bzrdir disk formats.
660
# This method is tested via the workingtree is_control_filename tests-
661
# it was extracted from WorkingTree.is_control_filename. If the method's
662
# contract is extended beyond the current trivial implementation, please
663
# add new tests for it to the appropriate place.
664
return filename == '.bzr' or filename.startswith('.bzr/')
666
def _cloning_metadir(self):
667
"""Produce a metadir suitable for cloning with.
669
:returns: (destination_bzrdir_format, source_repository)
671
result_format = self._format.__class__()
674
branch = self.open_branch(ignore_fallbacks=True)
675
source_repository = branch.repository
676
result_format._branch_format = branch._format
677
except errors.NotBranchError:
679
source_repository = self.open_repository()
680
except errors.NoRepositoryPresent:
681
source_repository = None
683
# XXX TODO: This isinstance is here because we have not implemented
684
# the fix recommended in bug # 103195 - to delegate this choice the
686
repo_format = source_repository._format
687
if isinstance(repo_format, remote.RemoteRepositoryFormat):
688
source_repository._ensure_real()
689
repo_format = source_repository._real_repository._format
690
result_format.repository_format = repo_format
692
# TODO: Couldn't we just probe for the format in these cases,
693
# rather than opening the whole tree? It would be a little
694
# faster. mbp 20070401
695
tree = self.open_workingtree(recommend_upgrade=False)
696
except (errors.NoWorkingTree, errors.NotLocalUrl):
697
result_format.workingtree_format = None
699
result_format.workingtree_format = tree._format.__class__()
700
return result_format, source_repository
702
def cloning_metadir(self, require_stacking=False):
703
"""Produce a metadir suitable for cloning or sprouting with.
705
These operations may produce workingtrees (yes, even though they're
706
"cloning" something that doesn't have a tree), so a viable workingtree
707
format must be selected.
709
:require_stacking: If True, non-stackable formats will be upgraded
710
to similar stackable formats.
711
:returns: a ControlDirFormat with all component formats either set
712
appropriately or set to None if that component should not be
715
format, repository = self._cloning_metadir()
716
if format._workingtree_format is None:
718
if repository is None:
719
# No repository either
721
# We have a repository, so set a working tree? (Why? This seems to
722
# contradict the stated return value in the docstring).
723
tree_format = repository._format._matchingbzrdir.workingtree_format
724
format.workingtree_format = tree_format.__class__()
726
format.require_stacking()
729
def get_branch_transport(self, branch_format, name=None):
730
"""Get the transport for use by branch format in this BzrDir.
732
Note that bzr dirs that do not support format strings will raise
733
IncompatibleFormat if the branch format they are given has
734
a format string, and vice versa.
736
If branch_format is None, the transport is returned with no
737
checking. If it is not None, then the returned transport is
738
guaranteed to point to an existing directory ready for use.
740
raise NotImplementedError(self.get_branch_transport)
742
def get_repository_transport(self, repository_format):
743
"""Get the transport for use by repository format in this BzrDir.
745
Note that bzr dirs that do not support format strings will raise
746
IncompatibleFormat if the repository format they are given has
747
a format string, and vice versa.
749
If repository_format is None, the transport is returned with no
750
checking. If it is not None, then the returned transport is
751
guaranteed to point to an existing directory ready for use.
753
raise NotImplementedError(self.get_repository_transport)
755
def get_workingtree_transport(self, tree_format):
756
"""Get the transport for use by workingtree format in this BzrDir.
758
Note that bzr dirs that do not support format strings will raise
759
IncompatibleFormat if the workingtree format they are given has a
760
format string, and vice versa.
762
If workingtree_format is None, the transport is returned with no
763
checking. If it is not None, then the returned transport is
764
guaranteed to point to an existing directory ready for use.
766
raise NotImplementedError(self.get_workingtree_transport)
769
def create(cls, base, format=None, possible_transports=None):
770
"""Create a new BzrDir at the url 'base'.
772
:param format: If supplied, the format of branch to create. If not
773
supplied, the default is used.
774
:param possible_transports: If supplied, a list of transports that
775
can be reused to share a remote connection.
777
if cls is not BzrDir:
778
raise AssertionError("BzrDir.create always creates the "
779
"default format, not one of %r" % cls)
780
return controldir.ControlDir.create(base, format=format,
781
possible_transports=possible_transports)
784
return "<%s at %r>" % (self.__class__.__name__, self.user_url)
786
def update_feature_flags(self, updated_flags):
787
"""Update the features required by this bzrdir.
789
:param updated_flags: Dictionary mapping feature names to necessities
790
A necessity can be None to indicate the feature should be removed
792
self.control_files.lock_write()
794
self._format._update_feature_flags(updated_flags)
795
self.transport.put_bytes('branch-format', self._format.as_string())
797
self.control_files.unlock()
800
class BzrDirMeta1(BzrDir):
801
"""A .bzr meta version 1 control object.
803
This is the first control object where the
804
individual aspects are really split out: there are separate repository,
805
workingtree and branch subdirectories and any subset of the three can be
806
present within a BzrDir.
809
def _get_branch_path(self, name):
810
"""Obtain the branch path to use.
812
This uses the API specified branch name first, and then falls back to
813
the branch name specified in the URL. If neither of those is specified,
814
it uses the default branch.
816
:param name: Optional branch name to use
817
:return: Relative path to branch
821
return urlutils.join('branches', name.encode("utf-8"))
823
def _read_branch_list(self):
824
"""Read the branch list.
826
:return: List of utf-8 encoded branch names.
829
f = self.control_transport.get('branch-list')
830
except errors.NoSuchFile:
836
ret.append(name.rstrip("\n"))
841
def _write_branch_list(self, branches):
842
"""Write out the branch list.
844
:param branches: List of utf-8 branch names to write
846
self.transport.put_bytes('branch-list',
847
"".join([name+"\n" for name in branches]))
849
def __init__(self, _transport, _format):
850
super(BzrDirMeta1, self).__init__(_transport, _format)
851
self.control_files = lockable_files.LockableFiles(
852
self.control_transport, self._format._lock_file_name,
853
self._format._lock_class)
855
def can_convert_format(self):
856
"""See BzrDir.can_convert_format()."""
859
def create_branch(self, name=None, repository=None,
860
append_revisions_only=None):
861
"""See ControlDir.create_branch."""
863
name = self._get_selected_branch()
864
return self._format.get_branch_format().initialize(self, name=name,
865
repository=repository,
866
append_revisions_only=append_revisions_only)
868
def destroy_branch(self, name=None):
869
"""See ControlDir.destroy_branch."""
871
name = self._get_selected_branch()
872
path = self._get_branch_path(name)
874
self.control_files.lock_write()
876
branches = self._read_branch_list()
878
branches.remove(name.encode("utf-8"))
880
raise errors.NotBranchError(name)
881
self._write_branch_list(branches)
883
self.control_files.unlock()
885
self.transport.delete_tree(path)
886
except errors.NoSuchFile:
887
raise errors.NotBranchError(path=urlutils.join(self.transport.base,
890
def create_repository(self, shared=False):
891
"""See BzrDir.create_repository."""
892
return self._format.repository_format.initialize(self, shared)
894
def destroy_repository(self):
895
"""See BzrDir.destroy_repository."""
897
self.transport.delete_tree('repository')
898
except errors.NoSuchFile:
899
raise errors.NoRepositoryPresent(self)
901
def create_workingtree(self, revision_id=None, from_branch=None,
902
accelerator_tree=None, hardlink=False):
903
"""See BzrDir.create_workingtree."""
904
return self._format.workingtree_format.initialize(
905
self, revision_id, from_branch=from_branch,
906
accelerator_tree=accelerator_tree, hardlink=hardlink)
908
def destroy_workingtree(self):
909
"""See BzrDir.destroy_workingtree."""
910
wt = self.open_workingtree(recommend_upgrade=False)
911
repository = wt.branch.repository
912
empty = repository.revision_tree(_mod_revision.NULL_REVISION)
913
# We ignore the conflicts returned by wt.revert since we're about to
914
# delete the wt metadata anyway, all that should be left here are
915
# detritus. But see bug #634470 about subtree .bzr dirs.
916
conflicts = wt.revert(old_tree=empty)
917
self.destroy_workingtree_metadata()
919
def destroy_workingtree_metadata(self):
920
self.transport.delete_tree('checkout')
922
def find_branch_format(self, name=None):
923
"""Find the branch 'format' for this bzrdir.
925
This might be a synthetic object for e.g. RemoteBranch and SVN.
927
from bzrlib.branch import BranchFormatMetadir
928
return BranchFormatMetadir.find_format(self, name=name)
930
def _get_mkdir_mode(self):
931
"""Figure out the mode to use when creating a bzrdir subdir."""
932
temp_control = lockable_files.LockableFiles(self.transport, '',
933
lockable_files.TransportLock)
934
return temp_control._dir_mode
936
def get_branch_reference(self, name=None):
937
"""See BzrDir.get_branch_reference()."""
938
from bzrlib.branch import BranchFormatMetadir
939
format = BranchFormatMetadir.find_format(self, name=name)
940
return format.get_reference(self, name=name)
942
def set_branch_reference(self, target_branch, name=None):
943
format = _mod_branch.BranchReferenceFormat()
944
return format.initialize(self, target_branch=target_branch, name=name)
946
def get_branch_transport(self, branch_format, name=None):
947
"""See BzrDir.get_branch_transport()."""
949
name = self._get_selected_branch()
950
path = self._get_branch_path(name)
951
# XXX: this shouldn't implicitly create the directory if it's just
952
# promising to get a transport -- mbp 20090727
953
if branch_format is None:
954
return self.transport.clone(path)
956
branch_format.get_format_string()
957
except NotImplementedError:
958
raise errors.IncompatibleFormat(branch_format, self._format)
960
branches = self._read_branch_list()
961
utf8_name = name.encode("utf-8")
962
if not utf8_name in branches:
963
self.control_files.lock_write()
965
branches = self._read_branch_list()
966
dirname = urlutils.dirname(utf8_name)
967
if dirname != "" and dirname in branches:
968
raise errors.ParentBranchExists(name)
970
b.startswith(utf8_name+"/") for b in branches]
971
if any(child_branches):
972
raise errors.AlreadyBranchError(name)
973
branches.append(utf8_name)
974
self._write_branch_list(branches)
976
self.control_files.unlock()
977
branch_transport = self.transport.clone(path)
978
mode = self._get_mkdir_mode()
979
branch_transport.create_prefix(mode=mode)
981
self.transport.mkdir(path, mode=mode)
982
except errors.FileExists:
984
return self.transport.clone(path)
986
def get_repository_transport(self, repository_format):
987
"""See BzrDir.get_repository_transport()."""
988
if repository_format is None:
989
return self.transport.clone('repository')
991
repository_format.get_format_string()
992
except NotImplementedError:
993
raise errors.IncompatibleFormat(repository_format, self._format)
995
self.transport.mkdir('repository', mode=self._get_mkdir_mode())
996
except errors.FileExists:
998
return self.transport.clone('repository')
1000
def get_workingtree_transport(self, workingtree_format):
1001
"""See BzrDir.get_workingtree_transport()."""
1002
if workingtree_format is None:
1003
return self.transport.clone('checkout')
1005
workingtree_format.get_format_string()
1006
except NotImplementedError:
1007
raise errors.IncompatibleFormat(workingtree_format, self._format)
1009
self.transport.mkdir('checkout', mode=self._get_mkdir_mode())
1010
except errors.FileExists:
1012
return self.transport.clone('checkout')
1014
def get_branches(self):
1015
"""See ControlDir.get_branches."""
1018
ret[""] = self.open_branch(name="")
1019
except (errors.NotBranchError, errors.NoRepositoryPresent):
1022
for name in self._read_branch_list():
1023
ret[name] = self.open_branch(name=name.decode('utf-8'))
1027
def has_workingtree(self):
1028
"""Tell if this bzrdir contains a working tree.
1030
Note: if you're going to open the working tree, you should just go
1031
ahead and try, and not ask permission first.
1033
from bzrlib.workingtree import WorkingTreeFormatMetaDir
1035
WorkingTreeFormatMetaDir.find_format_string(self)
1036
except errors.NoWorkingTree:
1040
def needs_format_conversion(self, format):
1041
"""See BzrDir.needs_format_conversion()."""
1042
if (not isinstance(self._format, format.__class__) or
1043
self._format.get_format_string() != format.get_format_string()):
1044
# it is not a meta dir format, conversion is needed.
1046
# we might want to push this down to the repository?
1048
if not isinstance(self.open_repository()._format,
1049
format.repository_format.__class__):
1050
# the repository needs an upgrade.
1052
except errors.NoRepositoryPresent:
1054
for branch in self.list_branches():
1055
if not isinstance(branch._format,
1056
format.get_branch_format().__class__):
1057
# the branch needs an upgrade.
1060
my_wt = self.open_workingtree(recommend_upgrade=False)
1061
if not isinstance(my_wt._format,
1062
format.workingtree_format.__class__):
1063
# the workingtree needs an upgrade.
1065
except (errors.NoWorkingTree, errors.NotLocalUrl):
1069
def open_branch(self, name=None, unsupported=False,
1070
ignore_fallbacks=False, possible_transports=None):
1071
"""See ControlDir.open_branch."""
1073
name = self._get_selected_branch()
1074
format = self.find_branch_format(name=name)
1075
format.check_support_status(unsupported)
1076
return format.open(self, name=name,
1077
_found=True, ignore_fallbacks=ignore_fallbacks,
1078
possible_transports=possible_transports)
1080
def open_repository(self, unsupported=False):
1081
"""See BzrDir.open_repository."""
1082
from bzrlib.repository import RepositoryFormatMetaDir
1083
format = RepositoryFormatMetaDir.find_format(self)
1084
format.check_support_status(unsupported)
1085
return format.open(self, _found=True)
1087
def open_workingtree(self, unsupported=False,
1088
recommend_upgrade=True):
1089
"""See BzrDir.open_workingtree."""
1090
from bzrlib.workingtree import WorkingTreeFormatMetaDir
1091
format = WorkingTreeFormatMetaDir.find_format(self)
1092
format.check_support_status(unsupported, recommend_upgrade,
1093
basedir=self.root_transport.base)
1094
return format.open(self, _found=True)
1096
def _get_config(self):
1097
return config.TransportConfig(self.transport, 'control.conf')
1100
class BzrFormat(object):
1101
"""Base class for all formats of things living in metadirs.
1103
This class manages the format string that is stored in the 'format'
1104
or 'branch-format' file.
1106
All classes for (branch-, repository-, workingtree-) formats that
1107
live in meta directories and have their own 'format' file
1108
(i.e. different from .bzr/branch-format) derive from this class,
1109
as well as the relevant base class for their kind
1110
(BranchFormat, WorkingTreeFormat, RepositoryFormat).
1112
Each format is identified by a "format" or "branch-format" file with a
1113
single line containing the base format name and then an optional list of
1116
Feature flags are supported as of bzr 2.5. Setting feature flags on formats
1117
will render them inaccessible to older versions of bzr.
1119
:ivar features: Dictionary mapping feature names to their necessity
1122
_present_features = set()
1128
def register_feature(cls, name):
1129
"""Register a feature as being present.
1131
:param name: Name of the feature
1134
raise ValueError("spaces are not allowed in feature names")
1135
if name in cls._present_features:
1136
raise errors.FeatureAlreadyRegistered(name)
1137
cls._present_features.add(name)
1140
def unregister_feature(cls, name):
1141
"""Unregister a feature."""
1142
cls._present_features.remove(name)
1144
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1146
for name, necessity in self.features.iteritems():
1147
if name in self._present_features:
1149
if necessity == "optional":
1150
mutter("ignoring optional missing feature %s", name)
1152
elif necessity == "required":
1153
raise errors.MissingFeature(name)
1155
mutter("treating unknown necessity as require for %s",
1157
raise errors.MissingFeature(name)
1160
def get_format_string(cls):
1161
"""Return the ASCII format string that identifies this format."""
1162
raise NotImplementedError(cls.get_format_string)
1165
def from_string(cls, text):
1166
format_string = cls.get_format_string()
1167
if not text.startswith(format_string):
1168
raise AssertionError("Invalid format header %r for %r" % (text, cls))
1169
lines = text[len(format_string):].splitlines()
1171
for lineno, line in enumerate(lines):
1173
(necessity, feature) = line.split(" ", 1)
1175
raise errors.ParseFormatError(format=cls, lineno=lineno+2,
1176
line=line, text=text)
1177
ret.features[feature] = necessity
1180
def as_string(self):
1181
"""Return the string representation of this format.
1183
lines = [self.get_format_string()]
1184
lines.extend([("%s %s\n" % (item[1], item[0])) for item in
1185
self.features.iteritems()])
1186
return "".join(lines)
1189
def _find_format(klass, registry, kind, format_string):
1191
first_line = format_string[:format_string.index("\n")+1]
1193
first_line = format_string
1195
cls = registry.get(first_line)
1197
raise errors.UnknownFormatError(format=first_line, kind=kind)
1198
return cls.from_string(format_string)
1200
def network_name(self):
1201
"""A simple byte string uniquely identifying this format for RPC calls.
1203
Metadir branch formats use their format string.
1205
return self.as_string()
1207
def __eq__(self, other):
1208
return (self.__class__ is other.__class__ and
1209
self.features == other.features)
1211
def _update_feature_flags(self, updated_flags):
1212
"""Update the feature flags in this format.
1214
:param updated_flags: Updated feature flags
1216
for name, necessity in updated_flags.iteritems():
1217
if necessity is None:
1219
del self.features[name]
1223
self.features[name] = necessity
1226
class BzrProber(controldir.Prober):
1227
"""Prober for formats that use a .bzr/ control directory."""
1229
formats = registry.FormatRegistry(controldir.network_format_registry)
1230
"""The known .bzr formats."""
1233
def probe_transport(klass, transport):
1234
"""Return the .bzrdir style format present in a directory."""
1236
format_string = transport.get_bytes(".bzr/branch-format")
1237
except errors.NoSuchFile:
1238
raise errors.NotBranchError(path=transport.base)
1240
first_line = format_string[:format_string.index("\n")+1]
1242
first_line = format_string
1244
cls = klass.formats.get(first_line)
1246
raise errors.UnknownFormatError(format=first_line, kind='bzrdir')
1247
return cls.from_string(format_string)
1250
def known_formats(cls):
1252
for name, format in cls.formats.iteritems():
1253
if callable(format):
1259
controldir.ControlDirFormat.register_prober(BzrProber)
1262
class RemoteBzrProber(controldir.Prober):
1263
"""Prober for remote servers that provide a Bazaar smart server."""
1266
def probe_transport(klass, transport):
1267
"""Return a RemoteBzrDirFormat object if it looks possible."""
1269
medium = transport.get_smart_medium()
1270
except (NotImplementedError, AttributeError,
1271
errors.TransportNotPossible, errors.NoSmartMedium,
1272
errors.SmartProtocolError):
1273
# no smart server, so not a branch for this format type.
1274
raise errors.NotBranchError(path=transport.base)
1276
# Decline to open it if the server doesn't support our required
1277
# version (3) so that the VFS-based transport will do it.
1278
if medium.should_probe():
1280
server_version = medium.protocol_version()
1281
except errors.SmartProtocolError:
1282
# Apparently there's no usable smart server there, even though
1283
# the medium supports the smart protocol.
1284
raise errors.NotBranchError(path=transport.base)
1285
if server_version != '2':
1286
raise errors.NotBranchError(path=transport.base)
1287
from bzrlib.remote import RemoteBzrDirFormat
1288
return RemoteBzrDirFormat()
1291
def known_formats(cls):
1292
from bzrlib.remote import RemoteBzrDirFormat
1293
return set([RemoteBzrDirFormat()])
1296
class BzrDirFormat(BzrFormat, controldir.ControlDirFormat):
1297
"""ControlDirFormat base class for .bzr/ directories.
1299
Formats are placed in a dict by their format string for reference
1300
during bzrdir opening. These should be subclasses of BzrDirFormat
1303
Once a format is deprecated, just deprecate the initialize and open
1304
methods on the format class. Do not deprecate the object, as the
1305
object will be created every system load.
1308
_lock_file_name = 'branch-lock'
1310
# _lock_class must be set in subclasses to the lock type, typ.
1311
# TransportLock or LockDir
1313
def initialize_on_transport(self, transport):
1314
"""Initialize a new bzrdir in the base directory of a Transport."""
1316
# can we hand off the request to the smart server rather than using
1318
client_medium = transport.get_smart_medium()
1319
except errors.NoSmartMedium:
1320
return self._initialize_on_transport_vfs(transport)
1322
# Current RPC's only know how to create bzr metadir1 instances, so
1323
# we still delegate to vfs methods if the requested format is not a
1325
if type(self) != BzrDirMetaFormat1:
1326
return self._initialize_on_transport_vfs(transport)
1327
from bzrlib.remote import RemoteBzrDirFormat
1328
remote_format = RemoteBzrDirFormat()
1329
self._supply_sub_formats_to(remote_format)
1330
return remote_format.initialize_on_transport(transport)
1332
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1333
create_prefix=False, force_new_repo=False, stacked_on=None,
1334
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1335
shared_repo=False, vfs_only=False):
1336
"""Create this format on transport.
1338
The directory to initialize will be created.
1340
:param force_new_repo: Do not use a shared repository for the target,
1341
even if one is available.
1342
:param create_prefix: Create any missing directories leading up to
1344
:param use_existing_dir: Use an existing directory if one exists.
1345
:param stacked_on: A url to stack any created branch on, None to follow
1346
any target stacking policy.
1347
:param stack_on_pwd: If stack_on is relative, the location it is
1349
:param repo_format_name: If non-None, a repository will be
1350
made-or-found. Should none be found, or if force_new_repo is True
1351
the repo_format_name is used to select the format of repository to
1353
:param make_working_trees: Control the setting of make_working_trees
1354
for a new shared repository when one is made. None to use whatever
1355
default the format has.
1356
:param shared_repo: Control whether made repositories are shared or
1358
:param vfs_only: If True do not attempt to use a smart server
1359
:return: repo, controldir, require_stacking, repository_policy. repo is
1360
None if none was created or found, bzrdir is always valid.
1361
require_stacking is the result of examining the stacked_on
1362
parameter and any stacking policy found for the target.
1365
# Try to hand off to a smart server
1367
client_medium = transport.get_smart_medium()
1368
except errors.NoSmartMedium:
1371
from bzrlib.remote import RemoteBzrDirFormat
1372
# TODO: lookup the local format from a server hint.
1373
remote_dir_format = RemoteBzrDirFormat()
1374
remote_dir_format._network_name = self.network_name()
1375
self._supply_sub_formats_to(remote_dir_format)
1376
return remote_dir_format.initialize_on_transport_ex(transport,
1377
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1378
force_new_repo=force_new_repo, stacked_on=stacked_on,
1379
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1380
make_working_trees=make_working_trees, shared_repo=shared_repo)
1381
# XXX: Refactor the create_prefix/no_create_prefix code into a
1382
# common helper function
1383
# The destination may not exist - if so make it according to policy.
1384
def make_directory(transport):
1385
transport.mkdir('.')
1387
def redirected(transport, e, redirection_notice):
1388
note(redirection_notice)
1389
return transport._redirected_to(e.source, e.target)
1391
transport = do_catching_redirections(make_directory, transport,
1393
except errors.FileExists:
1394
if not use_existing_dir:
1396
except errors.NoSuchFile:
1397
if not create_prefix:
1399
transport.create_prefix()
1401
require_stacking = (stacked_on is not None)
1402
# Now the target directory exists, but doesn't have a .bzr
1403
# directory. So we need to create it, along with any work to create
1404
# all of the dependent branches, etc.
1406
result = self.initialize_on_transport(transport)
1407
if repo_format_name:
1409
# use a custom format
1410
result._format.repository_format = \
1411
repository.network_format_registry.get(repo_format_name)
1412
except AttributeError:
1413
# The format didn't permit it to be set.
1415
# A repository is desired, either in-place or shared.
1416
repository_policy = result.determine_repository_policy(
1417
force_new_repo, stacked_on, stack_on_pwd,
1418
require_stacking=require_stacking)
1419
result_repo, is_new_repo = repository_policy.acquire_repository(
1420
make_working_trees, shared_repo)
1421
if not require_stacking and repository_policy._require_stacking:
1422
require_stacking = True
1423
result._format.require_stacking()
1424
result_repo.lock_write()
1427
repository_policy = None
1428
return result_repo, result, require_stacking, repository_policy
1430
def _initialize_on_transport_vfs(self, transport):
1431
"""Initialize a new bzrdir using VFS calls.
1433
:param transport: The transport to create the .bzr directory in.
1436
# Since we are creating a .bzr directory, inherit the
1437
# mode from the root directory
1438
temp_control = lockable_files.LockableFiles(transport,
1439
'', lockable_files.TransportLock)
1441
temp_control._transport.mkdir('.bzr',
1442
# FIXME: RBC 20060121 don't peek under
1444
mode=temp_control._dir_mode)
1445
except errors.FileExists:
1446
raise errors.AlreadyControlDirError(transport.base)
1447
if sys.platform == 'win32' and isinstance(transport, local.LocalTransport):
1448
win32utils.set_file_attr_hidden(transport._abspath('.bzr'))
1449
file_mode = temp_control._file_mode
1451
bzrdir_transport = transport.clone('.bzr')
1452
utf8_files = [('README',
1453
"This is a Bazaar control directory.\n"
1454
"Do not change any files in this directory.\n"
1455
"See http://bazaar.canonical.com/ for more information about Bazaar.\n"),
1456
('branch-format', self.as_string()),
1458
# NB: no need to escape relative paths that are url safe.
1459
control_files = lockable_files.LockableFiles(bzrdir_transport,
1460
self._lock_file_name, self._lock_class)
1461
control_files.create_lock()
1462
control_files.lock_write()
1464
for (filename, content) in utf8_files:
1465
bzrdir_transport.put_bytes(filename, content,
1468
control_files.unlock()
1469
return self.open(transport, _found=True)
1471
def open(self, transport, _found=False):
1472
"""Return an instance of this format for the dir transport points at.
1474
_found is a private parameter, do not use it.
1477
found_format = controldir.ControlDirFormat.find_format(transport)
1478
if not isinstance(found_format, self.__class__):
1479
raise AssertionError("%s was asked to open %s, but it seems to need "
1481
% (self, transport, found_format))
1482
# Allow subclasses - use the found format.
1483
self._supply_sub_formats_to(found_format)
1484
return found_format._open(transport)
1485
return self._open(transport)
1487
def _open(self, transport):
1488
"""Template method helper for opening BzrDirectories.
1490
This performs the actual open and any additional logic or parameter
1493
raise NotImplementedError(self._open)
1495
def _supply_sub_formats_to(self, other_format):
1496
"""Give other_format the same values for sub formats as this has.
1498
This method is expected to be used when parameterising a
1499
RemoteBzrDirFormat instance with the parameters from a
1500
BzrDirMetaFormat1 instance.
1502
:param other_format: other_format is a format which should be
1503
compatible with whatever sub formats are supported by self.
1506
other_format.features = dict(self.features)
1508
def supports_transport(self, transport):
1509
# bzr formats can be opened over all known transports
1512
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1514
controldir.ControlDirFormat.check_support_status(self,
1515
allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
1517
BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
1518
recommend_upgrade=recommend_upgrade, basedir=basedir)
1521
class BzrDirMetaFormat1(BzrDirFormat):
1522
"""Bzr meta control format 1
1524
This is the first format with split out working tree, branch and repository
1529
- Format 3 working trees [optional]
1530
- Format 5 branches [optional]
1531
- Format 7 repositories [optional]
1534
_lock_class = lockdir.LockDir
1536
fixed_components = False
1538
colocated_branches = True
1541
BzrDirFormat.__init__(self)
1542
self._workingtree_format = None
1543
self._branch_format = None
1544
self._repository_format = None
1546
def __eq__(self, other):
1547
if other.__class__ is not self.__class__:
1549
if other.repository_format != self.repository_format:
1551
if other.workingtree_format != self.workingtree_format:
1553
if other.features != self.features:
1557
def __ne__(self, other):
1558
return not self == other
1560
def get_branch_format(self):
1561
if self._branch_format is None:
1562
from bzrlib.branch import format_registry as branch_format_registry
1563
self._branch_format = branch_format_registry.get_default()
1564
return self._branch_format
1566
def set_branch_format(self, format):
1567
self._branch_format = format
1569
def require_stacking(self, stack_on=None, possible_transports=None,
1571
"""We have a request to stack, try to ensure the formats support it.
1573
:param stack_on: If supplied, it is the URL to a branch that we want to
1574
stack on. Check to see if that format supports stacking before
1577
# Stacking is desired. requested by the target, but does the place it
1578
# points at support stacking? If it doesn't then we should
1579
# not implicitly upgrade. We check this here.
1580
new_repo_format = None
1581
new_branch_format = None
1583
# a bit of state for get_target_branch so that we don't try to open it
1584
# 2 times, for both repo *and* branch
1585
target = [None, False, None] # target_branch, checked, upgrade anyway
1586
def get_target_branch():
1588
# We've checked, don't check again
1590
if stack_on is None:
1591
# No target format, that means we want to force upgrading
1592
target[:] = [None, True, True]
1595
target_dir = BzrDir.open(stack_on,
1596
possible_transports=possible_transports)
1597
except errors.NotBranchError:
1598
# Nothing there, don't change formats
1599
target[:] = [None, True, False]
1601
except errors.JailBreak:
1602
# JailBreak, JFDI and upgrade anyway
1603
target[:] = [None, True, True]
1606
target_branch = target_dir.open_branch()
1607
except errors.NotBranchError:
1608
# No branch, don't upgrade formats
1609
target[:] = [None, True, False]
1611
target[:] = [target_branch, True, False]
1614
if (not _skip_repo and
1615
not self.repository_format.supports_external_lookups):
1616
# We need to upgrade the Repository.
1617
target_branch, _, do_upgrade = get_target_branch()
1618
if target_branch is None:
1619
# We don't have a target branch, should we upgrade anyway?
1621
# stack_on is inaccessible, JFDI.
1622
# TODO: bad monkey, hard-coded formats...
1623
if self.repository_format.rich_root_data:
1624
new_repo_format = knitpack_repo.RepositoryFormatKnitPack5RichRoot()
1626
new_repo_format = knitpack_repo.RepositoryFormatKnitPack5()
1628
# If the target already supports stacking, then we know the
1629
# project is already able to use stacking, so auto-upgrade
1631
new_repo_format = target_branch.repository._format
1632
if not new_repo_format.supports_external_lookups:
1633
# target doesn't, source doesn't, so don't auto upgrade
1635
new_repo_format = None
1636
if new_repo_format is not None:
1637
self.repository_format = new_repo_format
1638
note(gettext('Source repository format does not support stacking,'
1639
' using format:\n %s'),
1640
new_repo_format.get_format_description())
1642
if not self.get_branch_format().supports_stacking():
1643
# We just checked the repo, now lets check if we need to
1644
# upgrade the branch format
1645
target_branch, _, do_upgrade = get_target_branch()
1646
if target_branch is None:
1648
# TODO: bad monkey, hard-coded formats...
1649
from bzrlib.branch import BzrBranchFormat7
1650
new_branch_format = BzrBranchFormat7()
1652
new_branch_format = target_branch._format
1653
if not new_branch_format.supports_stacking():
1654
new_branch_format = None
1655
if new_branch_format is not None:
1656
# Does support stacking, use its format.
1657
self.set_branch_format(new_branch_format)
1658
note(gettext('Source branch format does not support stacking,'
1659
' using format:\n %s'),
1660
new_branch_format.get_format_description())
1662
def get_converter(self, format=None):
1663
"""See BzrDirFormat.get_converter()."""
1665
format = BzrDirFormat.get_default_format()
1666
if (type(self) is BzrDirMetaFormat1 and
1667
type(format) is BzrDirMetaFormat1Colo):
1668
return ConvertMetaToColo(format)
1669
if (type(self) is BzrDirMetaFormat1Colo and
1670
type(format) is BzrDirMetaFormat1):
1671
return ConvertMetaToColo(format)
1672
if not isinstance(self, format.__class__):
1673
# converting away from metadir is not implemented
1674
raise NotImplementedError(self.get_converter)
1675
return ConvertMetaToMeta(format)
1678
def get_format_string(cls):
1679
"""See BzrDirFormat.get_format_string()."""
1680
return "Bazaar-NG meta directory, format 1\n"
1682
def get_format_description(self):
1683
"""See BzrDirFormat.get_format_description()."""
1684
return "Meta directory format 1"
1686
def _open(self, transport):
1687
"""See BzrDirFormat._open."""
1688
# Create a new format instance because otherwise initialisation of new
1689
# metadirs share the global default format object leading to alias
1691
format = BzrDirMetaFormat1()
1692
self._supply_sub_formats_to(format)
1693
return BzrDirMeta1(transport, format)
1695
def __return_repository_format(self):
1696
"""Circular import protection."""
1697
if self._repository_format:
1698
return self._repository_format
1699
from bzrlib.repository import format_registry
1700
return format_registry.get_default()
1702
def _set_repository_format(self, value):
1703
"""Allow changing the repository format for metadir formats."""
1704
self._repository_format = value
1706
repository_format = property(__return_repository_format,
1707
_set_repository_format)
1709
def _supply_sub_formats_to(self, other_format):
1710
"""Give other_format the same values for sub formats as this has.
1712
This method is expected to be used when parameterising a
1713
RemoteBzrDirFormat instance with the parameters from a
1714
BzrDirMetaFormat1 instance.
1716
:param other_format: other_format is a format which should be
1717
compatible with whatever sub formats are supported by self.
1720
super(BzrDirMetaFormat1, self)._supply_sub_formats_to(other_format)
1721
if getattr(self, '_repository_format', None) is not None:
1722
other_format.repository_format = self.repository_format
1723
if self._branch_format is not None:
1724
other_format._branch_format = self._branch_format
1725
if self._workingtree_format is not None:
1726
other_format.workingtree_format = self.workingtree_format
1728
def __get_workingtree_format(self):
1729
if self._workingtree_format is None:
1730
from bzrlib.workingtree import (
1731
format_registry as wt_format_registry,
1733
self._workingtree_format = wt_format_registry.get_default()
1734
return self._workingtree_format
1736
def __set_workingtree_format(self, wt_format):
1737
self._workingtree_format = wt_format
1740
return "<%r>" % (self.__class__.__name__,)
1742
workingtree_format = property(__get_workingtree_format,
1743
__set_workingtree_format)
1746
# Register bzr formats
1747
BzrProber.formats.register(BzrDirMetaFormat1.get_format_string(),
1749
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1752
class BzrDirMetaFormat1Colo(BzrDirMetaFormat1):
1753
"""BzrDirMeta1 format with support for colocated branches."""
1755
colocated_branches = True
1758
def get_format_string(cls):
1759
"""See BzrDirFormat.get_format_string()."""
1760
return "Bazaar meta directory, format 1 (with colocated branches)\n"
1762
def get_format_description(self):
1763
"""See BzrDirFormat.get_format_description()."""
1764
return "Meta directory format 1 with support for colocated branches"
1766
def _open(self, transport):
1767
"""See BzrDirFormat._open."""
1768
# Create a new format instance because otherwise initialisation of new
1769
# metadirs share the global default format object leading to alias
1771
format = BzrDirMetaFormat1Colo()
1772
self._supply_sub_formats_to(format)
1773
return BzrDirMeta1(transport, format)
1776
BzrProber.formats.register(BzrDirMetaFormat1Colo.get_format_string(),
1777
BzrDirMetaFormat1Colo)
1780
class ConvertMetaToMeta(controldir.Converter):
1781
"""Converts the components of metadirs."""
1783
def __init__(self, target_format):
1784
"""Create a metadir to metadir converter.
1786
:param target_format: The final metadir format that is desired.
1788
self.target_format = target_format
1790
def convert(self, to_convert, pb):
1791
"""See Converter.convert()."""
1792
self.bzrdir = to_convert
1793
self.pb = ui.ui_factory.nested_progress_bar()
1796
self.step('checking repository format')
1798
repo = self.bzrdir.open_repository()
1799
except errors.NoRepositoryPresent:
1802
if not isinstance(repo._format, self.target_format.repository_format.__class__):
1803
from bzrlib.repository import CopyConverter
1804
ui.ui_factory.note(gettext('starting repository conversion'))
1805
converter = CopyConverter(self.target_format.repository_format)
1806
converter.convert(repo, pb)
1807
for branch in self.bzrdir.list_branches():
1808
# TODO: conversions of Branch and Tree should be done by
1809
# InterXFormat lookups/some sort of registry.
1810
# Avoid circular imports
1811
old = branch._format.__class__
1812
new = self.target_format.get_branch_format().__class__
1814
if (old == _mod_branch.BzrBranchFormat5 and
1815
new in (_mod_branch.BzrBranchFormat6,
1816
_mod_branch.BzrBranchFormat7,
1817
_mod_branch.BzrBranchFormat8)):
1818
branch_converter = _mod_branch.Converter5to6()
1819
elif (old == _mod_branch.BzrBranchFormat6 and
1820
new in (_mod_branch.BzrBranchFormat7,
1821
_mod_branch.BzrBranchFormat8)):
1822
branch_converter = _mod_branch.Converter6to7()
1823
elif (old == _mod_branch.BzrBranchFormat7 and
1824
new is _mod_branch.BzrBranchFormat8):
1825
branch_converter = _mod_branch.Converter7to8()
1827
raise errors.BadConversionTarget("No converter", new,
1829
branch_converter.convert(branch)
1830
branch = self.bzrdir.open_branch()
1831
old = branch._format.__class__
1833
tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
1834
except (errors.NoWorkingTree, errors.NotLocalUrl):
1837
# TODO: conversions of Branch and Tree should be done by
1838
# InterXFormat lookups
1839
if (isinstance(tree, workingtree_3.WorkingTree3) and
1840
not isinstance(tree, workingtree_4.DirStateWorkingTree) and
1841
isinstance(self.target_format.workingtree_format,
1842
workingtree_4.DirStateWorkingTreeFormat)):
1843
workingtree_4.Converter3to4().convert(tree)
1844
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1845
not isinstance(tree, workingtree_4.WorkingTree5) and
1846
isinstance(self.target_format.workingtree_format,
1847
workingtree_4.WorkingTreeFormat5)):
1848
workingtree_4.Converter4to5().convert(tree)
1849
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1850
not isinstance(tree, workingtree_4.WorkingTree6) and
1851
isinstance(self.target_format.workingtree_format,
1852
workingtree_4.WorkingTreeFormat6)):
1853
workingtree_4.Converter4or5to6().convert(tree)
1858
class ConvertMetaToColo(controldir.Converter):
1859
"""Add colocated branch support."""
1861
def __init__(self, target_format):
1862
"""Create a converter.that upgrades a metadir to the colo format.
1864
:param target_format: The final metadir format that is desired.
1866
self.target_format = target_format
1868
def convert(self, to_convert, pb):
1869
"""See Converter.convert()."""
1870
to_convert.transport.put_bytes('branch-format',
1871
self.target_format.as_string())
1872
return BzrDir.open_from_transport(to_convert.root_transport)
1875
class ConvertMetaToColo(controldir.Converter):
1876
"""Convert a 'development-colo' bzrdir to a '2a' bzrdir."""
1878
def __init__(self, target_format):
1879
"""Create a converter that converts a 'development-colo' metadir
1882
:param target_format: The final metadir format that is desired.
1884
self.target_format = target_format
1886
def convert(self, to_convert, pb):
1887
"""See Converter.convert()."""
1888
to_convert.transport.put_bytes('branch-format',
1889
self.target_format.as_string())
1890
return BzrDir.open_from_transport(to_convert.root_transport)
1893
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
1896
class RepositoryAcquisitionPolicy(object):
1897
"""Abstract base class for repository acquisition policies.
1899
A repository acquisition policy decides how a BzrDir acquires a repository
1900
for a branch that is being created. The most basic policy decision is
1901
whether to create a new repository or use an existing one.
1903
def __init__(self, stack_on, stack_on_pwd, require_stacking):
1906
:param stack_on: A location to stack on
1907
:param stack_on_pwd: If stack_on is relative, the location it is
1909
:param require_stacking: If True, it is a failure to not stack.
1911
self._stack_on = stack_on
1912
self._stack_on_pwd = stack_on_pwd
1913
self._require_stacking = require_stacking
1915
def configure_branch(self, branch):
1916
"""Apply any configuration data from this policy to the branch.
1918
Default implementation sets repository stacking.
1920
if self._stack_on is None:
1922
if self._stack_on_pwd is None:
1923
stack_on = self._stack_on
1926
stack_on = urlutils.rebase_url(self._stack_on,
1929
except errors.InvalidRebaseURLs:
1930
stack_on = self._get_full_stack_on()
1932
branch.set_stacked_on_url(stack_on)
1933
except (errors.UnstackableBranchFormat,
1934
errors.UnstackableRepositoryFormat):
1935
if self._require_stacking:
1938
def requires_stacking(self):
1939
"""Return True if this policy requires stacking."""
1940
return self._stack_on is not None and self._require_stacking
1942
def _get_full_stack_on(self):
1943
"""Get a fully-qualified URL for the stack_on location."""
1944
if self._stack_on is None:
1946
if self._stack_on_pwd is None:
1947
return self._stack_on
1949
return urlutils.join(self._stack_on_pwd, self._stack_on)
1951
def _add_fallback(self, repository, possible_transports=None):
1952
"""Add a fallback to the supplied repository, if stacking is set."""
1953
stack_on = self._get_full_stack_on()
1954
if stack_on is None:
1957
stacked_dir = BzrDir.open(stack_on,
1958
possible_transports=possible_transports)
1959
except errors.JailBreak:
1960
# We keep the stacking details, but we are in the server code so
1961
# actually stacking is not needed.
1964
stacked_repo = stacked_dir.open_branch().repository
1965
except errors.NotBranchError:
1966
stacked_repo = stacked_dir.open_repository()
1968
repository.add_fallback_repository(stacked_repo)
1969
except errors.UnstackableRepositoryFormat:
1970
if self._require_stacking:
1973
self._require_stacking = True
1975
def acquire_repository(self, make_working_trees=None, shared=False,
1976
possible_transports=None):
1977
"""Acquire a repository for this bzrdir.
1979
Implementations may create a new repository or use a pre-exising
1982
:param make_working_trees: If creating a repository, set
1983
make_working_trees to this value (if non-None)
1984
:param shared: If creating a repository, make it shared if True
1985
:return: A repository, is_new_flag (True if the repository was
1988
raise NotImplementedError(RepositoryAcquisitionPolicy.acquire_repository)
1991
class CreateRepository(RepositoryAcquisitionPolicy):
1992
"""A policy of creating a new repository"""
1994
def __init__(self, bzrdir, stack_on=None, stack_on_pwd=None,
1995
require_stacking=False):
1998
:param bzrdir: The bzrdir to create the repository on.
1999
:param stack_on: A location to stack on
2000
:param stack_on_pwd: If stack_on is relative, the location it is
2003
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2005
self._bzrdir = bzrdir
2007
def acquire_repository(self, make_working_trees=None, shared=False,
2008
possible_transports=None):
2009
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2011
Creates the desired repository in the bzrdir we already have.
2013
if possible_transports is None:
2014
possible_transports = []
2016
possible_transports = list(possible_transports)
2017
possible_transports.append(self._bzrdir.root_transport)
2018
stack_on = self._get_full_stack_on()
2020
format = self._bzrdir._format
2021
format.require_stacking(stack_on=stack_on,
2022
possible_transports=possible_transports)
2023
if not self._require_stacking:
2024
# We have picked up automatic stacking somewhere.
2025
note(gettext('Using default stacking branch {0} at {1}').format(
2026
self._stack_on, self._stack_on_pwd))
2027
repository = self._bzrdir.create_repository(shared=shared)
2028
self._add_fallback(repository,
2029
possible_transports=possible_transports)
2030
if make_working_trees is not None:
2031
repository.set_make_working_trees(make_working_trees)
2032
return repository, True
2035
class UseExistingRepository(RepositoryAcquisitionPolicy):
2036
"""A policy of reusing an existing repository"""
2038
def __init__(self, repository, stack_on=None, stack_on_pwd=None,
2039
require_stacking=False):
2042
:param repository: The repository to use.
2043
:param stack_on: A location to stack on
2044
:param stack_on_pwd: If stack_on is relative, the location it is
2047
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2049
self._repository = repository
2051
def acquire_repository(self, make_working_trees=None, shared=False,
2052
possible_transports=None):
2053
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2055
Returns an existing repository to use.
2057
if possible_transports is None:
2058
possible_transports = []
2060
possible_transports = list(possible_transports)
2061
possible_transports.append(self._repository.bzrdir.transport)
2062
self._add_fallback(self._repository,
2063
possible_transports=possible_transports)
2064
return self._repository, False
2067
def register_metadir(registry, key,
2068
repository_format, help, native=True, deprecated=False,
2073
alias=False, bzrdir_format=None):
2074
"""Register a metadir subformat.
2076
These all use a meta bzrdir, but can be parameterized by the
2077
Repository/Branch/WorkingTreeformats.
2079
:param repository_format: The fully-qualified repository format class
2081
:param branch_format: Fully-qualified branch format class name as
2083
:param tree_format: Fully-qualified tree format class name as
2086
if bzrdir_format is None:
2087
bzrdir_format = BzrDirMetaFormat1
2088
# This should be expanded to support setting WorkingTree and Branch
2089
# formats, once the API supports that.
2090
def _load(full_name):
2091
mod_name, factory_name = full_name.rsplit('.', 1)
2093
factory = pyutils.get_named_object(mod_name, factory_name)
2094
except ImportError, e:
2095
raise ImportError('failed to load %s: %s' % (full_name, e))
2096
except AttributeError:
2097
raise AttributeError('no factory %s in module %r'
2098
% (full_name, sys.modules[mod_name]))
2102
bd = bzrdir_format()
2103
if branch_format is not None:
2104
bd.set_branch_format(_load(branch_format))
2105
if tree_format is not None:
2106
bd.workingtree_format = _load(tree_format)
2107
if repository_format is not None:
2108
bd.repository_format = _load(repository_format)
2110
registry.register(key, helper, help, native, deprecated, hidden,
2111
experimental, alias)
2113
register_metadir(controldir.format_registry, 'knit',
2114
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2115
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
2116
branch_format='bzrlib.branch.BzrBranchFormat5',
2117
tree_format='bzrlib.workingtree_3.WorkingTreeFormat3',
2120
register_metadir(controldir.format_registry, 'dirstate',
2121
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2122
help='Format using dirstate for working trees. '
2123
'Compatible with bzr 0.8 and '
2124
'above when accessed over the network. Introduced in bzr 0.15.',
2125
branch_format='bzrlib.branch.BzrBranchFormat5',
2126
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2129
register_metadir(controldir.format_registry, 'dirstate-tags',
2130
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2131
help='Variant of dirstate with support for tags. '
2132
'Introduced in bzr 0.15.',
2133
branch_format='bzrlib.branch.BzrBranchFormat6',
2134
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2137
register_metadir(controldir.format_registry, 'rich-root',
2138
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
2139
help='Variant of dirstate with better handling of tree roots. '
2140
'Introduced in bzr 1.0',
2141
branch_format='bzrlib.branch.BzrBranchFormat6',
2142
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2145
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
2146
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2147
help='Variant of dirstate with support for nested trees. '
2148
'Introduced in 0.15.',
2149
branch_format='bzrlib.branch.BzrBranchFormat6',
2150
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2154
register_metadir(controldir.format_registry, 'pack-0.92',
2155
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
2156
help='Pack-based format used in 1.x series. Introduced in 0.92. '
2157
'Interoperates with bzr repositories before 0.92 but cannot be '
2158
'read by bzr < 0.92. '
2160
branch_format='bzrlib.branch.BzrBranchFormat6',
2161
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2164
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2165
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
2166
help='Pack-based format used in 1.x series, with subtree support. '
2167
'Introduced in 0.92. Interoperates with '
2168
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2170
branch_format='bzrlib.branch.BzrBranchFormat6',
2171
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2176
register_metadir(controldir.format_registry, 'rich-root-pack',
2177
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
2178
help='A variant of pack-0.92 that supports rich-root data '
2179
'(needed for bzr-svn and bzr-git). Introduced in 1.0.',
2180
branch_format='bzrlib.branch.BzrBranchFormat6',
2181
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2185
register_metadir(controldir.format_registry, '1.6',
2186
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
2187
help='A format that allows a branch to indicate that there is another '
2188
'(stacked) repository that should be used to access data that is '
2189
'not present locally.',
2190
branch_format='bzrlib.branch.BzrBranchFormat7',
2191
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2195
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2196
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
2197
help='A variant of 1.6 that supports rich-root data '
2198
'(needed for bzr-svn and bzr-git).',
2199
branch_format='bzrlib.branch.BzrBranchFormat7',
2200
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2204
register_metadir(controldir.format_registry, '1.9',
2205
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2206
help='A repository format using B+tree indexes. These indexes '
2207
'are smaller in size, have smarter caching and provide faster '
2208
'performance for most operations.',
2209
branch_format='bzrlib.branch.BzrBranchFormat7',
2210
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2214
register_metadir(controldir.format_registry, '1.9-rich-root',
2215
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2216
help='A variant of 1.9 that supports rich-root data '
2217
'(needed for bzr-svn and bzr-git).',
2218
branch_format='bzrlib.branch.BzrBranchFormat7',
2219
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2223
register_metadir(controldir.format_registry, '1.14',
2224
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2225
help='A working-tree format that supports content filtering.',
2226
branch_format='bzrlib.branch.BzrBranchFormat7',
2227
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2231
register_metadir(controldir.format_registry, '1.14-rich-root',
2232
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2233
help='A variant of 1.14 that supports rich-root data '
2234
'(needed for bzr-svn and bzr-git).',
2235
branch_format='bzrlib.branch.BzrBranchFormat7',
2236
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2240
# The following un-numbered 'development' formats should always just be aliases.
2241
register_metadir(controldir.format_registry, 'development-subtree',
2242
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2aSubtree',
2243
help='Current development format, subtree variant. Can convert data to and '
2244
'from pack-0.92-subtree (and anything compatible with '
2245
'pack-0.92-subtree) format repositories. Repositories and branches in '
2246
'this format can only be read by bzr.dev. Please read '
2247
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2249
branch_format='bzrlib.branch.BzrBranchFormat7',
2250
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2253
alias=False, # Restore to being an alias when an actual development subtree format is added
2254
# This current non-alias status is simply because we did not introduce a
2255
# chk based subtree format.
2257
register_metadir(controldir.format_registry, 'development5-subtree',
2258
'bzrlib.repofmt.knitpack_repo.RepositoryFormatPackDevelopment2Subtree',
2259
help='Development format, subtree variant. Can convert data to and '
2260
'from pack-0.92-subtree (and anything compatible with '
2261
'pack-0.92-subtree) format repositories. Repositories and branches in '
2262
'this format can only be read by bzr.dev. Please read '
2263
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2265
branch_format='bzrlib.branch.BzrBranchFormat7',
2266
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2272
register_metadir(controldir.format_registry, 'development-colo',
2273
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2274
help='The 2a format with experimental support for colocated branches.\n',
2275
branch_format='bzrlib.branch.BzrBranchFormat7',
2276
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2278
bzrdir_format=BzrDirMetaFormat1Colo,
2282
# And the development formats above will have aliased one of the following:
2284
# Finally, the current format.
2285
register_metadir(controldir.format_registry, '2a',
2286
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2287
help='Format for the bzr 2.0 series.\n'
2288
'Uses group-compress storage.\n'
2289
'Provides rich roots which are a one-way transition.\n',
2290
# 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
2291
# 'rich roots. Supported by bzr 1.16 and later.',
2292
branch_format='bzrlib.branch.BzrBranchFormat7',
2293
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2297
# The following format should be an alias for the rich root equivalent
2298
# of the default format
2299
register_metadir(controldir.format_registry, 'default-rich-root',
2300
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2301
branch_format='bzrlib.branch.BzrBranchFormat7',
2302
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2307
# The current format that is made on 'bzr init'.
2308
format_name = config.GlobalStack().get('default_format')
2309
controldir.format_registry.set_default(format_name)
2311
# XXX 2010-08-20 JRV: There is still a lot of code relying on
2312
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc
2313
# get changed to ControlDir.create/ControlDir.open/etc this should be removed.
2314
format_registry = controldir.format_registry