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