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
@deprecated_method(deprecated_in((2, 3, 0)))
469
def generate_backup_name(self, base):
470
return self._available_backup_name(base)
472
def _available_backup_name(self, base):
473
"""Find a non-existing backup file name based on base.
475
See bzrlib.osutils.available_backup_name about race conditions.
477
return osutils.available_backup_name(base, self.root_transport.has)
479
def backup_bzrdir(self):
480
"""Backup this bzr control directory.
482
:return: Tuple with old path name and new path name
485
pb = ui.ui_factory.nested_progress_bar()
487
old_path = self.root_transport.abspath('.bzr')
488
backup_dir = self._available_backup_name('backup.bzr')
489
new_path = self.root_transport.abspath(backup_dir)
490
ui.ui_factory.note(gettext('making backup of {0}\n to {1}').format(
491
urlutils.unescape_for_display(old_path, 'utf-8'),
492
urlutils.unescape_for_display(new_path, 'utf-8')))
493
self.root_transport.copy_tree('.bzr', backup_dir)
494
return (old_path, new_path)
498
def retire_bzrdir(self, limit=10000):
499
"""Permanently disable the bzrdir.
501
This is done by renaming it to give the user some ability to recover
502
if there was a problem.
504
This will have horrible consequences if anyone has anything locked or
506
:param limit: number of times to retry
511
to_path = '.bzr.retired.%d' % i
512
self.root_transport.rename('.bzr', to_path)
513
note(gettext("renamed {0} to {1}").format(
514
self.root_transport.abspath('.bzr'), to_path))
516
except (errors.TransportError, IOError, errors.PathError):
523
def _find_containing(self, evaluate):
524
"""Find something in a containing control directory.
526
This method will scan containing control dirs, until it finds what
527
it is looking for, decides that it will never find it, or runs out
528
of containing control directories to check.
530
It is used to implement find_repository and
531
determine_repository_policy.
533
:param evaluate: A function returning (value, stop). If stop is True,
534
the value will be returned.
538
result, stop = evaluate(found_bzrdir)
541
next_transport = found_bzrdir.root_transport.clone('..')
542
if (found_bzrdir.user_url == next_transport.base):
543
# top of the file system
545
# find the next containing bzrdir
547
found_bzrdir = self.open_containing_from_transport(
549
except errors.NotBranchError:
552
def find_repository(self):
553
"""Find the repository that should be used.
555
This does not require a branch as we use it to find the repo for
556
new branches as well as to hook existing branches up to their
559
def usable_repository(found_bzrdir):
560
# does it have a repository ?
562
repository = found_bzrdir.open_repository()
563
except errors.NoRepositoryPresent:
565
if found_bzrdir.user_url == self.user_url:
566
return repository, True
567
elif repository.is_shared():
568
return repository, True
572
found_repo = self._find_containing(usable_repository)
573
if found_repo is None:
574
raise errors.NoRepositoryPresent(self)
577
def _find_creation_modes(self):
578
"""Determine the appropriate modes for files and directories.
580
They're always set to be consistent with the base directory,
581
assuming that this transport allows setting modes.
583
# TODO: Do we need or want an option (maybe a config setting) to turn
584
# this off or override it for particular locations? -- mbp 20080512
585
if self._mode_check_done:
587
self._mode_check_done = True
589
st = self.transport.stat('.')
590
except errors.TransportNotPossible:
591
self._dir_mode = None
592
self._file_mode = None
594
# Check the directory mode, but also make sure the created
595
# directories and files are read-write for this user. This is
596
# mostly a workaround for filesystems which lie about being able to
597
# write to a directory (cygwin & win32)
598
if (st.st_mode & 07777 == 00000):
599
# FTP allows stat but does not return dir/file modes
600
self._dir_mode = None
601
self._file_mode = None
603
self._dir_mode = (st.st_mode & 07777) | 00700
604
# Remove the sticky and execute bits for files
605
self._file_mode = self._dir_mode & ~07111
607
def _get_file_mode(self):
608
"""Return Unix mode for newly created files, or None.
610
if not self._mode_check_done:
611
self._find_creation_modes()
612
return self._file_mode
614
def _get_dir_mode(self):
615
"""Return Unix mode for newly created directories, or None.
617
if not self._mode_check_done:
618
self._find_creation_modes()
619
return self._dir_mode
621
def get_config(self):
622
"""Get configuration for this BzrDir."""
623
return config.BzrDirConfig(self)
625
def _get_config(self):
626
"""By default, no configuration is available."""
629
def __init__(self, _transport, _format):
630
"""Initialize a Bzr control dir object.
632
Only really common logic should reside here, concrete classes should be
633
made with varying behaviours.
635
:param _format: the format that is creating this BzrDir instance.
636
:param _transport: the transport this dir is based at.
638
self._format = _format
639
# these are also under the more standard names of
640
# control_transport and user_transport
641
self.transport = _transport.clone('.bzr')
642
self.root_transport = _transport
643
self._mode_check_done = False
646
def user_transport(self):
647
return self.root_transport
650
def control_transport(self):
651
return self.transport
653
def is_control_filename(self, filename):
654
"""True if filename is the name of a path which is reserved for bzrdir's.
656
:param filename: A filename within the root transport of this bzrdir.
658
This is true IF and ONLY IF the filename is part of the namespace reserved
659
for bzr control dirs. Currently this is the '.bzr' directory in the root
660
of the root_transport.
662
# this might be better on the BzrDirFormat class because it refers to
663
# all the possible bzrdir disk formats.
664
# This method is tested via the workingtree is_control_filename tests-
665
# it was extracted from WorkingTree.is_control_filename. If the method's
666
# contract is extended beyond the current trivial implementation, please
667
# add new tests for it to the appropriate place.
668
return filename == '.bzr' or filename.startswith('.bzr/')
670
def _cloning_metadir(self):
671
"""Produce a metadir suitable for cloning with.
673
:returns: (destination_bzrdir_format, source_repository)
675
result_format = self._format.__class__()
678
branch = self.open_branch(ignore_fallbacks=True)
679
source_repository = branch.repository
680
result_format._branch_format = branch._format
681
except errors.NotBranchError:
683
source_repository = self.open_repository()
684
except errors.NoRepositoryPresent:
685
source_repository = None
687
# XXX TODO: This isinstance is here because we have not implemented
688
# the fix recommended in bug # 103195 - to delegate this choice the
690
repo_format = source_repository._format
691
if isinstance(repo_format, remote.RemoteRepositoryFormat):
692
source_repository._ensure_real()
693
repo_format = source_repository._real_repository._format
694
result_format.repository_format = repo_format
696
# TODO: Couldn't we just probe for the format in these cases,
697
# rather than opening the whole tree? It would be a little
698
# faster. mbp 20070401
699
tree = self.open_workingtree(recommend_upgrade=False)
700
except (errors.NoWorkingTree, errors.NotLocalUrl):
701
result_format.workingtree_format = None
703
result_format.workingtree_format = tree._format.__class__()
704
return result_format, source_repository
706
def cloning_metadir(self, require_stacking=False):
707
"""Produce a metadir suitable for cloning or sprouting with.
709
These operations may produce workingtrees (yes, even though they're
710
"cloning" something that doesn't have a tree), so a viable workingtree
711
format must be selected.
713
:require_stacking: If True, non-stackable formats will be upgraded
714
to similar stackable formats.
715
:returns: a ControlDirFormat with all component formats either set
716
appropriately or set to None if that component should not be
719
format, repository = self._cloning_metadir()
720
if format._workingtree_format is None:
722
if repository is None:
723
# No repository either
725
# We have a repository, so set a working tree? (Why? This seems to
726
# contradict the stated return value in the docstring).
727
tree_format = repository._format._matchingbzrdir.workingtree_format
728
format.workingtree_format = tree_format.__class__()
730
format.require_stacking()
733
def get_branch_transport(self, branch_format, name=None):
734
"""Get the transport for use by branch format in this BzrDir.
736
Note that bzr dirs that do not support format strings will raise
737
IncompatibleFormat if the branch format they are given has
738
a format string, and vice versa.
740
If branch_format is None, the transport is returned with no
741
checking. If it is not None, then the returned transport is
742
guaranteed to point to an existing directory ready for use.
744
raise NotImplementedError(self.get_branch_transport)
746
def get_repository_transport(self, repository_format):
747
"""Get the transport for use by repository format in this BzrDir.
749
Note that bzr dirs that do not support format strings will raise
750
IncompatibleFormat if the repository format they are given has
751
a format string, and vice versa.
753
If repository_format is None, the transport is returned with no
754
checking. If it is not None, then the returned transport is
755
guaranteed to point to an existing directory ready for use.
757
raise NotImplementedError(self.get_repository_transport)
759
def get_workingtree_transport(self, tree_format):
760
"""Get the transport for use by workingtree format in this BzrDir.
762
Note that bzr dirs that do not support format strings will raise
763
IncompatibleFormat if the workingtree format they are given has a
764
format string, and vice versa.
766
If workingtree_format is None, the transport is returned with no
767
checking. If it is not None, then the returned transport is
768
guaranteed to point to an existing directory ready for use.
770
raise NotImplementedError(self.get_workingtree_transport)
773
def create(cls, base, format=None, possible_transports=None):
774
"""Create a new BzrDir at the url 'base'.
776
:param format: If supplied, the format of branch to create. If not
777
supplied, the default is used.
778
:param possible_transports: If supplied, a list of transports that
779
can be reused to share a remote connection.
781
if cls is not BzrDir:
782
raise AssertionError("BzrDir.create always creates the "
783
"default format, not one of %r" % cls)
784
return controldir.ControlDir.create(base, format=format,
785
possible_transports=possible_transports)
788
return "<%s at %r>" % (self.__class__.__name__, self.user_url)
790
def update_feature_flags(self, updated_flags):
791
"""Update the features required by this bzrdir.
793
:param updated_flags: Dictionary mapping feature names to necessities
794
A necessity can be None to indicate the feature should be removed
796
self.control_files.lock_write()
798
self._format._update_feature_flags(updated_flags)
799
self.transport.put_bytes('branch-format', self._format.as_string())
801
self.control_files.unlock()
804
class BzrDirMeta1(BzrDir):
805
"""A .bzr meta version 1 control object.
807
This is the first control object where the
808
individual aspects are really split out: there are separate repository,
809
workingtree and branch subdirectories and any subset of the three can be
810
present within a BzrDir.
813
def _get_branch_path(self, name):
814
"""Obtain the branch path to use.
816
This uses the API specified branch name first, and then falls back to
817
the branch name specified in the URL. If neither of those is specified,
818
it uses the default branch.
820
:param name: Optional branch name to use
821
:return: Relative path to branch
825
return urlutils.join('branches', name.encode("utf-8"))
827
def _read_branch_list(self):
828
"""Read the branch list.
830
:return: List of utf-8 encoded branch names.
833
f = self.control_transport.get('branch-list')
834
except errors.NoSuchFile:
840
ret.append(name.rstrip("\n"))
845
def _write_branch_list(self, branches):
846
"""Write out the branch list.
848
:param branches: List of utf-8 branch names to write
850
self.transport.put_bytes('branch-list',
851
"".join([name+"\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
def can_convert_format(self):
860
"""See BzrDir.can_convert_format()."""
863
def create_branch(self, name=None, repository=None,
864
append_revisions_only=None):
865
"""See BzrDir.create_branch."""
867
name = self._get_selected_branch()
868
return self._format.get_branch_format().initialize(self, name=name,
869
repository=repository,
870
append_revisions_only=append_revisions_only)
872
def destroy_branch(self, name=None):
873
"""See BzrDir.create_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.encode("utf-8"))
884
raise errors.NotBranchError(name)
885
self._write_branch_list(branches)
887
self.control_files.unlock()
888
self.transport.delete_tree(path)
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
@deprecated_method(deprecated_in((2, 4, 0)))
1234
def register_bzrdir_format(klass, format):
1235
klass.formats.register(format.get_format_string(), format)
1238
@deprecated_method(deprecated_in((2, 4, 0)))
1239
def unregister_bzrdir_format(klass, format):
1240
klass.formats.remove(format.get_format_string())
1243
def probe_transport(klass, transport):
1244
"""Return the .bzrdir style format present in a directory."""
1246
format_string = transport.get_bytes(".bzr/branch-format")
1247
except errors.NoSuchFile:
1248
raise errors.NotBranchError(path=transport.base)
1250
first_line = format_string[:format_string.index("\n")+1]
1252
first_line = format_string
1254
cls = klass.formats.get(first_line)
1256
raise errors.UnknownFormatError(format=first_line, kind='bzrdir')
1257
return cls.from_string(format_string)
1260
def known_formats(cls):
1262
for name, format in cls.formats.iteritems():
1263
if callable(format):
1269
controldir.ControlDirFormat.register_prober(BzrProber)
1272
class RemoteBzrProber(controldir.Prober):
1273
"""Prober for remote servers that provide a Bazaar smart server."""
1276
def probe_transport(klass, transport):
1277
"""Return a RemoteBzrDirFormat object if it looks possible."""
1279
medium = transport.get_smart_medium()
1280
except (NotImplementedError, AttributeError,
1281
errors.TransportNotPossible, errors.NoSmartMedium,
1282
errors.SmartProtocolError):
1283
# no smart server, so not a branch for this format type.
1284
raise errors.NotBranchError(path=transport.base)
1286
# Decline to open it if the server doesn't support our required
1287
# version (3) so that the VFS-based transport will do it.
1288
if medium.should_probe():
1290
server_version = medium.protocol_version()
1291
except errors.SmartProtocolError:
1292
# Apparently there's no usable smart server there, even though
1293
# the medium supports the smart protocol.
1294
raise errors.NotBranchError(path=transport.base)
1295
if server_version != '2':
1296
raise errors.NotBranchError(path=transport.base)
1297
from bzrlib.remote import RemoteBzrDirFormat
1298
return RemoteBzrDirFormat()
1301
def known_formats(cls):
1302
from bzrlib.remote import RemoteBzrDirFormat
1303
return set([RemoteBzrDirFormat()])
1306
class BzrDirFormat(BzrFormat, controldir.ControlDirFormat):
1307
"""ControlDirFormat base class for .bzr/ directories.
1309
Formats are placed in a dict by their format string for reference
1310
during bzrdir opening. These should be subclasses of BzrDirFormat
1313
Once a format is deprecated, just deprecate the initialize and open
1314
methods on the format class. Do not deprecate the object, as the
1315
object will be created every system load.
1318
_lock_file_name = 'branch-lock'
1320
# _lock_class must be set in subclasses to the lock type, typ.
1321
# TransportLock or LockDir
1323
def initialize_on_transport(self, transport):
1324
"""Initialize a new bzrdir in the base directory of a Transport."""
1326
# can we hand off the request to the smart server rather than using
1328
client_medium = transport.get_smart_medium()
1329
except errors.NoSmartMedium:
1330
return self._initialize_on_transport_vfs(transport)
1332
# Current RPC's only know how to create bzr metadir1 instances, so
1333
# we still delegate to vfs methods if the requested format is not a
1335
if type(self) != BzrDirMetaFormat1:
1336
return self._initialize_on_transport_vfs(transport)
1337
from bzrlib.remote import RemoteBzrDirFormat
1338
remote_format = RemoteBzrDirFormat()
1339
self._supply_sub_formats_to(remote_format)
1340
return remote_format.initialize_on_transport(transport)
1342
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1343
create_prefix=False, force_new_repo=False, stacked_on=None,
1344
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1345
shared_repo=False, vfs_only=False):
1346
"""Create this format on transport.
1348
The directory to initialize will be created.
1350
:param force_new_repo: Do not use a shared repository for the target,
1351
even if one is available.
1352
:param create_prefix: Create any missing directories leading up to
1354
:param use_existing_dir: Use an existing directory if one exists.
1355
:param stacked_on: A url to stack any created branch on, None to follow
1356
any target stacking policy.
1357
:param stack_on_pwd: If stack_on is relative, the location it is
1359
:param repo_format_name: If non-None, a repository will be
1360
made-or-found. Should none be found, or if force_new_repo is True
1361
the repo_format_name is used to select the format of repository to
1363
:param make_working_trees: Control the setting of make_working_trees
1364
for a new shared repository when one is made. None to use whatever
1365
default the format has.
1366
:param shared_repo: Control whether made repositories are shared or
1368
:param vfs_only: If True do not attempt to use a smart server
1369
:return: repo, bzrdir, require_stacking, repository_policy. repo is
1370
None if none was created or found, bzrdir is always valid.
1371
require_stacking is the result of examining the stacked_on
1372
parameter and any stacking policy found for the target.
1375
# Try to hand off to a smart server
1377
client_medium = transport.get_smart_medium()
1378
except errors.NoSmartMedium:
1381
from bzrlib.remote import RemoteBzrDirFormat
1382
# TODO: lookup the local format from a server hint.
1383
remote_dir_format = RemoteBzrDirFormat()
1384
remote_dir_format._network_name = self.network_name()
1385
self._supply_sub_formats_to(remote_dir_format)
1386
return remote_dir_format.initialize_on_transport_ex(transport,
1387
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1388
force_new_repo=force_new_repo, stacked_on=stacked_on,
1389
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1390
make_working_trees=make_working_trees, shared_repo=shared_repo)
1391
# XXX: Refactor the create_prefix/no_create_prefix code into a
1392
# common helper function
1393
# The destination may not exist - if so make it according to policy.
1394
def make_directory(transport):
1395
transport.mkdir('.')
1397
def redirected(transport, e, redirection_notice):
1398
note(redirection_notice)
1399
return transport._redirected_to(e.source, e.target)
1401
transport = do_catching_redirections(make_directory, transport,
1403
except errors.FileExists:
1404
if not use_existing_dir:
1406
except errors.NoSuchFile:
1407
if not create_prefix:
1409
transport.create_prefix()
1411
require_stacking = (stacked_on is not None)
1412
# Now the target directory exists, but doesn't have a .bzr
1413
# directory. So we need to create it, along with any work to create
1414
# all of the dependent branches, etc.
1416
result = self.initialize_on_transport(transport)
1417
if repo_format_name:
1419
# use a custom format
1420
result._format.repository_format = \
1421
repository.network_format_registry.get(repo_format_name)
1422
except AttributeError:
1423
# The format didn't permit it to be set.
1425
# A repository is desired, either in-place or shared.
1426
repository_policy = result.determine_repository_policy(
1427
force_new_repo, stacked_on, stack_on_pwd,
1428
require_stacking=require_stacking)
1429
result_repo, is_new_repo = repository_policy.acquire_repository(
1430
make_working_trees, shared_repo)
1431
if not require_stacking and repository_policy._require_stacking:
1432
require_stacking = True
1433
result._format.require_stacking()
1434
result_repo.lock_write()
1437
repository_policy = None
1438
return result_repo, result, require_stacking, repository_policy
1440
def _initialize_on_transport_vfs(self, transport):
1441
"""Initialize a new bzrdir using VFS calls.
1443
:param transport: The transport to create the .bzr directory in.
1446
# Since we are creating a .bzr directory, inherit the
1447
# mode from the root directory
1448
temp_control = lockable_files.LockableFiles(transport,
1449
'', lockable_files.TransportLock)
1451
temp_control._transport.mkdir('.bzr',
1452
# FIXME: RBC 20060121 don't peek under
1454
mode=temp_control._dir_mode)
1455
except errors.FileExists:
1456
raise errors.AlreadyControlDirError(transport.base)
1457
if sys.platform == 'win32' and isinstance(transport, local.LocalTransport):
1458
win32utils.set_file_attr_hidden(transport._abspath('.bzr'))
1459
file_mode = temp_control._file_mode
1461
bzrdir_transport = transport.clone('.bzr')
1462
utf8_files = [('README',
1463
"This is a Bazaar control directory.\n"
1464
"Do not change any files in this directory.\n"
1465
"See http://bazaar.canonical.com/ for more information about Bazaar.\n"),
1466
('branch-format', self.as_string()),
1468
# NB: no need to escape relative paths that are url safe.
1469
control_files = lockable_files.LockableFiles(bzrdir_transport,
1470
self._lock_file_name, self._lock_class)
1471
control_files.create_lock()
1472
control_files.lock_write()
1474
for (filename, content) in utf8_files:
1475
bzrdir_transport.put_bytes(filename, content,
1478
control_files.unlock()
1479
return self.open(transport, _found=True)
1481
def open(self, transport, _found=False):
1482
"""Return an instance of this format for the dir transport points at.
1484
_found is a private parameter, do not use it.
1487
found_format = controldir.ControlDirFormat.find_format(transport)
1488
if not isinstance(found_format, self.__class__):
1489
raise AssertionError("%s was asked to open %s, but it seems to need "
1491
% (self, transport, found_format))
1492
# Allow subclasses - use the found format.
1493
self._supply_sub_formats_to(found_format)
1494
return found_format._open(transport)
1495
return self._open(transport)
1497
def _open(self, transport):
1498
"""Template method helper for opening BzrDirectories.
1500
This performs the actual open and any additional logic or parameter
1503
raise NotImplementedError(self._open)
1505
def _supply_sub_formats_to(self, other_format):
1506
"""Give other_format the same values for sub formats as this has.
1508
This method is expected to be used when parameterising a
1509
RemoteBzrDirFormat instance with the parameters from a
1510
BzrDirMetaFormat1 instance.
1512
:param other_format: other_format is a format which should be
1513
compatible with whatever sub formats are supported by self.
1516
other_format.features = dict(self.features)
1518
def supports_transport(self, transport):
1519
# bzr formats can be opened over all known transports
1522
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1524
controldir.ControlDirFormat.check_support_status(self,
1525
allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
1527
BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
1528
recommend_upgrade=recommend_upgrade, basedir=basedir)
1531
class BzrDirMetaFormat1(BzrDirFormat):
1532
"""Bzr meta control format 1
1534
This is the first format with split out working tree, branch and repository
1539
- Format 3 working trees [optional]
1540
- Format 5 branches [optional]
1541
- Format 7 repositories [optional]
1544
_lock_class = lockdir.LockDir
1546
fixed_components = False
1548
colocated_branches = True
1551
BzrDirFormat.__init__(self)
1552
self._workingtree_format = None
1553
self._branch_format = None
1554
self._repository_format = None
1556
def __eq__(self, other):
1557
if other.__class__ is not self.__class__:
1559
if other.repository_format != self.repository_format:
1561
if other.workingtree_format != self.workingtree_format:
1563
if other.features != self.features:
1567
def __ne__(self, other):
1568
return not self == other
1570
def get_branch_format(self):
1571
if self._branch_format is None:
1572
from bzrlib.branch import format_registry as branch_format_registry
1573
self._branch_format = branch_format_registry.get_default()
1574
return self._branch_format
1576
def set_branch_format(self, format):
1577
self._branch_format = format
1579
def require_stacking(self, stack_on=None, possible_transports=None,
1581
"""We have a request to stack, try to ensure the formats support it.
1583
:param stack_on: If supplied, it is the URL to a branch that we want to
1584
stack on. Check to see if that format supports stacking before
1587
# Stacking is desired. requested by the target, but does the place it
1588
# points at support stacking? If it doesn't then we should
1589
# not implicitly upgrade. We check this here.
1590
new_repo_format = None
1591
new_branch_format = None
1593
# a bit of state for get_target_branch so that we don't try to open it
1594
# 2 times, for both repo *and* branch
1595
target = [None, False, None] # target_branch, checked, upgrade anyway
1596
def get_target_branch():
1598
# We've checked, don't check again
1600
if stack_on is None:
1601
# No target format, that means we want to force upgrading
1602
target[:] = [None, True, True]
1605
target_dir = BzrDir.open(stack_on,
1606
possible_transports=possible_transports)
1607
except errors.NotBranchError:
1608
# Nothing there, don't change formats
1609
target[:] = [None, True, False]
1611
except errors.JailBreak:
1612
# JailBreak, JFDI and upgrade anyway
1613
target[:] = [None, True, True]
1616
target_branch = target_dir.open_branch()
1617
except errors.NotBranchError:
1618
# No branch, don't upgrade formats
1619
target[:] = [None, True, False]
1621
target[:] = [target_branch, True, False]
1624
if (not _skip_repo and
1625
not self.repository_format.supports_external_lookups):
1626
# We need to upgrade the Repository.
1627
target_branch, _, do_upgrade = get_target_branch()
1628
if target_branch is None:
1629
# We don't have a target branch, should we upgrade anyway?
1631
# stack_on is inaccessible, JFDI.
1632
# TODO: bad monkey, hard-coded formats...
1633
if self.repository_format.rich_root_data:
1634
new_repo_format = knitpack_repo.RepositoryFormatKnitPack5RichRoot()
1636
new_repo_format = knitpack_repo.RepositoryFormatKnitPack5()
1638
# If the target already supports stacking, then we know the
1639
# project is already able to use stacking, so auto-upgrade
1641
new_repo_format = target_branch.repository._format
1642
if not new_repo_format.supports_external_lookups:
1643
# target doesn't, source doesn't, so don't auto upgrade
1645
new_repo_format = None
1646
if new_repo_format is not None:
1647
self.repository_format = new_repo_format
1648
note(gettext('Source repository format does not support stacking,'
1649
' using format:\n %s'),
1650
new_repo_format.get_format_description())
1652
if not self.get_branch_format().supports_stacking():
1653
# We just checked the repo, now lets check if we need to
1654
# upgrade the branch format
1655
target_branch, _, do_upgrade = get_target_branch()
1656
if target_branch is None:
1658
# TODO: bad monkey, hard-coded formats...
1659
from bzrlib.branch import BzrBranchFormat7
1660
new_branch_format = BzrBranchFormat7()
1662
new_branch_format = target_branch._format
1663
if not new_branch_format.supports_stacking():
1664
new_branch_format = None
1665
if new_branch_format is not None:
1666
# Does support stacking, use its format.
1667
self.set_branch_format(new_branch_format)
1668
note(gettext('Source branch format does not support stacking,'
1669
' using format:\n %s'),
1670
new_branch_format.get_format_description())
1672
def get_converter(self, format=None):
1673
"""See BzrDirFormat.get_converter()."""
1675
format = BzrDirFormat.get_default_format()
1676
if (type(self) is BzrDirMetaFormat1 and
1677
type(format) is BzrDirMetaFormat1Colo):
1678
return ConvertMetaToColo(format)
1679
if (type(self) is BzrDirMetaFormat1Colo and
1680
type(format) is BzrDirMetaFormat1):
1681
return ConvertMetaToColo(format)
1682
if not isinstance(self, format.__class__):
1683
# converting away from metadir is not implemented
1684
raise NotImplementedError(self.get_converter)
1685
return ConvertMetaToMeta(format)
1688
def get_format_string(cls):
1689
"""See BzrDirFormat.get_format_string()."""
1690
return "Bazaar-NG meta directory, format 1\n"
1692
def get_format_description(self):
1693
"""See BzrDirFormat.get_format_description()."""
1694
return "Meta directory format 1"
1696
def _open(self, transport):
1697
"""See BzrDirFormat._open."""
1698
# Create a new format instance because otherwise initialisation of new
1699
# metadirs share the global default format object leading to alias
1701
format = BzrDirMetaFormat1()
1702
self._supply_sub_formats_to(format)
1703
return BzrDirMeta1(transport, format)
1705
def __return_repository_format(self):
1706
"""Circular import protection."""
1707
if self._repository_format:
1708
return self._repository_format
1709
from bzrlib.repository import format_registry
1710
return format_registry.get_default()
1712
def _set_repository_format(self, value):
1713
"""Allow changing the repository format for metadir formats."""
1714
self._repository_format = value
1716
repository_format = property(__return_repository_format,
1717
_set_repository_format)
1719
def _supply_sub_formats_to(self, other_format):
1720
"""Give other_format the same values for sub formats as this has.
1722
This method is expected to be used when parameterising a
1723
RemoteBzrDirFormat instance with the parameters from a
1724
BzrDirMetaFormat1 instance.
1726
:param other_format: other_format is a format which should be
1727
compatible with whatever sub formats are supported by self.
1730
super(BzrDirMetaFormat1, self)._supply_sub_formats_to(other_format)
1731
if getattr(self, '_repository_format', None) is not None:
1732
other_format.repository_format = self.repository_format
1733
if self._branch_format is not None:
1734
other_format._branch_format = self._branch_format
1735
if self._workingtree_format is not None:
1736
other_format.workingtree_format = self.workingtree_format
1738
def __get_workingtree_format(self):
1739
if self._workingtree_format is None:
1740
from bzrlib.workingtree import (
1741
format_registry as wt_format_registry,
1743
self._workingtree_format = wt_format_registry.get_default()
1744
return self._workingtree_format
1746
def __set_workingtree_format(self, wt_format):
1747
self._workingtree_format = wt_format
1750
return "<%r>" % (self.__class__.__name__,)
1752
workingtree_format = property(__get_workingtree_format,
1753
__set_workingtree_format)
1756
# Register bzr formats
1757
BzrProber.formats.register(BzrDirMetaFormat1.get_format_string(),
1759
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1762
class BzrDirMetaFormat1Colo(BzrDirMetaFormat1):
1763
"""BzrDirMeta1 format with support for colocated branches."""
1765
colocated_branches = True
1768
def get_format_string(cls):
1769
"""See BzrDirFormat.get_format_string()."""
1770
return "Bazaar meta directory, format 1 (with colocated branches)\n"
1772
def get_format_description(self):
1773
"""See BzrDirFormat.get_format_description()."""
1774
return "Meta directory format 1 with support for colocated branches"
1776
def _open(self, transport):
1777
"""See BzrDirFormat._open."""
1778
# Create a new format instance because otherwise initialisation of new
1779
# metadirs share the global default format object leading to alias
1781
format = BzrDirMetaFormat1Colo()
1782
self._supply_sub_formats_to(format)
1783
return BzrDirMeta1(transport, format)
1786
BzrProber.formats.register(BzrDirMetaFormat1Colo.get_format_string(),
1787
BzrDirMetaFormat1Colo)
1790
class ConvertMetaToMeta(controldir.Converter):
1791
"""Converts the components of metadirs."""
1793
def __init__(self, target_format):
1794
"""Create a metadir to metadir converter.
1796
:param target_format: The final metadir format that is desired.
1798
self.target_format = target_format
1800
def convert(self, to_convert, pb):
1801
"""See Converter.convert()."""
1802
self.bzrdir = to_convert
1803
self.pb = ui.ui_factory.nested_progress_bar()
1806
self.step('checking repository format')
1808
repo = self.bzrdir.open_repository()
1809
except errors.NoRepositoryPresent:
1812
if not isinstance(repo._format, self.target_format.repository_format.__class__):
1813
from bzrlib.repository import CopyConverter
1814
ui.ui_factory.note(gettext('starting repository conversion'))
1815
converter = CopyConverter(self.target_format.repository_format)
1816
converter.convert(repo, pb)
1817
for branch in self.bzrdir.list_branches():
1818
# TODO: conversions of Branch and Tree should be done by
1819
# InterXFormat lookups/some sort of registry.
1820
# Avoid circular imports
1821
old = branch._format.__class__
1822
new = self.target_format.get_branch_format().__class__
1824
if (old == _mod_branch.BzrBranchFormat5 and
1825
new in (_mod_branch.BzrBranchFormat6,
1826
_mod_branch.BzrBranchFormat7,
1827
_mod_branch.BzrBranchFormat8)):
1828
branch_converter = _mod_branch.Converter5to6()
1829
elif (old == _mod_branch.BzrBranchFormat6 and
1830
new in (_mod_branch.BzrBranchFormat7,
1831
_mod_branch.BzrBranchFormat8)):
1832
branch_converter = _mod_branch.Converter6to7()
1833
elif (old == _mod_branch.BzrBranchFormat7 and
1834
new is _mod_branch.BzrBranchFormat8):
1835
branch_converter = _mod_branch.Converter7to8()
1837
raise errors.BadConversionTarget("No converter", new,
1839
branch_converter.convert(branch)
1840
branch = self.bzrdir.open_branch()
1841
old = branch._format.__class__
1843
tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
1844
except (errors.NoWorkingTree, errors.NotLocalUrl):
1847
# TODO: conversions of Branch and Tree should be done by
1848
# InterXFormat lookups
1849
if (isinstance(tree, workingtree_3.WorkingTree3) and
1850
not isinstance(tree, workingtree_4.DirStateWorkingTree) and
1851
isinstance(self.target_format.workingtree_format,
1852
workingtree_4.DirStateWorkingTreeFormat)):
1853
workingtree_4.Converter3to4().convert(tree)
1854
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1855
not isinstance(tree, workingtree_4.WorkingTree5) and
1856
isinstance(self.target_format.workingtree_format,
1857
workingtree_4.WorkingTreeFormat5)):
1858
workingtree_4.Converter4to5().convert(tree)
1859
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1860
not isinstance(tree, workingtree_4.WorkingTree6) and
1861
isinstance(self.target_format.workingtree_format,
1862
workingtree_4.WorkingTreeFormat6)):
1863
workingtree_4.Converter4or5to6().convert(tree)
1868
class ConvertMetaToColo(controldir.Converter):
1869
"""Add colocated branch support."""
1871
def __init__(self, target_format):
1872
"""Create a converter.that upgrades a metadir to the colo format.
1874
:param target_format: The final metadir format that is desired.
1876
self.target_format = target_format
1878
def convert(self, to_convert, pb):
1879
"""See Converter.convert()."""
1880
to_convert.transport.put_bytes('branch-format',
1881
self.target_format.as_string())
1882
return BzrDir.open_from_transport(to_convert.root_transport)
1885
class ConvertMetaToColo(controldir.Converter):
1886
"""Convert a 'development-colo' bzrdir to a '2a' bzrdir."""
1888
def __init__(self, target_format):
1889
"""Create a converter that converts a 'development-colo' metadir
1892
:param target_format: The final metadir format that is desired.
1894
self.target_format = target_format
1896
def convert(self, to_convert, pb):
1897
"""See Converter.convert()."""
1898
to_convert.transport.put_bytes('branch-format',
1899
self.target_format.as_string())
1900
return BzrDir.open_from_transport(to_convert.root_transport)
1903
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
1906
class RepositoryAcquisitionPolicy(object):
1907
"""Abstract base class for repository acquisition policies.
1909
A repository acquisition policy decides how a BzrDir acquires a repository
1910
for a branch that is being created. The most basic policy decision is
1911
whether to create a new repository or use an existing one.
1913
def __init__(self, stack_on, stack_on_pwd, require_stacking):
1916
:param stack_on: A location to stack on
1917
:param stack_on_pwd: If stack_on is relative, the location it is
1919
:param require_stacking: If True, it is a failure to not stack.
1921
self._stack_on = stack_on
1922
self._stack_on_pwd = stack_on_pwd
1923
self._require_stacking = require_stacking
1925
def configure_branch(self, branch):
1926
"""Apply any configuration data from this policy to the branch.
1928
Default implementation sets repository stacking.
1930
if self._stack_on is None:
1932
if self._stack_on_pwd is None:
1933
stack_on = self._stack_on
1936
stack_on = urlutils.rebase_url(self._stack_on,
1939
except errors.InvalidRebaseURLs:
1940
stack_on = self._get_full_stack_on()
1942
branch.set_stacked_on_url(stack_on)
1943
except (errors.UnstackableBranchFormat,
1944
errors.UnstackableRepositoryFormat):
1945
if self._require_stacking:
1948
def requires_stacking(self):
1949
"""Return True if this policy requires stacking."""
1950
return self._stack_on is not None and self._require_stacking
1952
def _get_full_stack_on(self):
1953
"""Get a fully-qualified URL for the stack_on location."""
1954
if self._stack_on is None:
1956
if self._stack_on_pwd is None:
1957
return self._stack_on
1959
return urlutils.join(self._stack_on_pwd, self._stack_on)
1961
def _add_fallback(self, repository, possible_transports=None):
1962
"""Add a fallback to the supplied repository, if stacking is set."""
1963
stack_on = self._get_full_stack_on()
1964
if stack_on is None:
1967
stacked_dir = BzrDir.open(stack_on,
1968
possible_transports=possible_transports)
1969
except errors.JailBreak:
1970
# We keep the stacking details, but we are in the server code so
1971
# actually stacking is not needed.
1974
stacked_repo = stacked_dir.open_branch().repository
1975
except errors.NotBranchError:
1976
stacked_repo = stacked_dir.open_repository()
1978
repository.add_fallback_repository(stacked_repo)
1979
except errors.UnstackableRepositoryFormat:
1980
if self._require_stacking:
1983
self._require_stacking = True
1985
def acquire_repository(self, make_working_trees=None, shared=False,
1986
possible_transports=None):
1987
"""Acquire a repository for this bzrdir.
1989
Implementations may create a new repository or use a pre-exising
1992
:param make_working_trees: If creating a repository, set
1993
make_working_trees to this value (if non-None)
1994
:param shared: If creating a repository, make it shared if True
1995
:return: A repository, is_new_flag (True if the repository was
1998
raise NotImplementedError(RepositoryAcquisitionPolicy.acquire_repository)
2001
class CreateRepository(RepositoryAcquisitionPolicy):
2002
"""A policy of creating a new repository"""
2004
def __init__(self, bzrdir, stack_on=None, stack_on_pwd=None,
2005
require_stacking=False):
2008
:param bzrdir: The bzrdir to create the repository on.
2009
:param stack_on: A location to stack on
2010
:param stack_on_pwd: If stack_on is relative, the location it is
2013
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2015
self._bzrdir = bzrdir
2017
def acquire_repository(self, make_working_trees=None, shared=False,
2018
possible_transports=None):
2019
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2021
Creates the desired repository in the bzrdir we already have.
2023
if possible_transports is None:
2024
possible_transports = []
2026
possible_transports = list(possible_transports)
2027
possible_transports.append(self._bzrdir.root_transport)
2028
stack_on = self._get_full_stack_on()
2030
format = self._bzrdir._format
2031
format.require_stacking(stack_on=stack_on,
2032
possible_transports=possible_transports)
2033
if not self._require_stacking:
2034
# We have picked up automatic stacking somewhere.
2035
note(gettext('Using default stacking branch {0} at {1}').format(
2036
self._stack_on, self._stack_on_pwd))
2037
repository = self._bzrdir.create_repository(shared=shared)
2038
self._add_fallback(repository,
2039
possible_transports=possible_transports)
2040
if make_working_trees is not None:
2041
repository.set_make_working_trees(make_working_trees)
2042
return repository, True
2045
class UseExistingRepository(RepositoryAcquisitionPolicy):
2046
"""A policy of reusing an existing repository"""
2048
def __init__(self, repository, stack_on=None, stack_on_pwd=None,
2049
require_stacking=False):
2052
:param repository: The repository to use.
2053
:param stack_on: A location to stack on
2054
:param stack_on_pwd: If stack_on is relative, the location it is
2057
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2059
self._repository = repository
2061
def acquire_repository(self, make_working_trees=None, shared=False,
2062
possible_transports=None):
2063
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2065
Returns an existing repository to use.
2067
if possible_transports is None:
2068
possible_transports = []
2070
possible_transports = list(possible_transports)
2071
possible_transports.append(self._repository.bzrdir.transport)
2072
self._add_fallback(self._repository,
2073
possible_transports=possible_transports)
2074
return self._repository, False
2077
def register_metadir(registry, key,
2078
repository_format, help, native=True, deprecated=False,
2083
alias=False, bzrdir_format=None):
2084
"""Register a metadir subformat.
2086
These all use a meta bzrdir, but can be parameterized by the
2087
Repository/Branch/WorkingTreeformats.
2089
:param repository_format: The fully-qualified repository format class
2091
:param branch_format: Fully-qualified branch format class name as
2093
:param tree_format: Fully-qualified tree format class name as
2096
if bzrdir_format is None:
2097
bzrdir_format = BzrDirMetaFormat1
2098
# This should be expanded to support setting WorkingTree and Branch
2099
# formats, once the API supports that.
2100
def _load(full_name):
2101
mod_name, factory_name = full_name.rsplit('.', 1)
2103
factory = pyutils.get_named_object(mod_name, factory_name)
2104
except ImportError, e:
2105
raise ImportError('failed to load %s: %s' % (full_name, e))
2106
except AttributeError:
2107
raise AttributeError('no factory %s in module %r'
2108
% (full_name, sys.modules[mod_name]))
2112
bd = bzrdir_format()
2113
if branch_format is not None:
2114
bd.set_branch_format(_load(branch_format))
2115
if tree_format is not None:
2116
bd.workingtree_format = _load(tree_format)
2117
if repository_format is not None:
2118
bd.repository_format = _load(repository_format)
2120
registry.register(key, helper, help, native, deprecated, hidden,
2121
experimental, alias)
2123
register_metadir(controldir.format_registry, 'knit',
2124
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2125
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
2126
branch_format='bzrlib.branch.BzrBranchFormat5',
2127
tree_format='bzrlib.workingtree_3.WorkingTreeFormat3',
2130
register_metadir(controldir.format_registry, 'dirstate',
2131
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2132
help='Format using dirstate for working trees. '
2133
'Compatible with bzr 0.8 and '
2134
'above when accessed over the network. Introduced in bzr 0.15.',
2135
branch_format='bzrlib.branch.BzrBranchFormat5',
2136
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2139
register_metadir(controldir.format_registry, 'dirstate-tags',
2140
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2141
help='Variant of dirstate with support for tags. '
2142
'Introduced in bzr 0.15.',
2143
branch_format='bzrlib.branch.BzrBranchFormat6',
2144
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2147
register_metadir(controldir.format_registry, 'rich-root',
2148
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
2149
help='Variant of dirstate with better handling of tree roots. '
2150
'Introduced in bzr 1.0',
2151
branch_format='bzrlib.branch.BzrBranchFormat6',
2152
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2155
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
2156
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2157
help='Variant of dirstate with support for nested trees. '
2158
'Introduced in 0.15.',
2159
branch_format='bzrlib.branch.BzrBranchFormat6',
2160
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2164
register_metadir(controldir.format_registry, 'pack-0.92',
2165
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
2166
help='Pack-based format used in 1.x series. Introduced in 0.92. '
2167
'Interoperates with bzr repositories before 0.92 but cannot be '
2168
'read by bzr < 0.92. '
2170
branch_format='bzrlib.branch.BzrBranchFormat6',
2171
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2174
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2175
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
2176
help='Pack-based format used in 1.x series, with subtree support. '
2177
'Introduced in 0.92. Interoperates with '
2178
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2180
branch_format='bzrlib.branch.BzrBranchFormat6',
2181
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2186
register_metadir(controldir.format_registry, 'rich-root-pack',
2187
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
2188
help='A variant of pack-0.92 that supports rich-root data '
2189
'(needed for bzr-svn and bzr-git). Introduced in 1.0.',
2190
branch_format='bzrlib.branch.BzrBranchFormat6',
2191
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2195
register_metadir(controldir.format_registry, '1.6',
2196
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
2197
help='A format that allows a branch to indicate that there is another '
2198
'(stacked) repository that should be used to access data that is '
2199
'not present locally.',
2200
branch_format='bzrlib.branch.BzrBranchFormat7',
2201
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2205
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2206
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
2207
help='A variant of 1.6 that supports rich-root data '
2208
'(needed for bzr-svn and bzr-git).',
2209
branch_format='bzrlib.branch.BzrBranchFormat7',
2210
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2214
register_metadir(controldir.format_registry, '1.9',
2215
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2216
help='A repository format using B+tree indexes. These indexes '
2217
'are smaller in size, have smarter caching and provide faster '
2218
'performance for most operations.',
2219
branch_format='bzrlib.branch.BzrBranchFormat7',
2220
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2224
register_metadir(controldir.format_registry, '1.9-rich-root',
2225
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2226
help='A variant of 1.9 that supports rich-root data '
2227
'(needed for bzr-svn and bzr-git).',
2228
branch_format='bzrlib.branch.BzrBranchFormat7',
2229
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2233
register_metadir(controldir.format_registry, '1.14',
2234
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2235
help='A working-tree format that supports content filtering.',
2236
branch_format='bzrlib.branch.BzrBranchFormat7',
2237
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2241
register_metadir(controldir.format_registry, '1.14-rich-root',
2242
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2243
help='A variant of 1.14 that supports rich-root data '
2244
'(needed for bzr-svn and bzr-git).',
2245
branch_format='bzrlib.branch.BzrBranchFormat7',
2246
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2250
# The following un-numbered 'development' formats should always just be aliases.
2251
register_metadir(controldir.format_registry, 'development-subtree',
2252
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2aSubtree',
2253
help='Current development format, subtree variant. Can convert data to and '
2254
'from pack-0.92-subtree (and anything compatible with '
2255
'pack-0.92-subtree) format repositories. Repositories and branches in '
2256
'this format can only be read by bzr.dev. Please read '
2257
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2259
branch_format='bzrlib.branch.BzrBranchFormat7',
2260
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2263
alias=False, # Restore to being an alias when an actual development subtree format is added
2264
# This current non-alias status is simply because we did not introduce a
2265
# chk based subtree format.
2267
register_metadir(controldir.format_registry, 'development5-subtree',
2268
'bzrlib.repofmt.knitpack_repo.RepositoryFormatPackDevelopment2Subtree',
2269
help='Development format, subtree variant. Can convert data to and '
2270
'from pack-0.92-subtree (and anything compatible with '
2271
'pack-0.92-subtree) format repositories. Repositories and branches in '
2272
'this format can only be read by bzr.dev. Please read '
2273
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2275
branch_format='bzrlib.branch.BzrBranchFormat7',
2276
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2282
register_metadir(controldir.format_registry, 'development-colo',
2283
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2284
help='The 2a format with experimental support for colocated branches.\n',
2285
branch_format='bzrlib.branch.BzrBranchFormat7',
2286
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2288
bzrdir_format=BzrDirMetaFormat1Colo,
2292
# And the development formats above will have aliased one of the following:
2294
# Finally, the current format.
2295
register_metadir(controldir.format_registry, '2a',
2296
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2297
help='Format for the bzr 2.0 series.\n'
2298
'Uses group-compress storage.\n'
2299
'Provides rich roots which are a one-way transition.\n',
2300
# 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
2301
# 'rich roots. Supported by bzr 1.16 and later.',
2302
branch_format='bzrlib.branch.BzrBranchFormat7',
2303
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2307
# The following format should be an alias for the rich root equivalent
2308
# of the default format
2309
register_metadir(controldir.format_registry, 'default-rich-root',
2310
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2311
branch_format='bzrlib.branch.BzrBranchFormat7',
2312
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2317
# The current format that is made on 'bzr init'.
2318
format_name = config.GlobalStack().get('default_format')
2319
controldir.format_registry.set_default(format_name)
2321
# XXX 2010-08-20 JRV: There is still a lot of code relying on
2322
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc
2323
# get changed to ControlDir.create/ControlDir.open/etc this should be removed.
2324
format_registry = controldir.format_registry