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.
359
operation = cleanup.OperationWithCleanups(self._sprout)
360
return operation.run(url, revision_id=revision_id,
361
force_new_repo=force_new_repo, recurse=recurse,
362
possible_transports=possible_transports,
363
accelerator_tree=accelerator_tree, hardlink=hardlink,
364
stacked=stacked, source_branch=source_branch,
365
create_tree_if_local=create_tree_if_local)
367
def _sprout(self, op, url, revision_id=None, force_new_repo=False,
368
recurse='down', possible_transports=None,
369
accelerator_tree=None, hardlink=False, stacked=False,
370
source_branch=None, create_tree_if_local=True):
371
add_cleanup = op.add_cleanup
372
fetch_spec_factory = fetch.FetchSpecFactory()
373
if revision_id is not None:
374
fetch_spec_factory.add_revision_ids([revision_id])
375
fetch_spec_factory.source_branch_stop_revision_id = revision_id
376
if possible_transports is None:
377
possible_transports = []
379
possible_transports = list(possible_transports) + [
381
target_transport = _mod_transport.get_transport(url,
383
target_transport.ensure_base()
384
cloning_format = self.cloning_metadir(stacked)
385
# Create/update the result branch
387
result = controldir.ControlDir.open_from_transport(target_transport)
388
except errors.NotBranchError:
389
result = cloning_format.initialize_on_transport(target_transport)
390
source_branch, source_repository = self._find_source_repo(
391
add_cleanup, source_branch)
392
fetch_spec_factory.source_branch = source_branch
393
# if a stacked branch wasn't requested, we don't create one
394
# even if the origin was stacked
395
if stacked and source_branch is not None:
396
stacked_branch_url = self.root_transport.base
398
stacked_branch_url = None
399
repository_policy = result.determine_repository_policy(
400
force_new_repo, stacked_branch_url, require_stacking=stacked)
401
result_repo, is_new_repo = repository_policy.acquire_repository(
402
possible_transports=possible_transports)
403
add_cleanup(result_repo.lock_write().unlock)
404
fetch_spec_factory.source_repo = source_repository
405
fetch_spec_factory.target_repo = result_repo
406
if stacked or (len(result_repo._fallback_repositories) != 0):
407
target_repo_kind = fetch.TargetRepoKinds.STACKED
409
target_repo_kind = fetch.TargetRepoKinds.EMPTY
411
target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
412
fetch_spec_factory.target_repo_kind = target_repo_kind
413
if source_repository is not None:
414
fetch_spec = fetch_spec_factory.make_fetch_spec()
415
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
417
if source_branch is None:
418
# this is for sprouting a controldir without a branch; is that
420
# Not especially, but it's part of the contract.
421
result_branch = result.create_branch()
423
result_branch = source_branch.sprout(result,
424
revision_id=revision_id, repository_policy=repository_policy,
425
repository=result_repo)
426
mutter("created new branch %r" % (result_branch,))
428
# Create/update the result working tree
429
if (create_tree_if_local and not result.has_workingtree() and
430
isinstance(target_transport, local.LocalTransport) and
431
(result_repo is None or result_repo.make_working_trees())):
432
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
433
hardlink=hardlink, from_branch=result_branch)
436
if wt.path2id('') is None:
438
wt.set_root_id(self.open_workingtree.get_root_id())
439
except errors.NoWorkingTree:
445
if recurse == 'down':
448
basis = wt.basis_tree()
449
elif result_branch is not None:
450
basis = result_branch.basis_tree()
451
elif source_branch is not None:
452
basis = source_branch.basis_tree()
453
if basis is not None:
454
add_cleanup(basis.lock_read().unlock)
455
subtrees = basis.iter_references()
458
for path, file_id in subtrees:
459
target = urlutils.join(url, urlutils.escape(path))
460
sublocation = source_branch.reference_parent(file_id, path)
461
sublocation.bzrdir.sprout(target,
462
basis.get_reference_revision(file_id, path),
463
force_new_repo=force_new_repo, recurse=recurse,
467
@deprecated_method(deprecated_in((2, 3, 0)))
468
def generate_backup_name(self, base):
469
return self._available_backup_name(base)
471
def _available_backup_name(self, base):
472
"""Find a non-existing backup file name based on base.
474
See bzrlib.osutils.available_backup_name about race conditions.
476
return osutils.available_backup_name(base, self.root_transport.has)
478
def backup_bzrdir(self):
479
"""Backup this bzr control directory.
481
:return: Tuple with old path name and new path name
484
pb = ui.ui_factory.nested_progress_bar()
486
old_path = self.root_transport.abspath('.bzr')
487
backup_dir = self._available_backup_name('backup.bzr')
488
new_path = self.root_transport.abspath(backup_dir)
489
ui.ui_factory.note(gettext('making backup of {0}\n to {1}').format(
490
urlutils.unescape_for_display(old_path, 'utf-8'),
491
urlutils.unescape_for_display(new_path, 'utf-8')))
492
self.root_transport.copy_tree('.bzr', backup_dir)
493
return (old_path, new_path)
497
def retire_bzrdir(self, limit=10000):
498
"""Permanently disable the bzrdir.
500
This is done by renaming it to give the user some ability to recover
501
if there was a problem.
503
This will have horrible consequences if anyone has anything locked or
505
:param limit: number of times to retry
510
to_path = '.bzr.retired.%d' % i
511
self.root_transport.rename('.bzr', to_path)
512
note(gettext("renamed {0} to {1}").format(
513
self.root_transport.abspath('.bzr'), to_path))
515
except (errors.TransportError, IOError, errors.PathError):
522
def _find_containing(self, evaluate):
523
"""Find something in a containing control directory.
525
This method will scan containing control dirs, until it finds what
526
it is looking for, decides that it will never find it, or runs out
527
of containing control directories to check.
529
It is used to implement find_repository and
530
determine_repository_policy.
532
:param evaluate: A function returning (value, stop). If stop is True,
533
the value will be returned.
537
result, stop = evaluate(found_bzrdir)
540
next_transport = found_bzrdir.root_transport.clone('..')
541
if (found_bzrdir.user_url == next_transport.base):
542
# top of the file system
544
# find the next containing bzrdir
546
found_bzrdir = self.open_containing_from_transport(
548
except errors.NotBranchError:
551
def find_repository(self):
552
"""Find the repository that should be used.
554
This does not require a branch as we use it to find the repo for
555
new branches as well as to hook existing branches up to their
558
def usable_repository(found_bzrdir):
559
# does it have a repository ?
561
repository = found_bzrdir.open_repository()
562
except errors.NoRepositoryPresent:
564
if found_bzrdir.user_url == self.user_url:
565
return repository, True
566
elif repository.is_shared():
567
return repository, True
571
found_repo = self._find_containing(usable_repository)
572
if found_repo is None:
573
raise errors.NoRepositoryPresent(self)
576
def _find_creation_modes(self):
577
"""Determine the appropriate modes for files and directories.
579
They're always set to be consistent with the base directory,
580
assuming that this transport allows setting modes.
582
# TODO: Do we need or want an option (maybe a config setting) to turn
583
# this off or override it for particular locations? -- mbp 20080512
584
if self._mode_check_done:
586
self._mode_check_done = True
588
st = self.transport.stat('.')
589
except errors.TransportNotPossible:
590
self._dir_mode = None
591
self._file_mode = None
593
# Check the directory mode, but also make sure the created
594
# directories and files are read-write for this user. This is
595
# mostly a workaround for filesystems which lie about being able to
596
# write to a directory (cygwin & win32)
597
if (st.st_mode & 07777 == 00000):
598
# FTP allows stat but does not return dir/file modes
599
self._dir_mode = None
600
self._file_mode = None
602
self._dir_mode = (st.st_mode & 07777) | 00700
603
# Remove the sticky and execute bits for files
604
self._file_mode = self._dir_mode & ~07111
606
def _get_file_mode(self):
607
"""Return Unix mode for newly created files, or None.
609
if not self._mode_check_done:
610
self._find_creation_modes()
611
return self._file_mode
613
def _get_dir_mode(self):
614
"""Return Unix mode for newly created directories, or None.
616
if not self._mode_check_done:
617
self._find_creation_modes()
618
return self._dir_mode
620
def get_config(self):
621
"""Get configuration for this BzrDir."""
622
return config.BzrDirConfig(self)
624
def _get_config(self):
625
"""By default, no configuration is available."""
628
def __init__(self, _transport, _format):
629
"""Initialize a Bzr control dir object.
631
Only really common logic should reside here, concrete classes should be
632
made with varying behaviours.
634
:param _format: the format that is creating this BzrDir instance.
635
:param _transport: the transport this dir is based at.
637
self._format = _format
638
# these are also under the more standard names of
639
# control_transport and user_transport
640
self.transport = _transport.clone('.bzr')
641
self.root_transport = _transport
642
self._mode_check_done = False
645
def user_transport(self):
646
return self.root_transport
649
def control_transport(self):
650
return self.transport
652
def is_control_filename(self, filename):
653
"""True if filename is the name of a path which is reserved for bzrdir's.
655
:param filename: A filename within the root transport of this bzrdir.
657
This is true IF and ONLY IF the filename is part of the namespace reserved
658
for bzr control dirs. Currently this is the '.bzr' directory in the root
659
of the root_transport.
661
# this might be better on the BzrDirFormat class because it refers to
662
# all the possible bzrdir disk formats.
663
# This method is tested via the workingtree is_control_filename tests-
664
# it was extracted from WorkingTree.is_control_filename. If the method's
665
# contract is extended beyond the current trivial implementation, please
666
# add new tests for it to the appropriate place.
667
return filename == '.bzr' or filename.startswith('.bzr/')
669
def _cloning_metadir(self):
670
"""Produce a metadir suitable for cloning with.
672
:returns: (destination_bzrdir_format, source_repository)
674
result_format = self._format.__class__()
677
branch = self.open_branch(ignore_fallbacks=True)
678
source_repository = branch.repository
679
result_format._branch_format = branch._format
680
except errors.NotBranchError:
682
source_repository = self.open_repository()
683
except errors.NoRepositoryPresent:
684
source_repository = None
686
# XXX TODO: This isinstance is here because we have not implemented
687
# the fix recommended in bug # 103195 - to delegate this choice the
689
repo_format = source_repository._format
690
if isinstance(repo_format, remote.RemoteRepositoryFormat):
691
source_repository._ensure_real()
692
repo_format = source_repository._real_repository._format
693
result_format.repository_format = repo_format
695
# TODO: Couldn't we just probe for the format in these cases,
696
# rather than opening the whole tree? It would be a little
697
# faster. mbp 20070401
698
tree = self.open_workingtree(recommend_upgrade=False)
699
except (errors.NoWorkingTree, errors.NotLocalUrl):
700
result_format.workingtree_format = None
702
result_format.workingtree_format = tree._format.__class__()
703
return result_format, source_repository
705
def cloning_metadir(self, require_stacking=False):
706
"""Produce a metadir suitable for cloning or sprouting with.
708
These operations may produce workingtrees (yes, even though they're
709
"cloning" something that doesn't have a tree), so a viable workingtree
710
format must be selected.
712
:require_stacking: If True, non-stackable formats will be upgraded
713
to similar stackable formats.
714
:returns: a ControlDirFormat with all component formats either set
715
appropriately or set to None if that component should not be
718
format, repository = self._cloning_metadir()
719
if format._workingtree_format is None:
721
if repository is None:
722
# No repository either
724
# We have a repository, so set a working tree? (Why? This seems to
725
# contradict the stated return value in the docstring).
726
tree_format = repository._format._matchingbzrdir.workingtree_format
727
format.workingtree_format = tree_format.__class__()
729
format.require_stacking()
732
def get_branch_transport(self, branch_format, name=None):
733
"""Get the transport for use by branch format in this BzrDir.
735
Note that bzr dirs that do not support format strings will raise
736
IncompatibleFormat if the branch format they are given has
737
a format string, and vice versa.
739
If branch_format is None, the transport is returned with no
740
checking. If it is not None, then the returned transport is
741
guaranteed to point to an existing directory ready for use.
743
raise NotImplementedError(self.get_branch_transport)
745
def get_repository_transport(self, repository_format):
746
"""Get the transport for use by repository format in this BzrDir.
748
Note that bzr dirs that do not support format strings will raise
749
IncompatibleFormat if the repository format they are given has
750
a format string, and vice versa.
752
If repository_format is None, the transport is returned with no
753
checking. If it is not None, then the returned transport is
754
guaranteed to point to an existing directory ready for use.
756
raise NotImplementedError(self.get_repository_transport)
758
def get_workingtree_transport(self, tree_format):
759
"""Get the transport for use by workingtree format in this BzrDir.
761
Note that bzr dirs that do not support format strings will raise
762
IncompatibleFormat if the workingtree format they are given has a
763
format string, and vice versa.
765
If workingtree_format is None, the transport is returned with no
766
checking. If it is not None, then the returned transport is
767
guaranteed to point to an existing directory ready for use.
769
raise NotImplementedError(self.get_workingtree_transport)
772
def create(cls, base, format=None, possible_transports=None):
773
"""Create a new BzrDir at the url 'base'.
775
:param format: If supplied, the format of branch to create. If not
776
supplied, the default is used.
777
:param possible_transports: If supplied, a list of transports that
778
can be reused to share a remote connection.
780
if cls is not BzrDir:
781
raise AssertionError("BzrDir.create always creates the "
782
"default format, not one of %r" % cls)
783
return controldir.ControlDir.create(base, format=format,
784
possible_transports=possible_transports)
787
return "<%s at %r>" % (self.__class__.__name__, self.user_url)
789
def update_feature_flags(self, updated_flags):
790
"""Update the features required by this bzrdir.
792
:param updated_flags: Dictionary mapping feature names to necessities
793
A necessity can be None to indicate the feature should be removed
795
self.control_files.lock_write()
797
self._format._update_feature_flags(updated_flags)
798
self.transport.put_bytes('branch-format', self._format.as_string())
800
self.control_files.unlock()
803
class BzrDirMeta1(BzrDir):
804
"""A .bzr meta version 1 control object.
806
This is the first control object where the
807
individual aspects are really split out: there are separate repository,
808
workingtree and branch subdirectories and any subset of the three can be
809
present within a BzrDir.
812
def __init__(self, _transport, _format):
813
super(BzrDirMeta1, self).__init__(_transport, _format)
814
self.control_files = lockable_files.LockableFiles(self.control_transport,
815
self._format._lock_file_name, self._format._lock_class)
817
def can_convert_format(self):
818
"""See BzrDir.can_convert_format()."""
821
def create_branch(self, name=None, repository=None,
822
append_revisions_only=None):
823
"""See BzrDir.create_branch."""
825
name = self._get_selected_branch()
826
return self._format.get_branch_format().initialize(self, name=name,
827
repository=repository,
828
append_revisions_only=append_revisions_only)
830
def destroy_branch(self, name=None):
831
"""See BzrDir.create_branch."""
833
name = self._get_selected_branch()
835
raise errors.NoColocatedBranchSupport(self)
836
self.transport.delete_tree('branch')
838
def create_repository(self, shared=False):
839
"""See BzrDir.create_repository."""
840
return self._format.repository_format.initialize(self, shared)
842
def destroy_repository(self):
843
"""See BzrDir.destroy_repository."""
845
self.transport.delete_tree('repository')
846
except errors.NoSuchFile:
847
raise errors.NoRepositoryPresent(self)
849
def create_workingtree(self, revision_id=None, from_branch=None,
850
accelerator_tree=None, hardlink=False):
851
"""See BzrDir.create_workingtree."""
852
return self._format.workingtree_format.initialize(
853
self, revision_id, from_branch=from_branch,
854
accelerator_tree=accelerator_tree, hardlink=hardlink)
856
def destroy_workingtree(self):
857
"""See BzrDir.destroy_workingtree."""
858
wt = self.open_workingtree(recommend_upgrade=False)
859
repository = wt.branch.repository
860
empty = repository.revision_tree(_mod_revision.NULL_REVISION)
861
# We ignore the conflicts returned by wt.revert since we're about to
862
# delete the wt metadata anyway, all that should be left here are
863
# detritus. But see bug #634470 about subtree .bzr dirs.
864
conflicts = wt.revert(old_tree=empty)
865
self.destroy_workingtree_metadata()
867
def destroy_workingtree_metadata(self):
868
self.transport.delete_tree('checkout')
870
def find_branch_format(self, name=None):
871
"""Find the branch 'format' for this bzrdir.
873
This might be a synthetic object for e.g. RemoteBranch and SVN.
875
from bzrlib.branch import BranchFormatMetadir
876
return BranchFormatMetadir.find_format(self, name=name)
878
def _get_mkdir_mode(self):
879
"""Figure out the mode to use when creating a bzrdir subdir."""
880
temp_control = lockable_files.LockableFiles(self.transport, '',
881
lockable_files.TransportLock)
882
return temp_control._dir_mode
884
def get_branch_reference(self, name=None):
885
"""See BzrDir.get_branch_reference()."""
886
from bzrlib.branch import BranchFormatMetadir
887
format = BranchFormatMetadir.find_format(self, name=name)
888
return format.get_reference(self, name=name)
890
def get_branch_transport(self, branch_format, name=None):
891
"""See BzrDir.get_branch_transport()."""
893
name = self._get_selected_branch()
895
raise errors.NoColocatedBranchSupport(self)
896
# XXX: this shouldn't implicitly create the directory if it's just
897
# promising to get a transport -- mbp 20090727
898
if branch_format is None:
899
return self.transport.clone('branch')
901
branch_format.get_format_string()
902
except NotImplementedError:
903
raise errors.IncompatibleFormat(branch_format, self._format)
905
self.transport.mkdir('branch', mode=self._get_mkdir_mode())
906
except errors.FileExists:
908
return self.transport.clone('branch')
910
def get_repository_transport(self, repository_format):
911
"""See BzrDir.get_repository_transport()."""
912
if repository_format is None:
913
return self.transport.clone('repository')
915
repository_format.get_format_string()
916
except NotImplementedError:
917
raise errors.IncompatibleFormat(repository_format, self._format)
919
self.transport.mkdir('repository', mode=self._get_mkdir_mode())
920
except errors.FileExists:
922
return self.transport.clone('repository')
924
def get_workingtree_transport(self, workingtree_format):
925
"""See BzrDir.get_workingtree_transport()."""
926
if workingtree_format is None:
927
return self.transport.clone('checkout')
929
workingtree_format.get_format_string()
930
except NotImplementedError:
931
raise errors.IncompatibleFormat(workingtree_format, self._format)
933
self.transport.mkdir('checkout', mode=self._get_mkdir_mode())
934
except errors.FileExists:
936
return self.transport.clone('checkout')
938
def has_workingtree(self):
939
"""Tell if this bzrdir contains a working tree.
941
Note: if you're going to open the working tree, you should just go
942
ahead and try, and not ask permission first.
944
from bzrlib.workingtree import WorkingTreeFormatMetaDir
946
WorkingTreeFormatMetaDir.find_format_string(self)
947
except errors.NoWorkingTree:
951
def needs_format_conversion(self, format):
952
"""See BzrDir.needs_format_conversion()."""
953
if (not isinstance(self._format, format.__class__) or
954
self._format.get_format_string() != format.get_format_string()):
955
# it is not a meta dir format, conversion is needed.
957
# we might want to push this down to the repository?
959
if not isinstance(self.open_repository()._format,
960
format.repository_format.__class__):
961
# the repository needs an upgrade.
963
except errors.NoRepositoryPresent:
965
for branch in self.list_branches():
966
if not isinstance(branch._format,
967
format.get_branch_format().__class__):
968
# the branch needs an upgrade.
971
my_wt = self.open_workingtree(recommend_upgrade=False)
972
if not isinstance(my_wt._format,
973
format.workingtree_format.__class__):
974
# the workingtree needs an upgrade.
976
except (errors.NoWorkingTree, errors.NotLocalUrl):
980
def open_branch(self, name=None, unsupported=False,
981
ignore_fallbacks=False, possible_transports=None):
982
"""See ControlDir.open_branch."""
984
name = self._get_selected_branch()
985
format = self.find_branch_format(name=name)
986
format.check_support_status(unsupported)
987
return format.open(self, name=name,
988
_found=True, ignore_fallbacks=ignore_fallbacks,
989
possible_transports=possible_transports)
991
def open_repository(self, unsupported=False):
992
"""See BzrDir.open_repository."""
993
from bzrlib.repository import RepositoryFormatMetaDir
994
format = RepositoryFormatMetaDir.find_format(self)
995
format.check_support_status(unsupported)
996
return format.open(self, _found=True)
998
def open_workingtree(self, unsupported=False,
999
recommend_upgrade=True):
1000
"""See BzrDir.open_workingtree."""
1001
from bzrlib.workingtree import WorkingTreeFormatMetaDir
1002
format = WorkingTreeFormatMetaDir.find_format(self)
1003
format.check_support_status(unsupported, recommend_upgrade,
1004
basedir=self.root_transport.base)
1005
return format.open(self, _found=True)
1007
def _get_config(self):
1008
return config.TransportConfig(self.transport, 'control.conf')
1011
class BzrDirMeta1Colo(BzrDirMeta1):
1012
"""BzrDirMeta1 with support for colocated branches.
1014
This format is experimental, and will eventually be merged back into
1018
def _get_branch_path(self, name):
1019
"""Obtain the branch path to use.
1021
This uses the API specified branch name first, and then falls back to
1022
the branch name specified in the URL. If neither of those is specified,
1023
it uses the default branch.
1025
:param name: Optional branch name to use
1026
:return: Relative path to branch
1030
return urlutils.join('branches', name.encode("utf-8"))
1032
def _read_branch_list(self):
1033
"""Read the branch list.
1035
:return: List of utf-8 encoded branch names.
1038
f = self.control_transport.get('branch-list')
1039
except errors.NoSuchFile:
1045
ret.append(name.rstrip("\n"))
1050
def _write_branch_list(self, branches):
1051
"""Write out the branch list.
1053
:param branches: List of utf-8 branch names to write
1055
self.transport.put_bytes('branch-list',
1056
"".join([name+"\n" for name in branches]))
1058
def destroy_branch(self, name=None):
1059
"""See BzrDir.create_branch."""
1061
name = self._get_selected_branch()
1062
path = self._get_branch_path(name)
1064
self.control_files.lock_write()
1066
branches = self._read_branch_list()
1068
branches.remove(name.encode("utf-8"))
1070
raise errors.NotBranchError(name)
1071
self._write_branch_list(branches)
1073
self.control_files.unlock()
1074
self.transport.delete_tree(path)
1076
def get_branches(self):
1077
"""See ControlDir.get_branches."""
1080
ret[""] = self.open_branch(name="")
1081
except (errors.NotBranchError, errors.NoRepositoryPresent):
1084
for name in self._read_branch_list():
1085
ret[name] = self.open_branch(name=name.decode('utf-8'))
1089
def get_branch_transport(self, branch_format, name=None):
1090
"""See BzrDir.get_branch_transport()."""
1092
name = self._get_selected_branch()
1093
path = self._get_branch_path(name)
1094
# XXX: this shouldn't implicitly create the directory if it's just
1095
# promising to get a transport -- mbp 20090727
1096
if branch_format is None:
1097
return self.transport.clone(path)
1099
branch_format.get_format_string()
1100
except NotImplementedError:
1101
raise errors.IncompatibleFormat(branch_format, self._format)
1104
self.transport.mkdir('branches', mode=self._get_mkdir_mode())
1105
except errors.FileExists:
1107
branches = self._read_branch_list()
1108
utf8_name = name.encode("utf-8")
1109
if not utf8_name in branches:
1110
self.control_files.lock_write()
1112
branches = self._read_branch_list()
1113
branches.append(utf8_name)
1114
self._write_branch_list(branches)
1116
self.control_files.unlock()
1118
self.transport.mkdir(path, mode=self._get_mkdir_mode())
1119
except errors.FileExists:
1121
return self.transport.clone(path)
1124
class BzrFormat(object):
1125
"""Base class for all formats of things living in metadirs.
1127
This class manages the format string that is stored in the 'format'
1128
or 'branch-format' file.
1130
All classes for (branch-, repository-, workingtree-) formats that
1131
live in meta directories and have their own 'format' file
1132
(i.e. different from .bzr/branch-format) derive from this class,
1133
as well as the relevant base class for their kind
1134
(BranchFormat, WorkingTreeFormat, RepositoryFormat).
1136
Each format is identified by a "format" or "branch-format" file with a
1137
single line containing the base format name and then an optional list of
1140
Feature flags are supported as of bzr 2.5. Setting feature flags on formats
1141
will render them inaccessible to older versions of bzr.
1143
:ivar features: Dictionary mapping feature names to their necessity
1146
_present_features = set()
1152
def register_feature(cls, name):
1153
"""Register a feature as being present.
1155
:param name: Name of the feature
1158
raise ValueError("spaces are not allowed in feature names")
1159
if name in cls._present_features:
1160
raise errors.FeatureAlreadyRegistered(name)
1161
cls._present_features.add(name)
1164
def unregister_feature(cls, name):
1165
"""Unregister a feature."""
1166
cls._present_features.remove(name)
1168
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1170
for name, necessity in self.features.iteritems():
1171
if name in self._present_features:
1173
if necessity == "optional":
1174
mutter("ignoring optional missing feature %s", name)
1176
elif necessity == "required":
1177
raise errors.MissingFeature(name)
1179
mutter("treating unknown necessity as require for %s",
1181
raise errors.MissingFeature(name)
1184
def get_format_string(cls):
1185
"""Return the ASCII format string that identifies this format."""
1186
raise NotImplementedError(cls.get_format_string)
1189
def from_string(cls, text):
1190
format_string = cls.get_format_string()
1191
if not text.startswith(format_string):
1192
raise AssertionError("Invalid format header %r for %r" % (text, cls))
1193
lines = text[len(format_string):].splitlines()
1195
for lineno, line in enumerate(lines):
1197
(necessity, feature) = line.split(" ", 1)
1199
raise errors.ParseFormatError(format=cls, lineno=lineno+2,
1200
line=line, text=text)
1201
ret.features[feature] = necessity
1204
def as_string(self):
1205
"""Return the string representation of this format.
1207
lines = [self.get_format_string()]
1208
lines.extend([("%s %s\n" % (item[1], item[0])) for item in
1209
self.features.iteritems()])
1210
return "".join(lines)
1213
def _find_format(klass, registry, kind, format_string):
1215
first_line = format_string[:format_string.index("\n")+1]
1217
first_line = format_string
1219
cls = registry.get(first_line)
1221
raise errors.UnknownFormatError(format=first_line, kind=kind)
1222
return cls.from_string(format_string)
1224
def network_name(self):
1225
"""A simple byte string uniquely identifying this format for RPC calls.
1227
Metadir branch formats use their format string.
1229
return self.as_string()
1231
def __eq__(self, other):
1232
return (self.__class__ is other.__class__ and
1233
self.features == other.features)
1235
def _update_feature_flags(self, updated_flags):
1236
"""Update the feature flags in this format.
1238
:param updated_flags: Updated feature flags
1240
for name, necessity in updated_flags.iteritems():
1241
if necessity is None:
1243
del self.features[name]
1247
self.features[name] = necessity
1250
class BzrProber(controldir.Prober):
1251
"""Prober for formats that use a .bzr/ control directory."""
1253
formats = registry.FormatRegistry(controldir.network_format_registry)
1254
"""The known .bzr formats."""
1257
@deprecated_method(deprecated_in((2, 4, 0)))
1258
def register_bzrdir_format(klass, format):
1259
klass.formats.register(format.get_format_string(), format)
1262
@deprecated_method(deprecated_in((2, 4, 0)))
1263
def unregister_bzrdir_format(klass, format):
1264
klass.formats.remove(format.get_format_string())
1267
def probe_transport(klass, transport):
1268
"""Return the .bzrdir style format present in a directory."""
1270
format_string = transport.get_bytes(".bzr/branch-format")
1271
except errors.NoSuchFile:
1272
raise errors.NotBranchError(path=transport.base)
1274
first_line = format_string[:format_string.index("\n")+1]
1276
first_line = format_string
1278
cls = klass.formats.get(first_line)
1280
raise errors.UnknownFormatError(format=first_line, kind='bzrdir')
1281
return cls.from_string(format_string)
1284
def known_formats(cls):
1286
for name, format in cls.formats.iteritems():
1287
if callable(format):
1293
controldir.ControlDirFormat.register_prober(BzrProber)
1296
class RemoteBzrProber(controldir.Prober):
1297
"""Prober for remote servers that provide a Bazaar smart server."""
1300
def probe_transport(klass, transport):
1301
"""Return a RemoteBzrDirFormat object if it looks possible."""
1303
medium = transport.get_smart_medium()
1304
except (NotImplementedError, AttributeError,
1305
errors.TransportNotPossible, errors.NoSmartMedium,
1306
errors.SmartProtocolError):
1307
# no smart server, so not a branch for this format type.
1308
raise errors.NotBranchError(path=transport.base)
1310
# Decline to open it if the server doesn't support our required
1311
# version (3) so that the VFS-based transport will do it.
1312
if medium.should_probe():
1314
server_version = medium.protocol_version()
1315
except errors.SmartProtocolError:
1316
# Apparently there's no usable smart server there, even though
1317
# the medium supports the smart protocol.
1318
raise errors.NotBranchError(path=transport.base)
1319
if server_version != '2':
1320
raise errors.NotBranchError(path=transport.base)
1321
from bzrlib.remote import RemoteBzrDirFormat
1322
return RemoteBzrDirFormat()
1325
def known_formats(cls):
1326
from bzrlib.remote import RemoteBzrDirFormat
1327
return set([RemoteBzrDirFormat()])
1330
class BzrDirFormat(BzrFormat, controldir.ControlDirFormat):
1331
"""ControlDirFormat base class for .bzr/ directories.
1333
Formats are placed in a dict by their format string for reference
1334
during bzrdir opening. These should be subclasses of BzrDirFormat
1337
Once a format is deprecated, just deprecate the initialize and open
1338
methods on the format class. Do not deprecate the object, as the
1339
object will be created every system load.
1342
_lock_file_name = 'branch-lock'
1344
# _lock_class must be set in subclasses to the lock type, typ.
1345
# TransportLock or LockDir
1347
def initialize_on_transport(self, transport):
1348
"""Initialize a new bzrdir in the base directory of a Transport."""
1350
# can we hand off the request to the smart server rather than using
1352
client_medium = transport.get_smart_medium()
1353
except errors.NoSmartMedium:
1354
return self._initialize_on_transport_vfs(transport)
1356
# Current RPC's only know how to create bzr metadir1 instances, so
1357
# we still delegate to vfs methods if the requested format is not a
1359
if type(self) != BzrDirMetaFormat1:
1360
return self._initialize_on_transport_vfs(transport)
1361
from bzrlib.remote import RemoteBzrDirFormat
1362
remote_format = RemoteBzrDirFormat()
1363
self._supply_sub_formats_to(remote_format)
1364
return remote_format.initialize_on_transport(transport)
1366
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1367
create_prefix=False, force_new_repo=False, stacked_on=None,
1368
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1369
shared_repo=False, vfs_only=False):
1370
"""Create this format on transport.
1372
The directory to initialize will be created.
1374
:param force_new_repo: Do not use a shared repository for the target,
1375
even if one is available.
1376
:param create_prefix: Create any missing directories leading up to
1378
:param use_existing_dir: Use an existing directory if one exists.
1379
:param stacked_on: A url to stack any created branch on, None to follow
1380
any target stacking policy.
1381
:param stack_on_pwd: If stack_on is relative, the location it is
1383
:param repo_format_name: If non-None, a repository will be
1384
made-or-found. Should none be found, or if force_new_repo is True
1385
the repo_format_name is used to select the format of repository to
1387
:param make_working_trees: Control the setting of make_working_trees
1388
for a new shared repository when one is made. None to use whatever
1389
default the format has.
1390
:param shared_repo: Control whether made repositories are shared or
1392
:param vfs_only: If True do not attempt to use a smart server
1393
:return: repo, bzrdir, require_stacking, repository_policy. repo is
1394
None if none was created or found, bzrdir is always valid.
1395
require_stacking is the result of examining the stacked_on
1396
parameter and any stacking policy found for the target.
1399
# Try to hand off to a smart server
1401
client_medium = transport.get_smart_medium()
1402
except errors.NoSmartMedium:
1405
from bzrlib.remote import RemoteBzrDirFormat
1406
# TODO: lookup the local format from a server hint.
1407
remote_dir_format = RemoteBzrDirFormat()
1408
remote_dir_format._network_name = self.network_name()
1409
self._supply_sub_formats_to(remote_dir_format)
1410
return remote_dir_format.initialize_on_transport_ex(transport,
1411
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1412
force_new_repo=force_new_repo, stacked_on=stacked_on,
1413
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1414
make_working_trees=make_working_trees, shared_repo=shared_repo)
1415
# XXX: Refactor the create_prefix/no_create_prefix code into a
1416
# common helper function
1417
# The destination may not exist - if so make it according to policy.
1418
def make_directory(transport):
1419
transport.mkdir('.')
1421
def redirected(transport, e, redirection_notice):
1422
note(redirection_notice)
1423
return transport._redirected_to(e.source, e.target)
1425
transport = do_catching_redirections(make_directory, transport,
1427
except errors.FileExists:
1428
if not use_existing_dir:
1430
except errors.NoSuchFile:
1431
if not create_prefix:
1433
transport.create_prefix()
1435
require_stacking = (stacked_on is not None)
1436
# Now the target directory exists, but doesn't have a .bzr
1437
# directory. So we need to create it, along with any work to create
1438
# all of the dependent branches, etc.
1440
result = self.initialize_on_transport(transport)
1441
if repo_format_name:
1443
# use a custom format
1444
result._format.repository_format = \
1445
repository.network_format_registry.get(repo_format_name)
1446
except AttributeError:
1447
# The format didn't permit it to be set.
1449
# A repository is desired, either in-place or shared.
1450
repository_policy = result.determine_repository_policy(
1451
force_new_repo, stacked_on, stack_on_pwd,
1452
require_stacking=require_stacking)
1453
result_repo, is_new_repo = repository_policy.acquire_repository(
1454
make_working_trees, shared_repo)
1455
if not require_stacking and repository_policy._require_stacking:
1456
require_stacking = True
1457
result._format.require_stacking()
1458
result_repo.lock_write()
1461
repository_policy = None
1462
return result_repo, result, require_stacking, repository_policy
1464
def _initialize_on_transport_vfs(self, transport):
1465
"""Initialize a new bzrdir using VFS calls.
1467
:param transport: The transport to create the .bzr directory in.
1470
# Since we are creating a .bzr directory, inherit the
1471
# mode from the root directory
1472
temp_control = lockable_files.LockableFiles(transport,
1473
'', lockable_files.TransportLock)
1474
temp_control._transport.mkdir('.bzr',
1475
# FIXME: RBC 20060121 don't peek under
1477
mode=temp_control._dir_mode)
1478
if sys.platform == 'win32' and isinstance(transport, local.LocalTransport):
1479
win32utils.set_file_attr_hidden(transport._abspath('.bzr'))
1480
file_mode = temp_control._file_mode
1482
bzrdir_transport = transport.clone('.bzr')
1483
utf8_files = [('README',
1484
"This is a Bazaar control directory.\n"
1485
"Do not change any files in this directory.\n"
1486
"See http://bazaar.canonical.com/ for more information about Bazaar.\n"),
1487
('branch-format', self.as_string()),
1489
# NB: no need to escape relative paths that are url safe.
1490
control_files = lockable_files.LockableFiles(bzrdir_transport,
1491
self._lock_file_name, self._lock_class)
1492
control_files.create_lock()
1493
control_files.lock_write()
1495
for (filename, content) in utf8_files:
1496
bzrdir_transport.put_bytes(filename, content,
1499
control_files.unlock()
1500
return self.open(transport, _found=True)
1502
def open(self, transport, _found=False):
1503
"""Return an instance of this format for the dir transport points at.
1505
_found is a private parameter, do not use it.
1508
found_format = controldir.ControlDirFormat.find_format(transport)
1509
if not isinstance(found_format, self.__class__):
1510
raise AssertionError("%s was asked to open %s, but it seems to need "
1512
% (self, transport, found_format))
1513
# Allow subclasses - use the found format.
1514
self._supply_sub_formats_to(found_format)
1515
return found_format._open(transport)
1516
return self._open(transport)
1518
def _open(self, transport):
1519
"""Template method helper for opening BzrDirectories.
1521
This performs the actual open and any additional logic or parameter
1524
raise NotImplementedError(self._open)
1526
def _supply_sub_formats_to(self, other_format):
1527
"""Give other_format the same values for sub formats as this has.
1529
This method is expected to be used when parameterising a
1530
RemoteBzrDirFormat instance with the parameters from a
1531
BzrDirMetaFormat1 instance.
1533
:param other_format: other_format is a format which should be
1534
compatible with whatever sub formats are supported by self.
1537
other_format.features = dict(self.features)
1539
def supports_transport(self, transport):
1540
# bzr formats can be opened over all known transports
1543
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1545
controldir.ControlDirFormat.check_support_status(self,
1546
allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
1548
BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
1549
recommend_upgrade=recommend_upgrade, basedir=basedir)
1552
class BzrDirMetaFormat1(BzrDirFormat):
1553
"""Bzr meta control format 1
1555
This is the first format with split out working tree, branch and repository
1560
- Format 3 working trees [optional]
1561
- Format 5 branches [optional]
1562
- Format 7 repositories [optional]
1565
_lock_class = lockdir.LockDir
1567
fixed_components = False
1569
colocated_branches = False
1572
BzrDirFormat.__init__(self)
1573
self._workingtree_format = None
1574
self._branch_format = None
1575
self._repository_format = None
1577
def __eq__(self, other):
1578
if other.__class__ is not self.__class__:
1580
if other.repository_format != self.repository_format:
1582
if other.workingtree_format != self.workingtree_format:
1584
if other.features != self.features:
1588
def __ne__(self, other):
1589
return not self == other
1591
def get_branch_format(self):
1592
if self._branch_format is None:
1593
from bzrlib.branch import format_registry as branch_format_registry
1594
self._branch_format = branch_format_registry.get_default()
1595
return self._branch_format
1597
def set_branch_format(self, format):
1598
self._branch_format = format
1600
def require_stacking(self, stack_on=None, possible_transports=None,
1602
"""We have a request to stack, try to ensure the formats support it.
1604
:param stack_on: If supplied, it is the URL to a branch that we want to
1605
stack on. Check to see if that format supports stacking before
1608
# Stacking is desired. requested by the target, but does the place it
1609
# points at support stacking? If it doesn't then we should
1610
# not implicitly upgrade. We check this here.
1611
new_repo_format = None
1612
new_branch_format = None
1614
# a bit of state for get_target_branch so that we don't try to open it
1615
# 2 times, for both repo *and* branch
1616
target = [None, False, None] # target_branch, checked, upgrade anyway
1617
def get_target_branch():
1619
# We've checked, don't check again
1621
if stack_on is None:
1622
# No target format, that means we want to force upgrading
1623
target[:] = [None, True, True]
1626
target_dir = BzrDir.open(stack_on,
1627
possible_transports=possible_transports)
1628
except errors.NotBranchError:
1629
# Nothing there, don't change formats
1630
target[:] = [None, True, False]
1632
except errors.JailBreak:
1633
# JailBreak, JFDI and upgrade anyway
1634
target[:] = [None, True, True]
1637
target_branch = target_dir.open_branch()
1638
except errors.NotBranchError:
1639
# No branch, don't upgrade formats
1640
target[:] = [None, True, False]
1642
target[:] = [target_branch, True, False]
1645
if (not _skip_repo and
1646
not self.repository_format.supports_external_lookups):
1647
# We need to upgrade the Repository.
1648
target_branch, _, do_upgrade = get_target_branch()
1649
if target_branch is None:
1650
# We don't have a target branch, should we upgrade anyway?
1652
# stack_on is inaccessible, JFDI.
1653
# TODO: bad monkey, hard-coded formats...
1654
if self.repository_format.rich_root_data:
1655
new_repo_format = knitpack_repo.RepositoryFormatKnitPack5RichRoot()
1657
new_repo_format = knitpack_repo.RepositoryFormatKnitPack5()
1659
# If the target already supports stacking, then we know the
1660
# project is already able to use stacking, so auto-upgrade
1662
new_repo_format = target_branch.repository._format
1663
if not new_repo_format.supports_external_lookups:
1664
# target doesn't, source doesn't, so don't auto upgrade
1666
new_repo_format = None
1667
if new_repo_format is not None:
1668
self.repository_format = new_repo_format
1669
note(gettext('Source repository format does not support stacking,'
1670
' using format:\n %s'),
1671
new_repo_format.get_format_description())
1673
if not self.get_branch_format().supports_stacking():
1674
# We just checked the repo, now lets check if we need to
1675
# upgrade the branch format
1676
target_branch, _, do_upgrade = get_target_branch()
1677
if target_branch is None:
1679
# TODO: bad monkey, hard-coded formats...
1680
from bzrlib.branch import BzrBranchFormat7
1681
new_branch_format = BzrBranchFormat7()
1683
new_branch_format = target_branch._format
1684
if not new_branch_format.supports_stacking():
1685
new_branch_format = None
1686
if new_branch_format is not None:
1687
# Does support stacking, use its format.
1688
self.set_branch_format(new_branch_format)
1689
note(gettext('Source branch format does not support stacking,'
1690
' using format:\n %s'),
1691
new_branch_format.get_format_description())
1693
def get_converter(self, format=None):
1694
"""See BzrDirFormat.get_converter()."""
1696
format = BzrDirFormat.get_default_format()
1697
if (type(self) is BzrDirMetaFormat1 and
1698
type(format) is BzrDirMetaFormat1Colo):
1699
return ConvertMetaToColo(format)
1700
if (type(self) is BzrDirMetaFormat1Colo and
1701
type(format) is BzrDirMetaFormat1):
1702
return ConvertMetaRemoveColo(format)
1703
if not isinstance(self, format.__class__):
1704
# converting away from metadir is not implemented
1705
raise NotImplementedError(self.get_converter)
1706
return ConvertMetaToMeta(format)
1709
def get_format_string(cls):
1710
"""See BzrDirFormat.get_format_string()."""
1711
return "Bazaar-NG meta directory, format 1\n"
1713
def get_format_description(self):
1714
"""See BzrDirFormat.get_format_description()."""
1715
return "Meta directory format 1"
1717
def _open(self, transport):
1718
"""See BzrDirFormat._open."""
1719
# Create a new format instance because otherwise initialisation of new
1720
# metadirs share the global default format object leading to alias
1722
format = BzrDirMetaFormat1()
1723
self._supply_sub_formats_to(format)
1724
return BzrDirMeta1(transport, format)
1726
def __return_repository_format(self):
1727
"""Circular import protection."""
1728
if self._repository_format:
1729
return self._repository_format
1730
from bzrlib.repository import format_registry
1731
return format_registry.get_default()
1733
def _set_repository_format(self, value):
1734
"""Allow changing the repository format for metadir formats."""
1735
self._repository_format = value
1737
repository_format = property(__return_repository_format,
1738
_set_repository_format)
1740
def _supply_sub_formats_to(self, other_format):
1741
"""Give other_format the same values for sub formats as this has.
1743
This method is expected to be used when parameterising a
1744
RemoteBzrDirFormat instance with the parameters from a
1745
BzrDirMetaFormat1 instance.
1747
:param other_format: other_format is a format which should be
1748
compatible with whatever sub formats are supported by self.
1751
super(BzrDirMetaFormat1, self)._supply_sub_formats_to(other_format)
1752
if getattr(self, '_repository_format', None) is not None:
1753
other_format.repository_format = self.repository_format
1754
if self._branch_format is not None:
1755
other_format._branch_format = self._branch_format
1756
if self._workingtree_format is not None:
1757
other_format.workingtree_format = self.workingtree_format
1759
def __get_workingtree_format(self):
1760
if self._workingtree_format is None:
1761
from bzrlib.workingtree import (
1762
format_registry as wt_format_registry,
1764
self._workingtree_format = wt_format_registry.get_default()
1765
return self._workingtree_format
1767
def __set_workingtree_format(self, wt_format):
1768
self._workingtree_format = wt_format
1771
return "<%r>" % (self.__class__.__name__,)
1773
workingtree_format = property(__get_workingtree_format,
1774
__set_workingtree_format)
1777
# Register bzr formats
1778
BzrProber.formats.register(BzrDirMetaFormat1.get_format_string(),
1780
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1783
class BzrDirMetaFormat1Colo(BzrDirMetaFormat1):
1784
"""BzrDirMeta1 format with support for colocated branches."""
1786
colocated_branches = True
1789
def get_format_string(cls):
1790
"""See BzrDirFormat.get_format_string()."""
1791
return "Bazaar meta directory, format 1 (with colocated branches)\n"
1793
def get_format_description(self):
1794
"""See BzrDirFormat.get_format_description()."""
1795
return "Meta directory format 1 with support for colocated branches"
1797
def _open(self, transport):
1798
"""See BzrDirFormat._open."""
1799
# Create a new format instance because otherwise initialisation of new
1800
# metadirs share the global default format object leading to alias
1802
format = BzrDirMetaFormat1Colo()
1803
self._supply_sub_formats_to(format)
1804
return BzrDirMeta1Colo(transport, format)
1807
BzrProber.formats.register(BzrDirMetaFormat1Colo.get_format_string(),
1808
BzrDirMetaFormat1Colo)
1811
class ConvertMetaToMeta(controldir.Converter):
1812
"""Converts the components of metadirs."""
1814
def __init__(self, target_format):
1815
"""Create a metadir to metadir converter.
1817
:param target_format: The final metadir format that is desired.
1819
self.target_format = target_format
1821
def convert(self, to_convert, pb):
1822
"""See Converter.convert()."""
1823
self.bzrdir = to_convert
1824
self.pb = ui.ui_factory.nested_progress_bar()
1827
self.step('checking repository format')
1829
repo = self.bzrdir.open_repository()
1830
except errors.NoRepositoryPresent:
1833
if not isinstance(repo._format, self.target_format.repository_format.__class__):
1834
from bzrlib.repository import CopyConverter
1835
ui.ui_factory.note(gettext('starting repository conversion'))
1836
converter = CopyConverter(self.target_format.repository_format)
1837
converter.convert(repo, pb)
1838
for branch in self.bzrdir.list_branches():
1839
# TODO: conversions of Branch and Tree should be done by
1840
# InterXFormat lookups/some sort of registry.
1841
# Avoid circular imports
1842
old = branch._format.__class__
1843
new = self.target_format.get_branch_format().__class__
1845
if (old == _mod_branch.BzrBranchFormat5 and
1846
new in (_mod_branch.BzrBranchFormat6,
1847
_mod_branch.BzrBranchFormat7,
1848
_mod_branch.BzrBranchFormat8)):
1849
branch_converter = _mod_branch.Converter5to6()
1850
elif (old == _mod_branch.BzrBranchFormat6 and
1851
new in (_mod_branch.BzrBranchFormat7,
1852
_mod_branch.BzrBranchFormat8)):
1853
branch_converter = _mod_branch.Converter6to7()
1854
elif (old == _mod_branch.BzrBranchFormat7 and
1855
new is _mod_branch.BzrBranchFormat8):
1856
branch_converter = _mod_branch.Converter7to8()
1858
raise errors.BadConversionTarget("No converter", new,
1860
branch_converter.convert(branch)
1861
branch = self.bzrdir.open_branch()
1862
old = branch._format.__class__
1864
tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
1865
except (errors.NoWorkingTree, errors.NotLocalUrl):
1868
# TODO: conversions of Branch and Tree should be done by
1869
# InterXFormat lookups
1870
if (isinstance(tree, workingtree_3.WorkingTree3) and
1871
not isinstance(tree, workingtree_4.DirStateWorkingTree) and
1872
isinstance(self.target_format.workingtree_format,
1873
workingtree_4.DirStateWorkingTreeFormat)):
1874
workingtree_4.Converter3to4().convert(tree)
1875
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1876
not isinstance(tree, workingtree_4.WorkingTree5) and
1877
isinstance(self.target_format.workingtree_format,
1878
workingtree_4.WorkingTreeFormat5)):
1879
workingtree_4.Converter4to5().convert(tree)
1880
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1881
not isinstance(tree, workingtree_4.WorkingTree6) and
1882
isinstance(self.target_format.workingtree_format,
1883
workingtree_4.WorkingTreeFormat6)):
1884
workingtree_4.Converter4or5to6().convert(tree)
1889
class ConvertMetaToColo(controldir.Converter):
1890
"""Add colocated branch support."""
1892
def __init__(self, target_format):
1893
"""Create a converter.that upgrades a metadir to the colo format.
1895
:param target_format: The final metadir format that is desired.
1897
self.target_format = target_format
1899
def convert(self, to_convert, pb):
1900
"""See Converter.convert()."""
1901
to_convert.transport.put_bytes('branch-format',
1902
self.target_format.as_string())
1903
return BzrDir.open_from_transport(to_convert.root_transport)
1906
class ConvertMetaRemoveColo(controldir.Converter):
1907
"""Remove colocated branch support from a bzrdir."""
1909
def __init__(self, target_format):
1910
"""Create a converter.that downgrades a colocated branch metadir
1911
to a regular metadir.
1913
:param target_format: The final metadir format that is desired.
1915
self.target_format = target_format
1917
def convert(self, to_convert, pb):
1918
"""See Converter.convert()."""
1919
to_convert.control_files.lock_write()
1921
branches = to_convert.list_branches()
1922
if len(branches) > 1:
1923
raise errors.BzrError("remove all but a single "
1924
"colocated branch when downgrading")
1926
to_convert.control_files.unlock()
1927
to_convert.transport.put_bytes('branch-format',
1928
self.target_format.as_string())
1929
return BzrDir.open_from_transport(to_convert.root_transport)
1932
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
1935
class RepositoryAcquisitionPolicy(object):
1936
"""Abstract base class for repository acquisition policies.
1938
A repository acquisition policy decides how a BzrDir acquires a repository
1939
for a branch that is being created. The most basic policy decision is
1940
whether to create a new repository or use an existing one.
1942
def __init__(self, stack_on, stack_on_pwd, require_stacking):
1945
:param stack_on: A location to stack on
1946
:param stack_on_pwd: If stack_on is relative, the location it is
1948
:param require_stacking: If True, it is a failure to not stack.
1950
self._stack_on = stack_on
1951
self._stack_on_pwd = stack_on_pwd
1952
self._require_stacking = require_stacking
1954
def configure_branch(self, branch):
1955
"""Apply any configuration data from this policy to the branch.
1957
Default implementation sets repository stacking.
1959
if self._stack_on is None:
1961
if self._stack_on_pwd is None:
1962
stack_on = self._stack_on
1965
stack_on = urlutils.rebase_url(self._stack_on,
1968
except errors.InvalidRebaseURLs:
1969
stack_on = self._get_full_stack_on()
1971
branch.set_stacked_on_url(stack_on)
1972
except (errors.UnstackableBranchFormat,
1973
errors.UnstackableRepositoryFormat):
1974
if self._require_stacking:
1977
def requires_stacking(self):
1978
"""Return True if this policy requires stacking."""
1979
return self._stack_on is not None and self._require_stacking
1981
def _get_full_stack_on(self):
1982
"""Get a fully-qualified URL for the stack_on location."""
1983
if self._stack_on is None:
1985
if self._stack_on_pwd is None:
1986
return self._stack_on
1988
return urlutils.join(self._stack_on_pwd, self._stack_on)
1990
def _add_fallback(self, repository, possible_transports=None):
1991
"""Add a fallback to the supplied repository, if stacking is set."""
1992
stack_on = self._get_full_stack_on()
1993
if stack_on is None:
1996
stacked_dir = BzrDir.open(stack_on,
1997
possible_transports=possible_transports)
1998
except errors.JailBreak:
1999
# We keep the stacking details, but we are in the server code so
2000
# actually stacking is not needed.
2003
stacked_repo = stacked_dir.open_branch().repository
2004
except errors.NotBranchError:
2005
stacked_repo = stacked_dir.open_repository()
2007
repository.add_fallback_repository(stacked_repo)
2008
except errors.UnstackableRepositoryFormat:
2009
if self._require_stacking:
2012
self._require_stacking = True
2014
def acquire_repository(self, make_working_trees=None, shared=False,
2015
possible_transports=None):
2016
"""Acquire a repository for this bzrdir.
2018
Implementations may create a new repository or use a pre-exising
2021
:param make_working_trees: If creating a repository, set
2022
make_working_trees to this value (if non-None)
2023
:param shared: If creating a repository, make it shared if True
2024
:return: A repository, is_new_flag (True if the repository was
2027
raise NotImplementedError(RepositoryAcquisitionPolicy.acquire_repository)
2030
class CreateRepository(RepositoryAcquisitionPolicy):
2031
"""A policy of creating a new repository"""
2033
def __init__(self, bzrdir, stack_on=None, stack_on_pwd=None,
2034
require_stacking=False):
2037
:param bzrdir: The bzrdir to create the repository on.
2038
:param stack_on: A location to stack on
2039
:param stack_on_pwd: If stack_on is relative, the location it is
2042
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2044
self._bzrdir = bzrdir
2046
def acquire_repository(self, make_working_trees=None, shared=False,
2047
possible_transports=None):
2048
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2050
Creates the desired repository in the bzrdir we already have.
2052
if possible_transports is None:
2053
possible_transports = []
2055
possible_transports = list(possible_transports)
2056
possible_transports.append(self._bzrdir.root_transport)
2057
stack_on = self._get_full_stack_on()
2059
format = self._bzrdir._format
2060
format.require_stacking(stack_on=stack_on,
2061
possible_transports=possible_transports)
2062
if not self._require_stacking:
2063
# We have picked up automatic stacking somewhere.
2064
note(gettext('Using default stacking branch {0} at {1}').format(
2065
self._stack_on, self._stack_on_pwd))
2066
repository = self._bzrdir.create_repository(shared=shared)
2067
self._add_fallback(repository,
2068
possible_transports=possible_transports)
2069
if make_working_trees is not None:
2070
repository.set_make_working_trees(make_working_trees)
2071
return repository, True
2074
class UseExistingRepository(RepositoryAcquisitionPolicy):
2075
"""A policy of reusing an existing repository"""
2077
def __init__(self, repository, stack_on=None, stack_on_pwd=None,
2078
require_stacking=False):
2081
:param repository: The repository to use.
2082
:param stack_on: A location to stack on
2083
:param stack_on_pwd: If stack_on is relative, the location it is
2086
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2088
self._repository = repository
2090
def acquire_repository(self, make_working_trees=None, shared=False,
2091
possible_transports=None):
2092
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2094
Returns an existing repository to use.
2096
if possible_transports is None:
2097
possible_transports = []
2099
possible_transports = list(possible_transports)
2100
possible_transports.append(self._repository.bzrdir.transport)
2101
self._add_fallback(self._repository,
2102
possible_transports=possible_transports)
2103
return self._repository, False
2106
def register_metadir(registry, key,
2107
repository_format, help, native=True, deprecated=False,
2112
alias=False, bzrdir_format=None):
2113
"""Register a metadir subformat.
2115
These all use a meta bzrdir, but can be parameterized by the
2116
Repository/Branch/WorkingTreeformats.
2118
:param repository_format: The fully-qualified repository format class
2120
:param branch_format: Fully-qualified branch format class name as
2122
:param tree_format: Fully-qualified tree format class name as
2125
if bzrdir_format is None:
2126
bzrdir_format = BzrDirMetaFormat1
2127
# This should be expanded to support setting WorkingTree and Branch
2128
# formats, once the API supports that.
2129
def _load(full_name):
2130
mod_name, factory_name = full_name.rsplit('.', 1)
2132
factory = pyutils.get_named_object(mod_name, factory_name)
2133
except ImportError, e:
2134
raise ImportError('failed to load %s: %s' % (full_name, e))
2135
except AttributeError:
2136
raise AttributeError('no factory %s in module %r'
2137
% (full_name, sys.modules[mod_name]))
2141
bd = bzrdir_format()
2142
if branch_format is not None:
2143
bd.set_branch_format(_load(branch_format))
2144
if tree_format is not None:
2145
bd.workingtree_format = _load(tree_format)
2146
if repository_format is not None:
2147
bd.repository_format = _load(repository_format)
2149
registry.register(key, helper, help, native, deprecated, hidden,
2150
experimental, alias)
2152
register_metadir(controldir.format_registry, 'knit',
2153
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2154
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
2155
branch_format='bzrlib.branch.BzrBranchFormat5',
2156
tree_format='bzrlib.workingtree_3.WorkingTreeFormat3',
2159
register_metadir(controldir.format_registry, 'dirstate',
2160
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2161
help='Format using dirstate for working trees. '
2162
'Compatible with bzr 0.8 and '
2163
'above when accessed over the network. Introduced in bzr 0.15.',
2164
branch_format='bzrlib.branch.BzrBranchFormat5',
2165
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2168
register_metadir(controldir.format_registry, 'dirstate-tags',
2169
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2170
help='Variant of dirstate with support for tags. '
2171
'Introduced in bzr 0.15.',
2172
branch_format='bzrlib.branch.BzrBranchFormat6',
2173
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2176
register_metadir(controldir.format_registry, 'rich-root',
2177
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
2178
help='Variant of dirstate with better handling of tree roots. '
2179
'Introduced in bzr 1.0',
2180
branch_format='bzrlib.branch.BzrBranchFormat6',
2181
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2184
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
2185
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2186
help='Variant of dirstate with support for nested trees. '
2187
'Introduced in 0.15.',
2188
branch_format='bzrlib.branch.BzrBranchFormat6',
2189
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2193
register_metadir(controldir.format_registry, 'pack-0.92',
2194
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
2195
help='Pack-based format used in 1.x series. Introduced in 0.92. '
2196
'Interoperates with bzr repositories before 0.92 but cannot be '
2197
'read by bzr < 0.92. '
2199
branch_format='bzrlib.branch.BzrBranchFormat6',
2200
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2203
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2204
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
2205
help='Pack-based format used in 1.x series, with subtree support. '
2206
'Introduced in 0.92. Interoperates with '
2207
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2209
branch_format='bzrlib.branch.BzrBranchFormat6',
2210
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2215
register_metadir(controldir.format_registry, 'rich-root-pack',
2216
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
2217
help='A variant of pack-0.92 that supports rich-root data '
2218
'(needed for bzr-svn and bzr-git). Introduced in 1.0.',
2219
branch_format='bzrlib.branch.BzrBranchFormat6',
2220
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2224
register_metadir(controldir.format_registry, '1.6',
2225
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
2226
help='A format that allows a branch to indicate that there is another '
2227
'(stacked) repository that should be used to access data that is '
2228
'not present locally.',
2229
branch_format='bzrlib.branch.BzrBranchFormat7',
2230
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2234
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2235
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
2236
help='A variant of 1.6 that supports rich-root data '
2237
'(needed for bzr-svn and bzr-git).',
2238
branch_format='bzrlib.branch.BzrBranchFormat7',
2239
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2243
register_metadir(controldir.format_registry, '1.9',
2244
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2245
help='A repository format using B+tree indexes. These indexes '
2246
'are smaller in size, have smarter caching and provide faster '
2247
'performance for most operations.',
2248
branch_format='bzrlib.branch.BzrBranchFormat7',
2249
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2253
register_metadir(controldir.format_registry, '1.9-rich-root',
2254
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2255
help='A variant of 1.9 that supports rich-root data '
2256
'(needed for bzr-svn and bzr-git).',
2257
branch_format='bzrlib.branch.BzrBranchFormat7',
2258
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2262
register_metadir(controldir.format_registry, '1.14',
2263
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2264
help='A working-tree format that supports content filtering.',
2265
branch_format='bzrlib.branch.BzrBranchFormat7',
2266
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2270
register_metadir(controldir.format_registry, '1.14-rich-root',
2271
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2272
help='A variant of 1.14 that supports rich-root data '
2273
'(needed for bzr-svn and bzr-git).',
2274
branch_format='bzrlib.branch.BzrBranchFormat7',
2275
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2279
# The following un-numbered 'development' formats should always just be aliases.
2280
register_metadir(controldir.format_registry, 'development-subtree',
2281
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2aSubtree',
2282
help='Current development format, subtree variant. Can convert data to and '
2283
'from pack-0.92-subtree (and anything compatible with '
2284
'pack-0.92-subtree) format repositories. Repositories and branches in '
2285
'this format can only be read by bzr.dev. Please read '
2286
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2288
branch_format='bzrlib.branch.BzrBranchFormat7',
2289
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2292
alias=False, # Restore to being an alias when an actual development subtree format is added
2293
# This current non-alias status is simply because we did not introduce a
2294
# chk based subtree format.
2296
register_metadir(controldir.format_registry, 'development5-subtree',
2297
'bzrlib.repofmt.knitpack_repo.RepositoryFormatPackDevelopment2Subtree',
2298
help='Development format, subtree variant. Can convert data to and '
2299
'from pack-0.92-subtree (and anything compatible with '
2300
'pack-0.92-subtree) format repositories. Repositories and branches in '
2301
'this format can only be read by bzr.dev. Please read '
2302
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2304
branch_format='bzrlib.branch.BzrBranchFormat7',
2305
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2311
register_metadir(controldir.format_registry, 'development-colo',
2312
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2313
help='The 2a format with experimental support for colocated branches.\n',
2314
branch_format='bzrlib.branch.BzrBranchFormat7',
2315
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2317
bzrdir_format=BzrDirMetaFormat1Colo,
2321
# And the development formats above will have aliased one of the following:
2323
# Finally, the current format.
2324
register_metadir(controldir.format_registry, '2a',
2325
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2326
help='Format for the bzr 2.0 series.\n'
2327
'Uses group-compress storage.\n'
2328
'Provides rich roots which are a one-way transition.\n',
2329
# 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
2330
# 'rich roots. Supported by bzr 1.16 and later.',
2331
branch_format='bzrlib.branch.BzrBranchFormat7',
2332
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2336
# The following format should be an alias for the rich root equivalent
2337
# of the default format
2338
register_metadir(controldir.format_registry, 'default-rich-root',
2339
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2340
branch_format='bzrlib.branch.BzrBranchFormat7',
2341
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2346
# The current format that is made on 'bzr init'.
2347
format_name = config.GlobalStack().get('default_format')
2348
controldir.format_registry.set_default(format_name)
2350
# XXX 2010-08-20 JRV: There is still a lot of code relying on
2351
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc
2352
# get changed to ControlDir.create/ControlDir.open/etc this should be removed.
2353
format_registry = controldir.format_registry