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 ControlDir.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 ControlDir.destroy_branch."""
875
name = self._get_selected_branch()
876
path = self._get_branch_path(name)
878
self.control_files.lock_write()
880
branches = self._read_branch_list()
882
branches.remove(name.encode("utf-8"))
884
raise errors.NotBranchError(name)
885
self._write_branch_list(branches)
887
self.control_files.unlock()
889
self.transport.delete_tree(path)
890
except errors.NoSuchFile:
891
raise errors.NotBranchError(path=urlutils.join(self.transport.base,
894
def create_repository(self, shared=False):
895
"""See BzrDir.create_repository."""
896
return self._format.repository_format.initialize(self, shared)
898
def destroy_repository(self):
899
"""See BzrDir.destroy_repository."""
901
self.transport.delete_tree('repository')
902
except errors.NoSuchFile:
903
raise errors.NoRepositoryPresent(self)
905
def create_workingtree(self, revision_id=None, from_branch=None,
906
accelerator_tree=None, hardlink=False):
907
"""See BzrDir.create_workingtree."""
908
return self._format.workingtree_format.initialize(
909
self, revision_id, from_branch=from_branch,
910
accelerator_tree=accelerator_tree, hardlink=hardlink)
912
def destroy_workingtree(self):
913
"""See BzrDir.destroy_workingtree."""
914
wt = self.open_workingtree(recommend_upgrade=False)
915
repository = wt.branch.repository
916
empty = repository.revision_tree(_mod_revision.NULL_REVISION)
917
# We ignore the conflicts returned by wt.revert since we're about to
918
# delete the wt metadata anyway, all that should be left here are
919
# detritus. But see bug #634470 about subtree .bzr dirs.
920
conflicts = wt.revert(old_tree=empty)
921
self.destroy_workingtree_metadata()
923
def destroy_workingtree_metadata(self):
924
self.transport.delete_tree('checkout')
926
def find_branch_format(self, name=None):
927
"""Find the branch 'format' for this bzrdir.
929
This might be a synthetic object for e.g. RemoteBranch and SVN.
931
from bzrlib.branch import BranchFormatMetadir
932
return BranchFormatMetadir.find_format(self, name=name)
934
def _get_mkdir_mode(self):
935
"""Figure out the mode to use when creating a bzrdir subdir."""
936
temp_control = lockable_files.LockableFiles(self.transport, '',
937
lockable_files.TransportLock)
938
return temp_control._dir_mode
940
def get_branch_reference(self, name=None):
941
"""See BzrDir.get_branch_reference()."""
942
from bzrlib.branch import BranchFormatMetadir
943
format = BranchFormatMetadir.find_format(self, name=name)
944
return format.get_reference(self, name=name)
946
def set_branch_reference(self, target_branch, name=None):
947
format = _mod_branch.BranchReferenceFormat()
948
return format.initialize(self, target_branch=target_branch, name=name)
950
def get_branch_transport(self, branch_format, name=None):
951
"""See BzrDir.get_branch_transport()."""
953
name = self._get_selected_branch()
954
path = self._get_branch_path(name)
955
# XXX: this shouldn't implicitly create the directory if it's just
956
# promising to get a transport -- mbp 20090727
957
if branch_format is None:
958
return self.transport.clone(path)
960
branch_format.get_format_string()
961
except NotImplementedError:
962
raise errors.IncompatibleFormat(branch_format, self._format)
964
branches = self._read_branch_list()
965
utf8_name = name.encode("utf-8")
966
if not utf8_name in branches:
967
self.control_files.lock_write()
969
branches = self._read_branch_list()
970
dirname = urlutils.dirname(utf8_name)
971
if dirname != "" and dirname in branches:
972
raise errors.ParentBranchExists(name)
974
b.startswith(utf8_name+"/") for b in branches]
975
if any(child_branches):
976
raise errors.AlreadyBranchError(name)
977
branches.append(utf8_name)
978
self._write_branch_list(branches)
980
self.control_files.unlock()
981
branch_transport = self.transport.clone(path)
982
mode = self._get_mkdir_mode()
983
branch_transport.create_prefix(mode=mode)
985
self.transport.mkdir(path, mode=mode)
986
except errors.FileExists:
988
return self.transport.clone(path)
990
def get_repository_transport(self, repository_format):
991
"""See BzrDir.get_repository_transport()."""
992
if repository_format is None:
993
return self.transport.clone('repository')
995
repository_format.get_format_string()
996
except NotImplementedError:
997
raise errors.IncompatibleFormat(repository_format, self._format)
999
self.transport.mkdir('repository', mode=self._get_mkdir_mode())
1000
except errors.FileExists:
1002
return self.transport.clone('repository')
1004
def get_workingtree_transport(self, workingtree_format):
1005
"""See BzrDir.get_workingtree_transport()."""
1006
if workingtree_format is None:
1007
return self.transport.clone('checkout')
1009
workingtree_format.get_format_string()
1010
except NotImplementedError:
1011
raise errors.IncompatibleFormat(workingtree_format, self._format)
1013
self.transport.mkdir('checkout', mode=self._get_mkdir_mode())
1014
except errors.FileExists:
1016
return self.transport.clone('checkout')
1018
def get_branches(self):
1019
"""See ControlDir.get_branches."""
1022
ret[""] = self.open_branch(name="")
1023
except (errors.NotBranchError, errors.NoRepositoryPresent):
1026
for name in self._read_branch_list():
1027
ret[name] = self.open_branch(name=name.decode('utf-8'))
1031
def has_workingtree(self):
1032
"""Tell if this bzrdir contains a working tree.
1034
Note: if you're going to open the working tree, you should just go
1035
ahead and try, and not ask permission first.
1037
from bzrlib.workingtree import WorkingTreeFormatMetaDir
1039
WorkingTreeFormatMetaDir.find_format_string(self)
1040
except errors.NoWorkingTree:
1044
def needs_format_conversion(self, format):
1045
"""See BzrDir.needs_format_conversion()."""
1046
if (not isinstance(self._format, format.__class__) or
1047
self._format.get_format_string() != format.get_format_string()):
1048
# it is not a meta dir format, conversion is needed.
1050
# we might want to push this down to the repository?
1052
if not isinstance(self.open_repository()._format,
1053
format.repository_format.__class__):
1054
# the repository needs an upgrade.
1056
except errors.NoRepositoryPresent:
1058
for branch in self.list_branches():
1059
if not isinstance(branch._format,
1060
format.get_branch_format().__class__):
1061
# the branch needs an upgrade.
1064
my_wt = self.open_workingtree(recommend_upgrade=False)
1065
if not isinstance(my_wt._format,
1066
format.workingtree_format.__class__):
1067
# the workingtree needs an upgrade.
1069
except (errors.NoWorkingTree, errors.NotLocalUrl):
1073
def open_branch(self, name=None, unsupported=False,
1074
ignore_fallbacks=False, possible_transports=None):
1075
"""See ControlDir.open_branch."""
1077
name = self._get_selected_branch()
1078
format = self.find_branch_format(name=name)
1079
format.check_support_status(unsupported)
1080
return format.open(self, name=name,
1081
_found=True, ignore_fallbacks=ignore_fallbacks,
1082
possible_transports=possible_transports)
1084
def open_repository(self, unsupported=False):
1085
"""See BzrDir.open_repository."""
1086
from bzrlib.repository import RepositoryFormatMetaDir
1087
format = RepositoryFormatMetaDir.find_format(self)
1088
format.check_support_status(unsupported)
1089
return format.open(self, _found=True)
1091
def open_workingtree(self, unsupported=False,
1092
recommend_upgrade=True):
1093
"""See BzrDir.open_workingtree."""
1094
from bzrlib.workingtree import WorkingTreeFormatMetaDir
1095
format = WorkingTreeFormatMetaDir.find_format(self)
1096
format.check_support_status(unsupported, recommend_upgrade,
1097
basedir=self.root_transport.base)
1098
return format.open(self, _found=True)
1100
def _get_config(self):
1101
return config.TransportConfig(self.transport, 'control.conf')
1104
class BzrFormat(object):
1105
"""Base class for all formats of things living in metadirs.
1107
This class manages the format string that is stored in the 'format'
1108
or 'branch-format' file.
1110
All classes for (branch-, repository-, workingtree-) formats that
1111
live in meta directories and have their own 'format' file
1112
(i.e. different from .bzr/branch-format) derive from this class,
1113
as well as the relevant base class for their kind
1114
(BranchFormat, WorkingTreeFormat, RepositoryFormat).
1116
Each format is identified by a "format" or "branch-format" file with a
1117
single line containing the base format name and then an optional list of
1120
Feature flags are supported as of bzr 2.5. Setting feature flags on formats
1121
will render them inaccessible to older versions of bzr.
1123
:ivar features: Dictionary mapping feature names to their necessity
1126
_present_features = set()
1132
def register_feature(cls, name):
1133
"""Register a feature as being present.
1135
:param name: Name of the feature
1138
raise ValueError("spaces are not allowed in feature names")
1139
if name in cls._present_features:
1140
raise errors.FeatureAlreadyRegistered(name)
1141
cls._present_features.add(name)
1144
def unregister_feature(cls, name):
1145
"""Unregister a feature."""
1146
cls._present_features.remove(name)
1148
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1150
for name, necessity in self.features.iteritems():
1151
if name in self._present_features:
1153
if necessity == "optional":
1154
mutter("ignoring optional missing feature %s", name)
1156
elif necessity == "required":
1157
raise errors.MissingFeature(name)
1159
mutter("treating unknown necessity as require for %s",
1161
raise errors.MissingFeature(name)
1164
def get_format_string(cls):
1165
"""Return the ASCII format string that identifies this format."""
1166
raise NotImplementedError(cls.get_format_string)
1169
def from_string(cls, text):
1170
format_string = cls.get_format_string()
1171
if not text.startswith(format_string):
1172
raise AssertionError("Invalid format header %r for %r" % (text, cls))
1173
lines = text[len(format_string):].splitlines()
1175
for lineno, line in enumerate(lines):
1177
(necessity, feature) = line.split(" ", 1)
1179
raise errors.ParseFormatError(format=cls, lineno=lineno+2,
1180
line=line, text=text)
1181
ret.features[feature] = necessity
1184
def as_string(self):
1185
"""Return the string representation of this format.
1187
lines = [self.get_format_string()]
1188
lines.extend([("%s %s\n" % (item[1], item[0])) for item in
1189
self.features.iteritems()])
1190
return "".join(lines)
1193
def _find_format(klass, registry, kind, format_string):
1195
first_line = format_string[:format_string.index("\n")+1]
1197
first_line = format_string
1199
cls = registry.get(first_line)
1201
raise errors.UnknownFormatError(format=first_line, kind=kind)
1202
return cls.from_string(format_string)
1204
def network_name(self):
1205
"""A simple byte string uniquely identifying this format for RPC calls.
1207
Metadir branch formats use their format string.
1209
return self.as_string()
1211
def __eq__(self, other):
1212
return (self.__class__ is other.__class__ and
1213
self.features == other.features)
1215
def _update_feature_flags(self, updated_flags):
1216
"""Update the feature flags in this format.
1218
:param updated_flags: Updated feature flags
1220
for name, necessity in updated_flags.iteritems():
1221
if necessity is None:
1223
del self.features[name]
1227
self.features[name] = necessity
1230
class BzrProber(controldir.Prober):
1231
"""Prober for formats that use a .bzr/ control directory."""
1233
formats = registry.FormatRegistry(controldir.network_format_registry)
1234
"""The known .bzr formats."""
1237
@deprecated_method(deprecated_in((2, 4, 0)))
1238
def register_bzrdir_format(klass, format):
1239
klass.formats.register(format.get_format_string(), format)
1242
@deprecated_method(deprecated_in((2, 4, 0)))
1243
def unregister_bzrdir_format(klass, format):
1244
klass.formats.remove(format.get_format_string())
1247
def probe_transport(klass, transport):
1248
"""Return the .bzrdir style format present in a directory."""
1250
format_string = transport.get_bytes(".bzr/branch-format")
1251
except errors.NoSuchFile:
1252
raise errors.NotBranchError(path=transport.base)
1254
first_line = format_string[:format_string.index("\n")+1]
1256
first_line = format_string
1258
cls = klass.formats.get(first_line)
1260
raise errors.UnknownFormatError(format=first_line, kind='bzrdir')
1261
return cls.from_string(format_string)
1264
def known_formats(cls):
1266
for name, format in cls.formats.iteritems():
1267
if callable(format):
1273
controldir.ControlDirFormat.register_prober(BzrProber)
1276
class RemoteBzrProber(controldir.Prober):
1277
"""Prober for remote servers that provide a Bazaar smart server."""
1280
def probe_transport(klass, transport):
1281
"""Return a RemoteBzrDirFormat object if it looks possible."""
1283
medium = transport.get_smart_medium()
1284
except (NotImplementedError, AttributeError,
1285
errors.TransportNotPossible, errors.NoSmartMedium,
1286
errors.SmartProtocolError):
1287
# no smart server, so not a branch for this format type.
1288
raise errors.NotBranchError(path=transport.base)
1290
# Decline to open it if the server doesn't support our required
1291
# version (3) so that the VFS-based transport will do it.
1292
if medium.should_probe():
1294
server_version = medium.protocol_version()
1295
except errors.SmartProtocolError:
1296
# Apparently there's no usable smart server there, even though
1297
# the medium supports the smart protocol.
1298
raise errors.NotBranchError(path=transport.base)
1299
if server_version != '2':
1300
raise errors.NotBranchError(path=transport.base)
1301
from bzrlib.remote import RemoteBzrDirFormat
1302
return RemoteBzrDirFormat()
1305
def known_formats(cls):
1306
from bzrlib.remote import RemoteBzrDirFormat
1307
return set([RemoteBzrDirFormat()])
1310
class BzrDirFormat(BzrFormat, controldir.ControlDirFormat):
1311
"""ControlDirFormat base class for .bzr/ directories.
1313
Formats are placed in a dict by their format string for reference
1314
during bzrdir opening. These should be subclasses of BzrDirFormat
1317
Once a format is deprecated, just deprecate the initialize and open
1318
methods on the format class. Do not deprecate the object, as the
1319
object will be created every system load.
1322
_lock_file_name = 'branch-lock'
1324
# _lock_class must be set in subclasses to the lock type, typ.
1325
# TransportLock or LockDir
1327
def initialize_on_transport(self, transport):
1328
"""Initialize a new bzrdir in the base directory of a Transport."""
1330
# can we hand off the request to the smart server rather than using
1332
client_medium = transport.get_smart_medium()
1333
except errors.NoSmartMedium:
1334
return self._initialize_on_transport_vfs(transport)
1336
# Current RPC's only know how to create bzr metadir1 instances, so
1337
# we still delegate to vfs methods if the requested format is not a
1339
if type(self) != BzrDirMetaFormat1:
1340
return self._initialize_on_transport_vfs(transport)
1341
from bzrlib.remote import RemoteBzrDirFormat
1342
remote_format = RemoteBzrDirFormat()
1343
self._supply_sub_formats_to(remote_format)
1344
return remote_format.initialize_on_transport(transport)
1346
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1347
create_prefix=False, force_new_repo=False, stacked_on=None,
1348
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1349
shared_repo=False, vfs_only=False):
1350
"""Create this format on transport.
1352
The directory to initialize will be created.
1354
:param force_new_repo: Do not use a shared repository for the target,
1355
even if one is available.
1356
:param create_prefix: Create any missing directories leading up to
1358
:param use_existing_dir: Use an existing directory if one exists.
1359
:param stacked_on: A url to stack any created branch on, None to follow
1360
any target stacking policy.
1361
:param stack_on_pwd: If stack_on is relative, the location it is
1363
:param repo_format_name: If non-None, a repository will be
1364
made-or-found. Should none be found, or if force_new_repo is True
1365
the repo_format_name is used to select the format of repository to
1367
:param make_working_trees: Control the setting of make_working_trees
1368
for a new shared repository when one is made. None to use whatever
1369
default the format has.
1370
:param shared_repo: Control whether made repositories are shared or
1372
:param vfs_only: If True do not attempt to use a smart server
1373
:return: repo, bzrdir, require_stacking, repository_policy. repo is
1374
None if none was created or found, bzrdir is always valid.
1375
require_stacking is the result of examining the stacked_on
1376
parameter and any stacking policy found for the target.
1379
# Try to hand off to a smart server
1381
client_medium = transport.get_smart_medium()
1382
except errors.NoSmartMedium:
1385
from bzrlib.remote import RemoteBzrDirFormat
1386
# TODO: lookup the local format from a server hint.
1387
remote_dir_format = RemoteBzrDirFormat()
1388
remote_dir_format._network_name = self.network_name()
1389
self._supply_sub_formats_to(remote_dir_format)
1390
return remote_dir_format.initialize_on_transport_ex(transport,
1391
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1392
force_new_repo=force_new_repo, stacked_on=stacked_on,
1393
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1394
make_working_trees=make_working_trees, shared_repo=shared_repo)
1395
# XXX: Refactor the create_prefix/no_create_prefix code into a
1396
# common helper function
1397
# The destination may not exist - if so make it according to policy.
1398
def make_directory(transport):
1399
transport.mkdir('.')
1401
def redirected(transport, e, redirection_notice):
1402
note(redirection_notice)
1403
return transport._redirected_to(e.source, e.target)
1405
transport = do_catching_redirections(make_directory, transport,
1407
except errors.FileExists:
1408
if not use_existing_dir:
1410
except errors.NoSuchFile:
1411
if not create_prefix:
1413
transport.create_prefix()
1415
require_stacking = (stacked_on is not None)
1416
# Now the target directory exists, but doesn't have a .bzr
1417
# directory. So we need to create it, along with any work to create
1418
# all of the dependent branches, etc.
1420
result = self.initialize_on_transport(transport)
1421
if repo_format_name:
1423
# use a custom format
1424
result._format.repository_format = \
1425
repository.network_format_registry.get(repo_format_name)
1426
except AttributeError:
1427
# The format didn't permit it to be set.
1429
# A repository is desired, either in-place or shared.
1430
repository_policy = result.determine_repository_policy(
1431
force_new_repo, stacked_on, stack_on_pwd,
1432
require_stacking=require_stacking)
1433
result_repo, is_new_repo = repository_policy.acquire_repository(
1434
make_working_trees, shared_repo)
1435
if not require_stacking and repository_policy._require_stacking:
1436
require_stacking = True
1437
result._format.require_stacking()
1438
result_repo.lock_write()
1441
repository_policy = None
1442
return result_repo, result, require_stacking, repository_policy
1444
def _initialize_on_transport_vfs(self, transport):
1445
"""Initialize a new bzrdir using VFS calls.
1447
:param transport: The transport to create the .bzr directory in.
1450
# Since we are creating a .bzr directory, inherit the
1451
# mode from the root directory
1452
temp_control = lockable_files.LockableFiles(transport,
1453
'', lockable_files.TransportLock)
1455
temp_control._transport.mkdir('.bzr',
1456
# FIXME: RBC 20060121 don't peek under
1458
mode=temp_control._dir_mode)
1459
except errors.FileExists:
1460
raise errors.AlreadyControlDirError(transport.base)
1461
if sys.platform == 'win32' and isinstance(transport, local.LocalTransport):
1462
win32utils.set_file_attr_hidden(transport._abspath('.bzr'))
1463
file_mode = temp_control._file_mode
1465
bzrdir_transport = transport.clone('.bzr')
1466
utf8_files = [('README',
1467
"This is a Bazaar control directory.\n"
1468
"Do not change any files in this directory.\n"
1469
"See http://bazaar.canonical.com/ for more information about Bazaar.\n"),
1470
('branch-format', self.as_string()),
1472
# NB: no need to escape relative paths that are url safe.
1473
control_files = lockable_files.LockableFiles(bzrdir_transport,
1474
self._lock_file_name, self._lock_class)
1475
control_files.create_lock()
1476
control_files.lock_write()
1478
for (filename, content) in utf8_files:
1479
bzrdir_transport.put_bytes(filename, content,
1482
control_files.unlock()
1483
return self.open(transport, _found=True)
1485
def open(self, transport, _found=False):
1486
"""Return an instance of this format for the dir transport points at.
1488
_found is a private parameter, do not use it.
1491
found_format = controldir.ControlDirFormat.find_format(transport)
1492
if not isinstance(found_format, self.__class__):
1493
raise AssertionError("%s was asked to open %s, but it seems to need "
1495
% (self, transport, found_format))
1496
# Allow subclasses - use the found format.
1497
self._supply_sub_formats_to(found_format)
1498
return found_format._open(transport)
1499
return self._open(transport)
1501
def _open(self, transport):
1502
"""Template method helper for opening BzrDirectories.
1504
This performs the actual open and any additional logic or parameter
1507
raise NotImplementedError(self._open)
1509
def _supply_sub_formats_to(self, other_format):
1510
"""Give other_format the same values for sub formats as this has.
1512
This method is expected to be used when parameterising a
1513
RemoteBzrDirFormat instance with the parameters from a
1514
BzrDirMetaFormat1 instance.
1516
:param other_format: other_format is a format which should be
1517
compatible with whatever sub formats are supported by self.
1520
other_format.features = dict(self.features)
1522
def supports_transport(self, transport):
1523
# bzr formats can be opened over all known transports
1526
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1528
controldir.ControlDirFormat.check_support_status(self,
1529
allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
1531
BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
1532
recommend_upgrade=recommend_upgrade, basedir=basedir)
1535
class BzrDirMetaFormat1(BzrDirFormat):
1536
"""Bzr meta control format 1
1538
This is the first format with split out working tree, branch and repository
1543
- Format 3 working trees [optional]
1544
- Format 5 branches [optional]
1545
- Format 7 repositories [optional]
1548
_lock_class = lockdir.LockDir
1550
fixed_components = False
1552
colocated_branches = True
1555
BzrDirFormat.__init__(self)
1556
self._workingtree_format = None
1557
self._branch_format = None
1558
self._repository_format = None
1560
def __eq__(self, other):
1561
if other.__class__ is not self.__class__:
1563
if other.repository_format != self.repository_format:
1565
if other.workingtree_format != self.workingtree_format:
1567
if other.features != self.features:
1571
def __ne__(self, other):
1572
return not self == other
1574
def get_branch_format(self):
1575
if self._branch_format is None:
1576
from bzrlib.branch import format_registry as branch_format_registry
1577
self._branch_format = branch_format_registry.get_default()
1578
return self._branch_format
1580
def set_branch_format(self, format):
1581
self._branch_format = format
1583
def require_stacking(self, stack_on=None, possible_transports=None,
1585
"""We have a request to stack, try to ensure the formats support it.
1587
:param stack_on: If supplied, it is the URL to a branch that we want to
1588
stack on. Check to see if that format supports stacking before
1591
# Stacking is desired. requested by the target, but does the place it
1592
# points at support stacking? If it doesn't then we should
1593
# not implicitly upgrade. We check this here.
1594
new_repo_format = None
1595
new_branch_format = None
1597
# a bit of state for get_target_branch so that we don't try to open it
1598
# 2 times, for both repo *and* branch
1599
target = [None, False, None] # target_branch, checked, upgrade anyway
1600
def get_target_branch():
1602
# We've checked, don't check again
1604
if stack_on is None:
1605
# No target format, that means we want to force upgrading
1606
target[:] = [None, True, True]
1609
target_dir = BzrDir.open(stack_on,
1610
possible_transports=possible_transports)
1611
except errors.NotBranchError:
1612
# Nothing there, don't change formats
1613
target[:] = [None, True, False]
1615
except errors.JailBreak:
1616
# JailBreak, JFDI and upgrade anyway
1617
target[:] = [None, True, True]
1620
target_branch = target_dir.open_branch()
1621
except errors.NotBranchError:
1622
# No branch, don't upgrade formats
1623
target[:] = [None, True, False]
1625
target[:] = [target_branch, True, False]
1628
if (not _skip_repo and
1629
not self.repository_format.supports_external_lookups):
1630
# We need to upgrade the Repository.
1631
target_branch, _, do_upgrade = get_target_branch()
1632
if target_branch is None:
1633
# We don't have a target branch, should we upgrade anyway?
1635
# stack_on is inaccessible, JFDI.
1636
# TODO: bad monkey, hard-coded formats...
1637
if self.repository_format.rich_root_data:
1638
new_repo_format = knitpack_repo.RepositoryFormatKnitPack5RichRoot()
1640
new_repo_format = knitpack_repo.RepositoryFormatKnitPack5()
1642
# If the target already supports stacking, then we know the
1643
# project is already able to use stacking, so auto-upgrade
1645
new_repo_format = target_branch.repository._format
1646
if not new_repo_format.supports_external_lookups:
1647
# target doesn't, source doesn't, so don't auto upgrade
1649
new_repo_format = None
1650
if new_repo_format is not None:
1651
self.repository_format = new_repo_format
1652
note(gettext('Source repository format does not support stacking,'
1653
' using format:\n %s'),
1654
new_repo_format.get_format_description())
1656
if not self.get_branch_format().supports_stacking():
1657
# We just checked the repo, now lets check if we need to
1658
# upgrade the branch format
1659
target_branch, _, do_upgrade = get_target_branch()
1660
if target_branch is None:
1662
# TODO: bad monkey, hard-coded formats...
1663
from bzrlib.branch import BzrBranchFormat7
1664
new_branch_format = BzrBranchFormat7()
1666
new_branch_format = target_branch._format
1667
if not new_branch_format.supports_stacking():
1668
new_branch_format = None
1669
if new_branch_format is not None:
1670
# Does support stacking, use its format.
1671
self.set_branch_format(new_branch_format)
1672
note(gettext('Source branch format does not support stacking,'
1673
' using format:\n %s'),
1674
new_branch_format.get_format_description())
1676
def get_converter(self, format=None):
1677
"""See BzrDirFormat.get_converter()."""
1679
format = BzrDirFormat.get_default_format()
1680
if (type(self) is BzrDirMetaFormat1 and
1681
type(format) is BzrDirMetaFormat1Colo):
1682
return ConvertMetaToColo(format)
1683
if (type(self) is BzrDirMetaFormat1Colo and
1684
type(format) is BzrDirMetaFormat1):
1685
return ConvertMetaToColo(format)
1686
if not isinstance(self, format.__class__):
1687
# converting away from metadir is not implemented
1688
raise NotImplementedError(self.get_converter)
1689
return ConvertMetaToMeta(format)
1692
def get_format_string(cls):
1693
"""See BzrDirFormat.get_format_string()."""
1694
return "Bazaar-NG meta directory, format 1\n"
1696
def get_format_description(self):
1697
"""See BzrDirFormat.get_format_description()."""
1698
return "Meta directory format 1"
1700
def _open(self, transport):
1701
"""See BzrDirFormat._open."""
1702
# Create a new format instance because otherwise initialisation of new
1703
# metadirs share the global default format object leading to alias
1705
format = BzrDirMetaFormat1()
1706
self._supply_sub_formats_to(format)
1707
return BzrDirMeta1(transport, format)
1709
def __return_repository_format(self):
1710
"""Circular import protection."""
1711
if self._repository_format:
1712
return self._repository_format
1713
from bzrlib.repository import format_registry
1714
return format_registry.get_default()
1716
def _set_repository_format(self, value):
1717
"""Allow changing the repository format for metadir formats."""
1718
self._repository_format = value
1720
repository_format = property(__return_repository_format,
1721
_set_repository_format)
1723
def _supply_sub_formats_to(self, other_format):
1724
"""Give other_format the same values for sub formats as this has.
1726
This method is expected to be used when parameterising a
1727
RemoteBzrDirFormat instance with the parameters from a
1728
BzrDirMetaFormat1 instance.
1730
:param other_format: other_format is a format which should be
1731
compatible with whatever sub formats are supported by self.
1734
super(BzrDirMetaFormat1, self)._supply_sub_formats_to(other_format)
1735
if getattr(self, '_repository_format', None) is not None:
1736
other_format.repository_format = self.repository_format
1737
if self._branch_format is not None:
1738
other_format._branch_format = self._branch_format
1739
if self._workingtree_format is not None:
1740
other_format.workingtree_format = self.workingtree_format
1742
def __get_workingtree_format(self):
1743
if self._workingtree_format is None:
1744
from bzrlib.workingtree import (
1745
format_registry as wt_format_registry,
1747
self._workingtree_format = wt_format_registry.get_default()
1748
return self._workingtree_format
1750
def __set_workingtree_format(self, wt_format):
1751
self._workingtree_format = wt_format
1754
return "<%r>" % (self.__class__.__name__,)
1756
workingtree_format = property(__get_workingtree_format,
1757
__set_workingtree_format)
1760
# Register bzr formats
1761
BzrProber.formats.register(BzrDirMetaFormat1.get_format_string(),
1763
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1766
class BzrDirMetaFormat1Colo(BzrDirMetaFormat1):
1767
"""BzrDirMeta1 format with support for colocated branches."""
1769
colocated_branches = True
1772
def get_format_string(cls):
1773
"""See BzrDirFormat.get_format_string()."""
1774
return "Bazaar meta directory, format 1 (with colocated branches)\n"
1776
def get_format_description(self):
1777
"""See BzrDirFormat.get_format_description()."""
1778
return "Meta directory format 1 with support for colocated branches"
1780
def _open(self, transport):
1781
"""See BzrDirFormat._open."""
1782
# Create a new format instance because otherwise initialisation of new
1783
# metadirs share the global default format object leading to alias
1785
format = BzrDirMetaFormat1Colo()
1786
self._supply_sub_formats_to(format)
1787
return BzrDirMeta1(transport, format)
1790
BzrProber.formats.register(BzrDirMetaFormat1Colo.get_format_string(),
1791
BzrDirMetaFormat1Colo)
1794
class ConvertMetaToMeta(controldir.Converter):
1795
"""Converts the components of metadirs."""
1797
def __init__(self, target_format):
1798
"""Create a metadir to metadir converter.
1800
:param target_format: The final metadir format that is desired.
1802
self.target_format = target_format
1804
def convert(self, to_convert, pb):
1805
"""See Converter.convert()."""
1806
self.bzrdir = to_convert
1807
self.pb = ui.ui_factory.nested_progress_bar()
1810
self.step('checking repository format')
1812
repo = self.bzrdir.open_repository()
1813
except errors.NoRepositoryPresent:
1816
if not isinstance(repo._format, self.target_format.repository_format.__class__):
1817
from bzrlib.repository import CopyConverter
1818
ui.ui_factory.note(gettext('starting repository conversion'))
1819
converter = CopyConverter(self.target_format.repository_format)
1820
converter.convert(repo, pb)
1821
for branch in self.bzrdir.list_branches():
1822
# TODO: conversions of Branch and Tree should be done by
1823
# InterXFormat lookups/some sort of registry.
1824
# Avoid circular imports
1825
old = branch._format.__class__
1826
new = self.target_format.get_branch_format().__class__
1828
if (old == _mod_branch.BzrBranchFormat5 and
1829
new in (_mod_branch.BzrBranchFormat6,
1830
_mod_branch.BzrBranchFormat7,
1831
_mod_branch.BzrBranchFormat8)):
1832
branch_converter = _mod_branch.Converter5to6()
1833
elif (old == _mod_branch.BzrBranchFormat6 and
1834
new in (_mod_branch.BzrBranchFormat7,
1835
_mod_branch.BzrBranchFormat8)):
1836
branch_converter = _mod_branch.Converter6to7()
1837
elif (old == _mod_branch.BzrBranchFormat7 and
1838
new is _mod_branch.BzrBranchFormat8):
1839
branch_converter = _mod_branch.Converter7to8()
1841
raise errors.BadConversionTarget("No converter", new,
1843
branch_converter.convert(branch)
1844
branch = self.bzrdir.open_branch()
1845
old = branch._format.__class__
1847
tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
1848
except (errors.NoWorkingTree, errors.NotLocalUrl):
1851
# TODO: conversions of Branch and Tree should be done by
1852
# InterXFormat lookups
1853
if (isinstance(tree, workingtree_3.WorkingTree3) and
1854
not isinstance(tree, workingtree_4.DirStateWorkingTree) and
1855
isinstance(self.target_format.workingtree_format,
1856
workingtree_4.DirStateWorkingTreeFormat)):
1857
workingtree_4.Converter3to4().convert(tree)
1858
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1859
not isinstance(tree, workingtree_4.WorkingTree5) and
1860
isinstance(self.target_format.workingtree_format,
1861
workingtree_4.WorkingTreeFormat5)):
1862
workingtree_4.Converter4to5().convert(tree)
1863
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1864
not isinstance(tree, workingtree_4.WorkingTree6) and
1865
isinstance(self.target_format.workingtree_format,
1866
workingtree_4.WorkingTreeFormat6)):
1867
workingtree_4.Converter4or5to6().convert(tree)
1872
class ConvertMetaToColo(controldir.Converter):
1873
"""Add colocated branch support."""
1875
def __init__(self, target_format):
1876
"""Create a converter.that upgrades a metadir to the colo format.
1878
:param target_format: The final metadir format that is desired.
1880
self.target_format = target_format
1882
def convert(self, to_convert, pb):
1883
"""See Converter.convert()."""
1884
to_convert.transport.put_bytes('branch-format',
1885
self.target_format.as_string())
1886
return BzrDir.open_from_transport(to_convert.root_transport)
1889
class ConvertMetaToColo(controldir.Converter):
1890
"""Convert a 'development-colo' bzrdir to a '2a' bzrdir."""
1892
def __init__(self, target_format):
1893
"""Create a converter that converts a 'development-colo' metadir
1896
:param target_format: The final metadir format that is desired.
1898
self.target_format = target_format
1900
def convert(self, to_convert, pb):
1901
"""See Converter.convert()."""
1902
to_convert.transport.put_bytes('branch-format',
1903
self.target_format.as_string())
1904
return BzrDir.open_from_transport(to_convert.root_transport)
1907
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
1910
class RepositoryAcquisitionPolicy(object):
1911
"""Abstract base class for repository acquisition policies.
1913
A repository acquisition policy decides how a BzrDir acquires a repository
1914
for a branch that is being created. The most basic policy decision is
1915
whether to create a new repository or use an existing one.
1917
def __init__(self, stack_on, stack_on_pwd, require_stacking):
1920
:param stack_on: A location to stack on
1921
:param stack_on_pwd: If stack_on is relative, the location it is
1923
:param require_stacking: If True, it is a failure to not stack.
1925
self._stack_on = stack_on
1926
self._stack_on_pwd = stack_on_pwd
1927
self._require_stacking = require_stacking
1929
def configure_branch(self, branch):
1930
"""Apply any configuration data from this policy to the branch.
1932
Default implementation sets repository stacking.
1934
if self._stack_on is None:
1936
if self._stack_on_pwd is None:
1937
stack_on = self._stack_on
1940
stack_on = urlutils.rebase_url(self._stack_on,
1943
except errors.InvalidRebaseURLs:
1944
stack_on = self._get_full_stack_on()
1946
branch.set_stacked_on_url(stack_on)
1947
except (errors.UnstackableBranchFormat,
1948
errors.UnstackableRepositoryFormat):
1949
if self._require_stacking:
1952
def requires_stacking(self):
1953
"""Return True if this policy requires stacking."""
1954
return self._stack_on is not None and self._require_stacking
1956
def _get_full_stack_on(self):
1957
"""Get a fully-qualified URL for the stack_on location."""
1958
if self._stack_on is None:
1960
if self._stack_on_pwd is None:
1961
return self._stack_on
1963
return urlutils.join(self._stack_on_pwd, self._stack_on)
1965
def _add_fallback(self, repository, possible_transports=None):
1966
"""Add a fallback to the supplied repository, if stacking is set."""
1967
stack_on = self._get_full_stack_on()
1968
if stack_on is None:
1971
stacked_dir = BzrDir.open(stack_on,
1972
possible_transports=possible_transports)
1973
except errors.JailBreak:
1974
# We keep the stacking details, but we are in the server code so
1975
# actually stacking is not needed.
1978
stacked_repo = stacked_dir.open_branch().repository
1979
except errors.NotBranchError:
1980
stacked_repo = stacked_dir.open_repository()
1982
repository.add_fallback_repository(stacked_repo)
1983
except errors.UnstackableRepositoryFormat:
1984
if self._require_stacking:
1987
self._require_stacking = True
1989
def acquire_repository(self, make_working_trees=None, shared=False,
1990
possible_transports=None):
1991
"""Acquire a repository for this bzrdir.
1993
Implementations may create a new repository or use a pre-exising
1996
:param make_working_trees: If creating a repository, set
1997
make_working_trees to this value (if non-None)
1998
:param shared: If creating a repository, make it shared if True
1999
:return: A repository, is_new_flag (True if the repository was
2002
raise NotImplementedError(RepositoryAcquisitionPolicy.acquire_repository)
2005
class CreateRepository(RepositoryAcquisitionPolicy):
2006
"""A policy of creating a new repository"""
2008
def __init__(self, bzrdir, stack_on=None, stack_on_pwd=None,
2009
require_stacking=False):
2012
:param bzrdir: The bzrdir to create the repository on.
2013
:param stack_on: A location to stack on
2014
:param stack_on_pwd: If stack_on is relative, the location it is
2017
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2019
self._bzrdir = bzrdir
2021
def acquire_repository(self, make_working_trees=None, shared=False,
2022
possible_transports=None):
2023
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2025
Creates the desired repository in the bzrdir we already have.
2027
if possible_transports is None:
2028
possible_transports = []
2030
possible_transports = list(possible_transports)
2031
possible_transports.append(self._bzrdir.root_transport)
2032
stack_on = self._get_full_stack_on()
2034
format = self._bzrdir._format
2035
format.require_stacking(stack_on=stack_on,
2036
possible_transports=possible_transports)
2037
if not self._require_stacking:
2038
# We have picked up automatic stacking somewhere.
2039
note(gettext('Using default stacking branch {0} at {1}').format(
2040
self._stack_on, self._stack_on_pwd))
2041
repository = self._bzrdir.create_repository(shared=shared)
2042
self._add_fallback(repository,
2043
possible_transports=possible_transports)
2044
if make_working_trees is not None:
2045
repository.set_make_working_trees(make_working_trees)
2046
return repository, True
2049
class UseExistingRepository(RepositoryAcquisitionPolicy):
2050
"""A policy of reusing an existing repository"""
2052
def __init__(self, repository, stack_on=None, stack_on_pwd=None,
2053
require_stacking=False):
2056
:param repository: The repository to use.
2057
:param stack_on: A location to stack on
2058
:param stack_on_pwd: If stack_on is relative, the location it is
2061
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2063
self._repository = repository
2065
def acquire_repository(self, make_working_trees=None, shared=False,
2066
possible_transports=None):
2067
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2069
Returns an existing repository to use.
2071
if possible_transports is None:
2072
possible_transports = []
2074
possible_transports = list(possible_transports)
2075
possible_transports.append(self._repository.bzrdir.transport)
2076
self._add_fallback(self._repository,
2077
possible_transports=possible_transports)
2078
return self._repository, False
2081
def register_metadir(registry, key,
2082
repository_format, help, native=True, deprecated=False,
2087
alias=False, bzrdir_format=None):
2088
"""Register a metadir subformat.
2090
These all use a meta bzrdir, but can be parameterized by the
2091
Repository/Branch/WorkingTreeformats.
2093
:param repository_format: The fully-qualified repository format class
2095
:param branch_format: Fully-qualified branch format class name as
2097
:param tree_format: Fully-qualified tree format class name as
2100
if bzrdir_format is None:
2101
bzrdir_format = BzrDirMetaFormat1
2102
# This should be expanded to support setting WorkingTree and Branch
2103
# formats, once the API supports that.
2104
def _load(full_name):
2105
mod_name, factory_name = full_name.rsplit('.', 1)
2107
factory = pyutils.get_named_object(mod_name, factory_name)
2108
except ImportError, e:
2109
raise ImportError('failed to load %s: %s' % (full_name, e))
2110
except AttributeError:
2111
raise AttributeError('no factory %s in module %r'
2112
% (full_name, sys.modules[mod_name]))
2116
bd = bzrdir_format()
2117
if branch_format is not None:
2118
bd.set_branch_format(_load(branch_format))
2119
if tree_format is not None:
2120
bd.workingtree_format = _load(tree_format)
2121
if repository_format is not None:
2122
bd.repository_format = _load(repository_format)
2124
registry.register(key, helper, help, native, deprecated, hidden,
2125
experimental, alias)
2127
register_metadir(controldir.format_registry, 'knit',
2128
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2129
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
2130
branch_format='bzrlib.branch.BzrBranchFormat5',
2131
tree_format='bzrlib.workingtree_3.WorkingTreeFormat3',
2134
register_metadir(controldir.format_registry, 'dirstate',
2135
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2136
help='Format using dirstate for working trees. '
2137
'Compatible with bzr 0.8 and '
2138
'above when accessed over the network. Introduced in bzr 0.15.',
2139
branch_format='bzrlib.branch.BzrBranchFormat5',
2140
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2143
register_metadir(controldir.format_registry, 'dirstate-tags',
2144
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2145
help='Variant of dirstate with support for tags. '
2146
'Introduced in bzr 0.15.',
2147
branch_format='bzrlib.branch.BzrBranchFormat6',
2148
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2151
register_metadir(controldir.format_registry, 'rich-root',
2152
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
2153
help='Variant of dirstate with better handling of tree roots. '
2154
'Introduced in bzr 1.0',
2155
branch_format='bzrlib.branch.BzrBranchFormat6',
2156
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2159
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
2160
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2161
help='Variant of dirstate with support for nested trees. '
2162
'Introduced in 0.15.',
2163
branch_format='bzrlib.branch.BzrBranchFormat6',
2164
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2168
register_metadir(controldir.format_registry, 'pack-0.92',
2169
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
2170
help='Pack-based format used in 1.x series. Introduced in 0.92. '
2171
'Interoperates with bzr repositories before 0.92 but cannot be '
2172
'read by bzr < 0.92. '
2174
branch_format='bzrlib.branch.BzrBranchFormat6',
2175
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2178
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2179
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
2180
help='Pack-based format used in 1.x series, with subtree support. '
2181
'Introduced in 0.92. Interoperates with '
2182
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2184
branch_format='bzrlib.branch.BzrBranchFormat6',
2185
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2190
register_metadir(controldir.format_registry, 'rich-root-pack',
2191
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
2192
help='A variant of pack-0.92 that supports rich-root data '
2193
'(needed for bzr-svn and bzr-git). Introduced in 1.0.',
2194
branch_format='bzrlib.branch.BzrBranchFormat6',
2195
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2199
register_metadir(controldir.format_registry, '1.6',
2200
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
2201
help='A format that allows a branch to indicate that there is another '
2202
'(stacked) repository that should be used to access data that is '
2203
'not present locally.',
2204
branch_format='bzrlib.branch.BzrBranchFormat7',
2205
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2209
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2210
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
2211
help='A variant of 1.6 that supports rich-root data '
2212
'(needed for bzr-svn and bzr-git).',
2213
branch_format='bzrlib.branch.BzrBranchFormat7',
2214
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2218
register_metadir(controldir.format_registry, '1.9',
2219
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2220
help='A repository format using B+tree indexes. These indexes '
2221
'are smaller in size, have smarter caching and provide faster '
2222
'performance for most operations.',
2223
branch_format='bzrlib.branch.BzrBranchFormat7',
2224
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2228
register_metadir(controldir.format_registry, '1.9-rich-root',
2229
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2230
help='A variant of 1.9 that supports rich-root data '
2231
'(needed for bzr-svn and bzr-git).',
2232
branch_format='bzrlib.branch.BzrBranchFormat7',
2233
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2237
register_metadir(controldir.format_registry, '1.14',
2238
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2239
help='A working-tree format that supports content filtering.',
2240
branch_format='bzrlib.branch.BzrBranchFormat7',
2241
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2245
register_metadir(controldir.format_registry, '1.14-rich-root',
2246
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2247
help='A variant of 1.14 that supports rich-root data '
2248
'(needed for bzr-svn and bzr-git).',
2249
branch_format='bzrlib.branch.BzrBranchFormat7',
2250
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2254
# The following un-numbered 'development' formats should always just be aliases.
2255
register_metadir(controldir.format_registry, 'development-subtree',
2256
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2aSubtree',
2257
help='Current development format, subtree variant. Can convert data to and '
2258
'from pack-0.92-subtree (and anything compatible with '
2259
'pack-0.92-subtree) format repositories. Repositories and branches in '
2260
'this format can only be read by bzr.dev. Please read '
2261
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2263
branch_format='bzrlib.branch.BzrBranchFormat7',
2264
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2267
alias=False, # Restore to being an alias when an actual development subtree format is added
2268
# This current non-alias status is simply because we did not introduce a
2269
# chk based subtree format.
2271
register_metadir(controldir.format_registry, 'development5-subtree',
2272
'bzrlib.repofmt.knitpack_repo.RepositoryFormatPackDevelopment2Subtree',
2273
help='Development format, subtree variant. Can convert data to and '
2274
'from pack-0.92-subtree (and anything compatible with '
2275
'pack-0.92-subtree) format repositories. Repositories and branches in '
2276
'this format can only be read by bzr.dev. Please read '
2277
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2279
branch_format='bzrlib.branch.BzrBranchFormat7',
2280
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2286
register_metadir(controldir.format_registry, 'development-colo',
2287
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2288
help='The 2a format with experimental support for colocated branches.\n',
2289
branch_format='bzrlib.branch.BzrBranchFormat7',
2290
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2292
bzrdir_format=BzrDirMetaFormat1Colo,
2296
# And the development formats above will have aliased one of the following:
2298
# Finally, the current format.
2299
register_metadir(controldir.format_registry, '2a',
2300
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2301
help='Format for the bzr 2.0 series.\n'
2302
'Uses group-compress storage.\n'
2303
'Provides rich roots which are a one-way transition.\n',
2304
# 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
2305
# 'rich roots. Supported by bzr 1.16 and later.',
2306
branch_format='bzrlib.branch.BzrBranchFormat7',
2307
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2311
# The following format should be an alias for the rich root equivalent
2312
# of the default format
2313
register_metadir(controldir.format_registry, 'default-rich-root',
2314
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2315
branch_format='bzrlib.branch.BzrBranchFormat7',
2316
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2321
# The current format that is made on 'bzr init'.
2322
format_name = config.GlobalStack().get('default_format')
2323
controldir.format_registry.set_default(format_name)
2325
# XXX 2010-08-20 JRV: There is still a lot of code relying on
2326
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc
2327
# get changed to ControlDir.create/ControlDir.open/etc this should be removed.
2328
format_registry = controldir.format_registry