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
30
from bzrlib.lazy_import import lazy_import
31
lazy_import(globals(), """
34
branch as _mod_branch,
47
revision as _mod_revision,
48
transport as _mod_transport,
55
from bzrlib.repofmt import knitpack_repo
56
from bzrlib.transport import (
57
do_catching_redirections,
62
from bzrlib.trace import (
71
from bzrlib.symbol_versioning import (
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 = graph.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)
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)
236
def find_bzrdirs(transport, evaluate=None, list_current=None):
237
"""Find bzrdirs recursively from current location.
239
This is intended primarily as a building block for more sophisticated
240
functionality, like finding trees under a directory, or finding
241
branches that use a given repository.
242
:param evaluate: An optional callable that yields recurse, value,
243
where recurse controls whether this bzrdir is recursed into
244
and value is the value to yield. By default, all bzrdirs
245
are recursed into, and the return value is the bzrdir.
246
:param list_current: if supplied, use this function to list the current
247
directory, instead of Transport.list_dir
248
:return: a generator of found bzrdirs, or whatever evaluate returns.
250
if list_current is None:
251
def list_current(transport):
252
return transport.list_dir('')
254
def evaluate(bzrdir):
257
pending = [transport]
258
while len(pending) > 0:
259
current_transport = pending.pop()
262
bzrdir = BzrDir.open_from_transport(current_transport)
263
except (errors.NotBranchError, errors.PermissionDenied):
266
recurse, value = evaluate(bzrdir)
269
subdirs = list_current(current_transport)
270
except (errors.NoSuchFile, errors.PermissionDenied):
273
for subdir in sorted(subdirs, reverse=True):
274
pending.append(current_transport.clone(subdir))
277
def find_branches(transport):
278
"""Find all branches under a transport.
280
This will find all branches below the transport, including branches
281
inside other branches. Where possible, it will use
282
Repository.find_branches.
284
To list all the branches that use a particular Repository, see
285
Repository.find_branches
287
def evaluate(bzrdir):
289
repository = bzrdir.open_repository()
290
except errors.NoRepositoryPresent:
293
return False, ([], repository)
294
return True, (bzrdir.list_branches(), None)
296
for branches, repo in BzrDir.find_bzrdirs(transport,
299
ret.extend(repo.find_branches())
300
if branches is not None:
305
def create_branch_and_repo(base, force_new_repo=False, format=None):
306
"""Create a new BzrDir, Branch and Repository at the url 'base'.
308
This will use the current default BzrDirFormat unless one is
309
specified, and use whatever
310
repository format that that uses via bzrdir.create_branch and
311
create_repository. If a shared repository is available that is used
314
The created Branch object is returned.
316
:param base: The URL to create the branch at.
317
:param force_new_repo: If True a new repository is always created.
318
:param format: If supplied, the format of branch to create. If not
319
supplied, the default is used.
321
bzrdir = BzrDir.create(base, format)
322
bzrdir._find_or_create_repository(force_new_repo)
323
return bzrdir.create_branch()
325
def determine_repository_policy(self, force_new_repo=False, stack_on=None,
326
stack_on_pwd=None, require_stacking=False):
327
"""Return an object representing a policy to use.
329
This controls whether a new repository is created, and the format of
330
that repository, or some existing shared repository used instead.
332
If stack_on is supplied, will not seek a containing shared repo.
334
:param force_new_repo: If True, require a new repository to be created.
335
:param stack_on: If supplied, the location to stack on. If not
336
supplied, a default_stack_on location may be used.
337
:param stack_on_pwd: If stack_on is relative, the location it is
340
def repository_policy(found_bzrdir):
343
config = found_bzrdir.get_config()
345
stack_on = config.get_default_stack_on()
346
if stack_on is not None:
347
stack_on_pwd = found_bzrdir.user_url
349
# does it have a repository ?
351
repository = found_bzrdir.open_repository()
352
except errors.NoRepositoryPresent:
355
if (found_bzrdir.user_url != self.user_url
356
and not repository.is_shared()):
357
# Don't look higher, can't use a higher shared repo.
365
return UseExistingRepository(repository, stack_on,
366
stack_on_pwd, require_stacking=require_stacking), True
368
return CreateRepository(self, stack_on, stack_on_pwd,
369
require_stacking=require_stacking), True
371
if not force_new_repo:
373
policy = self._find_containing(repository_policy)
374
if policy is not None:
378
return UseExistingRepository(self.open_repository(),
379
stack_on, stack_on_pwd,
380
require_stacking=require_stacking)
381
except errors.NoRepositoryPresent:
383
return CreateRepository(self, stack_on, stack_on_pwd,
384
require_stacking=require_stacking)
386
def _find_or_create_repository(self, force_new_repo):
387
"""Create a new repository if needed, returning the repository."""
388
policy = self.determine_repository_policy(force_new_repo)
389
return policy.acquire_repository()[0]
391
def _find_source_repo(self, add_cleanup, source_branch):
392
"""Find the source branch and repo for a sprout operation.
394
This is helper intended for use by _sprout.
396
:returns: (source_branch, source_repository). Either or both may be
397
None. If not None, they will be read-locked (and their unlock(s)
398
scheduled via the add_cleanup param).
400
if source_branch is not None:
401
add_cleanup(source_branch.lock_read().unlock)
402
return source_branch, source_branch.repository
404
source_branch = self.open_branch()
405
source_repository = source_branch.repository
406
except errors.NotBranchError:
409
source_repository = self.open_repository()
410
except errors.NoRepositoryPresent:
411
source_repository = None
413
add_cleanup(source_repository.lock_read().unlock)
415
add_cleanup(source_branch.lock_read().unlock)
416
return source_branch, source_repository
418
def sprout(self, url, revision_id=None, force_new_repo=False,
419
recurse='down', possible_transports=None,
420
accelerator_tree=None, hardlink=False, stacked=False,
421
source_branch=None, create_tree_if_local=True):
422
"""Create a copy of this controldir prepared for use as a new line of
425
If url's last component does not exist, it will be created.
427
Attributes related to the identity of the source branch like
428
branch nickname will be cleaned, a working tree is created
429
whether one existed before or not; and a local branch is always
432
if revision_id is not None, then the clone operation may tune
433
itself to download less data.
434
:param accelerator_tree: A tree which can be used for retrieving file
435
contents more quickly than the revision tree, i.e. a workingtree.
436
The revision tree will be used for cases where accelerator_tree's
437
content is different.
438
:param hardlink: If true, hard-link files from accelerator_tree,
440
:param stacked: If true, create a stacked branch referring to the
441
location of this control directory.
442
:param create_tree_if_local: If true, a working-tree will be created
443
when working locally.
445
operation = cleanup.OperationWithCleanups(self._sprout)
446
return operation.run(url, revision_id=revision_id,
447
force_new_repo=force_new_repo, recurse=recurse,
448
possible_transports=possible_transports,
449
accelerator_tree=accelerator_tree, hardlink=hardlink,
450
stacked=stacked, source_branch=source_branch,
451
create_tree_if_local=create_tree_if_local)
453
def _sprout(self, op, url, revision_id=None, force_new_repo=False,
454
recurse='down', possible_transports=None,
455
accelerator_tree=None, hardlink=False, stacked=False,
456
source_branch=None, create_tree_if_local=True):
457
add_cleanup = op.add_cleanup
458
fetch_spec_factory = fetch.FetchSpecFactory()
459
if revision_id is not None:
460
fetch_spec_factory.add_revision_ids([revision_id])
461
fetch_spec_factory.source_branch_stop_revision_id = revision_id
462
target_transport = _mod_transport.get_transport(url,
464
target_transport.ensure_base()
465
cloning_format = self.cloning_metadir(stacked)
466
# Create/update the result branch
467
result = cloning_format.initialize_on_transport(target_transport)
468
source_branch, source_repository = self._find_source_repo(
469
add_cleanup, source_branch)
470
fetch_spec_factory.source_branch = source_branch
471
# if a stacked branch wasn't requested, we don't create one
472
# even if the origin was stacked
473
if stacked and source_branch is not None:
474
stacked_branch_url = self.root_transport.base
476
stacked_branch_url = None
477
repository_policy = result.determine_repository_policy(
478
force_new_repo, stacked_branch_url, require_stacking=stacked)
479
result_repo, is_new_repo = repository_policy.acquire_repository()
480
add_cleanup(result_repo.lock_write().unlock)
481
fetch_spec_factory.source_repo = source_repository
482
fetch_spec_factory.target_repo = result_repo
483
if stacked or (len(result_repo._fallback_repositories) != 0):
484
target_repo_kind = fetch.TargetRepoKinds.STACKED
486
target_repo_kind = fetch.TargetRepoKinds.EMPTY
488
target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
489
fetch_spec_factory.target_repo_kind = target_repo_kind
490
if source_repository is not None:
491
fetch_spec = fetch_spec_factory.make_fetch_spec()
492
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
494
if source_branch is None:
495
# this is for sprouting a controldir without a branch; is that
497
# Not especially, but it's part of the contract.
498
result_branch = result.create_branch()
500
result_branch = source_branch.sprout(result,
501
revision_id=revision_id, repository_policy=repository_policy,
502
repository=result_repo)
503
mutter("created new branch %r" % (result_branch,))
505
# Create/update the result working tree
506
if (create_tree_if_local and
507
isinstance(target_transport, local.LocalTransport) and
508
(result_repo is None or result_repo.make_working_trees())):
509
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
510
hardlink=hardlink, from_branch=result_branch)
513
if wt.path2id('') is None:
515
wt.set_root_id(self.open_workingtree.get_root_id())
516
except errors.NoWorkingTree:
522
if recurse == 'down':
525
basis = wt.basis_tree()
526
elif result_branch is not None:
527
basis = result_branch.basis_tree()
528
elif source_branch is not None:
529
basis = source_branch.basis_tree()
530
if basis is not None:
531
add_cleanup(basis.lock_read().unlock)
532
subtrees = basis.iter_references()
535
for path, file_id in subtrees:
536
target = urlutils.join(url, urlutils.escape(path))
537
sublocation = source_branch.reference_parent(file_id, path)
538
sublocation.bzrdir.sprout(target,
539
basis.get_reference_revision(file_id, path),
540
force_new_repo=force_new_repo, recurse=recurse,
547
def create_branch_convenience(base, force_new_repo=False,
548
force_new_tree=None, format=None,
549
possible_transports=None):
550
"""Create a new BzrDir, Branch and Repository at the url 'base'.
552
This is a convenience function - it will use an existing repository
553
if possible, can be told explicitly whether to create a working tree or
556
This will use the current default BzrDirFormat unless one is
557
specified, and use whatever
558
repository format that that uses via bzrdir.create_branch and
559
create_repository. If a shared repository is available that is used
560
preferentially. Whatever repository is used, its tree creation policy
563
The created Branch object is returned.
564
If a working tree cannot be made due to base not being a file:// url,
565
no error is raised unless force_new_tree is True, in which case no
566
data is created on disk and NotLocalUrl is raised.
568
:param base: The URL to create the branch at.
569
:param force_new_repo: If True a new repository is always created.
570
:param force_new_tree: If True or False force creation of a tree or
571
prevent such creation respectively.
572
:param format: Override for the bzrdir format to create.
573
:param possible_transports: An optional reusable transports list.
576
# check for non local urls
577
t = _mod_transport.get_transport(base, possible_transports)
578
if not isinstance(t, local.LocalTransport):
579
raise errors.NotLocalUrl(base)
580
bzrdir = BzrDir.create(base, format, possible_transports)
581
repo = bzrdir._find_or_create_repository(force_new_repo)
582
result = bzrdir.create_branch()
583
if force_new_tree or (repo.make_working_trees() and
584
force_new_tree is None):
586
bzrdir.create_workingtree()
587
except errors.NotLocalUrl:
592
def create_standalone_workingtree(base, format=None):
593
"""Create a new BzrDir, WorkingTree, Branch and Repository at 'base'.
595
'base' must be a local path or a file:// url.
597
This will use the current default BzrDirFormat unless one is
598
specified, and use whatever
599
repository format that that uses for bzrdirformat.create_workingtree,
600
create_branch and create_repository.
602
:param format: Override for the bzrdir format to create.
603
:return: The WorkingTree object.
605
t = _mod_transport.get_transport(base)
606
if not isinstance(t, local.LocalTransport):
607
raise errors.NotLocalUrl(base)
608
bzrdir = BzrDir.create_branch_and_repo(base,
610
format=format).bzrdir
611
return bzrdir.create_workingtree()
613
@deprecated_method(deprecated_in((2, 3, 0)))
614
def generate_backup_name(self, base):
615
return self._available_backup_name(base)
617
def _available_backup_name(self, base):
618
"""Find a non-existing backup file name based on base.
620
See bzrlib.osutils.available_backup_name about race conditions.
622
return osutils.available_backup_name(base, self.root_transport.has)
624
def backup_bzrdir(self):
625
"""Backup this bzr control directory.
627
:return: Tuple with old path name and new path name
630
pb = ui.ui_factory.nested_progress_bar()
632
old_path = self.root_transport.abspath('.bzr')
633
backup_dir = self._available_backup_name('backup.bzr')
634
new_path = self.root_transport.abspath(backup_dir)
635
ui.ui_factory.note('making backup of %s\n to %s'
636
% (old_path, new_path,))
637
self.root_transport.copy_tree('.bzr', backup_dir)
638
return (old_path, new_path)
642
def retire_bzrdir(self, limit=10000):
643
"""Permanently disable the bzrdir.
645
This is done by renaming it to give the user some ability to recover
646
if there was a problem.
648
This will have horrible consequences if anyone has anything locked or
650
:param limit: number of times to retry
655
to_path = '.bzr.retired.%d' % i
656
self.root_transport.rename('.bzr', to_path)
657
note("renamed %s to %s"
658
% (self.root_transport.abspath('.bzr'), to_path))
660
except (errors.TransportError, IOError, errors.PathError):
667
def _find_containing(self, evaluate):
668
"""Find something in a containing control directory.
670
This method will scan containing control dirs, until it finds what
671
it is looking for, decides that it will never find it, or runs out
672
of containing control directories to check.
674
It is used to implement find_repository and
675
determine_repository_policy.
677
:param evaluate: A function returning (value, stop). If stop is True,
678
the value will be returned.
682
result, stop = evaluate(found_bzrdir)
685
next_transport = found_bzrdir.root_transport.clone('..')
686
if (found_bzrdir.user_url == next_transport.base):
687
# top of the file system
689
# find the next containing bzrdir
691
found_bzrdir = BzrDir.open_containing_from_transport(
693
except errors.NotBranchError:
696
def find_repository(self):
697
"""Find the repository that should be used.
699
This does not require a branch as we use it to find the repo for
700
new branches as well as to hook existing branches up to their
703
def usable_repository(found_bzrdir):
704
# does it have a repository ?
706
repository = found_bzrdir.open_repository()
707
except errors.NoRepositoryPresent:
709
if found_bzrdir.user_url == self.user_url:
710
return repository, True
711
elif repository.is_shared():
712
return repository, True
716
found_repo = self._find_containing(usable_repository)
717
if found_repo is None:
718
raise errors.NoRepositoryPresent(self)
721
def _find_creation_modes(self):
722
"""Determine the appropriate modes for files and directories.
724
They're always set to be consistent with the base directory,
725
assuming that this transport allows setting modes.
727
# TODO: Do we need or want an option (maybe a config setting) to turn
728
# this off or override it for particular locations? -- mbp 20080512
729
if self._mode_check_done:
731
self._mode_check_done = True
733
st = self.transport.stat('.')
734
except errors.TransportNotPossible:
735
self._dir_mode = None
736
self._file_mode = None
738
# Check the directory mode, but also make sure the created
739
# directories and files are read-write for this user. This is
740
# mostly a workaround for filesystems which lie about being able to
741
# write to a directory (cygwin & win32)
742
if (st.st_mode & 07777 == 00000):
743
# FTP allows stat but does not return dir/file modes
744
self._dir_mode = None
745
self._file_mode = None
747
self._dir_mode = (st.st_mode & 07777) | 00700
748
# Remove the sticky and execute bits for files
749
self._file_mode = self._dir_mode & ~07111
751
def _get_file_mode(self):
752
"""Return Unix mode for newly created files, or None.
754
if not self._mode_check_done:
755
self._find_creation_modes()
756
return self._file_mode
758
def _get_dir_mode(self):
759
"""Return Unix mode for newly created directories, or None.
761
if not self._mode_check_done:
762
self._find_creation_modes()
763
return self._dir_mode
765
def get_config(self):
766
"""Get configuration for this BzrDir."""
767
return config.BzrDirConfig(self)
769
def _get_config(self):
770
"""By default, no configuration is available."""
773
def __init__(self, _transport, _format):
774
"""Initialize a Bzr control dir object.
776
Only really common logic should reside here, concrete classes should be
777
made with varying behaviours.
779
:param _format: the format that is creating this BzrDir instance.
780
:param _transport: the transport this dir is based at.
782
self._format = _format
783
# these are also under the more standard names of
784
# control_transport and user_transport
785
self.transport = _transport.clone('.bzr')
786
self.root_transport = _transport
787
self._mode_check_done = False
790
def user_transport(self):
791
return self.root_transport
794
def control_transport(self):
795
return self.transport
797
def is_control_filename(self, filename):
798
"""True if filename is the name of a path which is reserved for bzrdir's.
800
:param filename: A filename within the root transport of this bzrdir.
802
This is true IF and ONLY IF the filename is part of the namespace reserved
803
for bzr control dirs. Currently this is the '.bzr' directory in the root
804
of the root_transport.
806
# this might be better on the BzrDirFormat class because it refers to
807
# all the possible bzrdir disk formats.
808
# This method is tested via the workingtree is_control_filename tests-
809
# it was extracted from WorkingTree.is_control_filename. If the method's
810
# contract is extended beyond the current trivial implementation, please
811
# add new tests for it to the appropriate place.
812
return filename == '.bzr' or filename.startswith('.bzr/')
815
def open_unsupported(base):
816
"""Open a branch which is not supported."""
817
return BzrDir.open(base, _unsupported=True)
820
def open(base, _unsupported=False, possible_transports=None):
821
"""Open an existing bzrdir, rooted at 'base' (url).
823
:param _unsupported: a private parameter to the BzrDir class.
825
t = _mod_transport.get_transport(base, possible_transports)
826
return BzrDir.open_from_transport(t, _unsupported=_unsupported)
829
def open_from_transport(transport, _unsupported=False,
830
_server_formats=True):
831
"""Open a bzrdir within a particular directory.
833
:param transport: Transport containing the bzrdir.
834
:param _unsupported: private.
836
for hook in BzrDir.hooks['pre_open']:
838
# Keep initial base since 'transport' may be modified while following
840
base = transport.base
841
def find_format(transport):
842
return transport, controldir.ControlDirFormat.find_format(
843
transport, _server_formats=_server_formats)
845
def redirected(transport, e, redirection_notice):
846
redirected_transport = transport._redirected_to(e.source, e.target)
847
if redirected_transport is None:
848
raise errors.NotBranchError(base)
849
note('%s is%s redirected to %s',
850
transport.base, e.permanently, redirected_transport.base)
851
return redirected_transport
854
transport, format = do_catching_redirections(find_format,
857
except errors.TooManyRedirections:
858
raise errors.NotBranchError(base)
860
format.check_support_status(_unsupported)
861
return format.open(transport, _found=True)
864
def open_containing(url, possible_transports=None):
865
"""Open an existing branch which contains url.
867
:param url: url to search from.
868
See open_containing_from_transport for more detail.
870
transport = _mod_transport.get_transport(url, possible_transports)
871
return BzrDir.open_containing_from_transport(transport)
874
def open_containing_from_transport(a_transport):
875
"""Open an existing branch which contains a_transport.base.
877
This probes for a branch at a_transport, and searches upwards from there.
879
Basically we keep looking up until we find the control directory or
880
run into the root. If there isn't one, raises NotBranchError.
881
If there is one and it is either an unrecognised format or an unsupported
882
format, UnknownFormatError or UnsupportedFormatError are raised.
883
If there is one, it is returned, along with the unused portion of url.
885
:return: The BzrDir that contains the path, and a Unicode path
886
for the rest of the URL.
888
# this gets the normalised url back. I.e. '.' -> the full path.
889
url = a_transport.base
892
result = BzrDir.open_from_transport(a_transport)
893
return result, urlutils.unescape(a_transport.relpath(url))
894
except errors.NotBranchError, e:
897
new_t = a_transport.clone('..')
898
except errors.InvalidURLJoin:
899
# reached the root, whatever that may be
900
raise errors.NotBranchError(path=url)
901
if new_t.base == a_transport.base:
902
# reached the root, whatever that may be
903
raise errors.NotBranchError(path=url)
907
def open_tree_or_branch(klass, location):
908
"""Return the branch and working tree at a location.
910
If there is no tree at the location, tree will be None.
911
If there is no branch at the location, an exception will be
913
:return: (tree, branch)
915
bzrdir = klass.open(location)
916
return bzrdir._get_tree_branch()
919
def open_containing_tree_or_branch(klass, location):
920
"""Return the branch and working tree contained by a location.
922
Returns (tree, branch, relpath).
923
If there is no tree at containing the location, tree will be None.
924
If there is no branch containing the location, an exception will be
926
relpath is the portion of the path that is contained by the branch.
928
bzrdir, relpath = klass.open_containing(location)
929
tree, branch = bzrdir._get_tree_branch()
930
return tree, branch, relpath
933
def open_containing_tree_branch_or_repository(klass, location):
934
"""Return the working tree, branch and repo contained by a location.
936
Returns (tree, branch, repository, relpath).
937
If there is no tree containing the location, tree will be None.
938
If there is no branch containing the location, branch will be None.
939
If there is no repository containing the location, repository will be
941
relpath is the portion of the path that is contained by the innermost
944
If no tree, branch or repository is found, a NotBranchError is raised.
946
bzrdir, relpath = klass.open_containing(location)
948
tree, branch = bzrdir._get_tree_branch()
949
except errors.NotBranchError:
951
repo = bzrdir.find_repository()
952
return None, None, repo, relpath
953
except (errors.NoRepositoryPresent):
954
raise errors.NotBranchError(location)
955
return tree, branch, branch.repository, relpath
957
def _cloning_metadir(self):
958
"""Produce a metadir suitable for cloning with.
960
:returns: (destination_bzrdir_format, source_repository)
962
result_format = self._format.__class__()
965
branch = self.open_branch(ignore_fallbacks=True)
966
source_repository = branch.repository
967
result_format._branch_format = branch._format
968
except errors.NotBranchError:
970
source_repository = self.open_repository()
971
except errors.NoRepositoryPresent:
972
source_repository = None
974
# XXX TODO: This isinstance is here because we have not implemented
975
# the fix recommended in bug # 103195 - to delegate this choice the
977
repo_format = source_repository._format
978
if isinstance(repo_format, remote.RemoteRepositoryFormat):
979
source_repository._ensure_real()
980
repo_format = source_repository._real_repository._format
981
result_format.repository_format = repo_format
983
# TODO: Couldn't we just probe for the format in these cases,
984
# rather than opening the whole tree? It would be a little
985
# faster. mbp 20070401
986
tree = self.open_workingtree(recommend_upgrade=False)
987
except (errors.NoWorkingTree, errors.NotLocalUrl):
988
result_format.workingtree_format = None
990
result_format.workingtree_format = tree._format.__class__()
991
return result_format, source_repository
993
def cloning_metadir(self, require_stacking=False):
994
"""Produce a metadir suitable for cloning or sprouting with.
996
These operations may produce workingtrees (yes, even though they're
997
"cloning" something that doesn't have a tree), so a viable workingtree
998
format must be selected.
1000
:require_stacking: If True, non-stackable formats will be upgraded
1001
to similar stackable formats.
1002
:returns: a BzrDirFormat with all component formats either set
1003
appropriately or set to None if that component should not be
1006
format, repository = self._cloning_metadir()
1007
if format._workingtree_format is None:
1009
if repository is None:
1010
# No repository either
1012
# We have a repository, so set a working tree? (Why? This seems to
1013
# contradict the stated return value in the docstring).
1014
tree_format = repository._format._matchingbzrdir.workingtree_format
1015
format.workingtree_format = tree_format.__class__()
1016
if require_stacking:
1017
format.require_stacking()
1021
def create(cls, base, format=None, possible_transports=None):
1022
"""Create a new BzrDir at the url 'base'.
1024
:param format: If supplied, the format of branch to create. If not
1025
supplied, the default is used.
1026
:param possible_transports: If supplied, a list of transports that
1027
can be reused to share a remote connection.
1029
if cls is not BzrDir:
1030
raise AssertionError("BzrDir.create always creates the"
1031
"default format, not one of %r" % cls)
1032
t = _mod_transport.get_transport(base, possible_transports)
1035
format = controldir.ControlDirFormat.get_default_format()
1036
return format.initialize_on_transport(t)
1038
def get_branch_transport(self, branch_format, name=None):
1039
"""Get the transport for use by branch format in this BzrDir.
1041
Note that bzr dirs that do not support format strings will raise
1042
IncompatibleFormat if the branch format they are given has
1043
a format string, and vice versa.
1045
If branch_format is None, the transport is returned with no
1046
checking. If it is not None, then the returned transport is
1047
guaranteed to point to an existing directory ready for use.
1049
raise NotImplementedError(self.get_branch_transport)
1051
def get_repository_transport(self, repository_format):
1052
"""Get the transport for use by repository format in this BzrDir.
1054
Note that bzr dirs that do not support format strings will raise
1055
IncompatibleFormat if the repository format they are given has
1056
a format string, and vice versa.
1058
If repository_format is None, the transport is returned with no
1059
checking. If it is not None, then the returned transport is
1060
guaranteed to point to an existing directory ready for use.
1062
raise NotImplementedError(self.get_repository_transport)
1064
def get_workingtree_transport(self, tree_format):
1065
"""Get the transport for use by workingtree format in this BzrDir.
1067
Note that bzr dirs that do not support format strings will raise
1068
IncompatibleFormat if the workingtree format they are given has a
1069
format string, and vice versa.
1071
If workingtree_format is None, the transport is returned with no
1072
checking. If it is not None, then the returned transport is
1073
guaranteed to point to an existing directory ready for use.
1075
raise NotImplementedError(self.get_workingtree_transport)
1078
class BzrDirHooks(hooks.Hooks):
1079
"""Hooks for BzrDir operations."""
1082
"""Create the default hooks."""
1083
hooks.Hooks.__init__(self, "bzrlib.bzrdir", "BzrDir.hooks")
1084
self.add_hook('pre_open',
1085
"Invoked before attempting to open a BzrDir with the transport "
1086
"that the open will use.", (1, 14))
1087
self.add_hook('post_repo_init',
1088
"Invoked after a repository has been initialized. "
1089
"post_repo_init is called with a "
1090
"bzrlib.bzrdir.RepoInitHookParams.",
1093
# install the default hooks
1094
BzrDir.hooks = BzrDirHooks()
1097
class RepoInitHookParams(object):
1098
"""Object holding parameters passed to *_repo_init hooks.
1100
There are 4 fields that hooks may wish to access:
1102
:ivar repository: Repository created
1103
:ivar format: Repository format
1104
:ivar bzrdir: The bzrdir for the repository
1105
:ivar shared: The repository is shared
1108
def __init__(self, repository, format, a_bzrdir, shared):
1109
"""Create a group of RepoInitHook parameters.
1111
:param repository: Repository created
1112
:param format: Repository format
1113
:param bzrdir: The bzrdir for the repository
1114
:param shared: The repository is shared
1116
self.repository = repository
1117
self.format = format
1118
self.bzrdir = a_bzrdir
1119
self.shared = shared
1121
def __eq__(self, other):
1122
return self.__dict__ == other.__dict__
1126
return "<%s for %s>" % (self.__class__.__name__,
1129
return "<%s for %s>" % (self.__class__.__name__,
1133
class BzrDirMeta1(BzrDir):
1134
"""A .bzr meta version 1 control object.
1136
This is the first control object where the
1137
individual aspects are really split out: there are separate repository,
1138
workingtree and branch subdirectories and any subset of the three can be
1139
present within a BzrDir.
1142
def can_convert_format(self):
1143
"""See BzrDir.can_convert_format()."""
1146
def create_branch(self, name=None, repository=None):
1147
"""See BzrDir.create_branch."""
1148
return self._format.get_branch_format().initialize(self, name=name,
1149
repository=repository)
1151
def destroy_branch(self, name=None):
1152
"""See BzrDir.create_branch."""
1153
if name is not None:
1154
raise errors.NoColocatedBranchSupport(self)
1155
self.transport.delete_tree('branch')
1157
def create_repository(self, shared=False):
1158
"""See BzrDir.create_repository."""
1159
return self._format.repository_format.initialize(self, shared)
1161
def destroy_repository(self):
1162
"""See BzrDir.destroy_repository."""
1163
self.transport.delete_tree('repository')
1165
def create_workingtree(self, revision_id=None, from_branch=None,
1166
accelerator_tree=None, hardlink=False):
1167
"""See BzrDir.create_workingtree."""
1168
return self._format.workingtree_format.initialize(
1169
self, revision_id, from_branch=from_branch,
1170
accelerator_tree=accelerator_tree, hardlink=hardlink)
1172
def destroy_workingtree(self):
1173
"""See BzrDir.destroy_workingtree."""
1174
wt = self.open_workingtree(recommend_upgrade=False)
1175
repository = wt.branch.repository
1176
empty = repository.revision_tree(_mod_revision.NULL_REVISION)
1177
# We ignore the conflicts returned by wt.revert since we're about to
1178
# delete the wt metadata anyway, all that should be left here are
1179
# detritus. But see bug #634470 about subtree .bzr dirs.
1180
conflicts = wt.revert(old_tree=empty)
1181
self.destroy_workingtree_metadata()
1183
def destroy_workingtree_metadata(self):
1184
self.transport.delete_tree('checkout')
1186
def find_branch_format(self, name=None):
1187
"""Find the branch 'format' for this bzrdir.
1189
This might be a synthetic object for e.g. RemoteBranch and SVN.
1191
from bzrlib.branch import BranchFormat
1192
return BranchFormat.find_format(self, name=name)
1194
def _get_mkdir_mode(self):
1195
"""Figure out the mode to use when creating a bzrdir subdir."""
1196
temp_control = lockable_files.LockableFiles(self.transport, '',
1197
lockable_files.TransportLock)
1198
return temp_control._dir_mode
1200
def get_branch_reference(self, name=None):
1201
"""See BzrDir.get_branch_reference()."""
1202
from bzrlib.branch import BranchFormat
1203
format = BranchFormat.find_format(self, name=name)
1204
return format.get_reference(self, name=name)
1206
def get_branch_transport(self, branch_format, name=None):
1207
"""See BzrDir.get_branch_transport()."""
1208
if name is not None:
1209
raise errors.NoColocatedBranchSupport(self)
1210
# XXX: this shouldn't implicitly create the directory if it's just
1211
# promising to get a transport -- mbp 20090727
1212
if branch_format is None:
1213
return self.transport.clone('branch')
1215
branch_format.get_format_string()
1216
except NotImplementedError:
1217
raise errors.IncompatibleFormat(branch_format, self._format)
1219
self.transport.mkdir('branch', mode=self._get_mkdir_mode())
1220
except errors.FileExists:
1222
return self.transport.clone('branch')
1224
def get_repository_transport(self, repository_format):
1225
"""See BzrDir.get_repository_transport()."""
1226
if repository_format is None:
1227
return self.transport.clone('repository')
1229
repository_format.get_format_string()
1230
except NotImplementedError:
1231
raise errors.IncompatibleFormat(repository_format, self._format)
1233
self.transport.mkdir('repository', mode=self._get_mkdir_mode())
1234
except errors.FileExists:
1236
return self.transport.clone('repository')
1238
def get_workingtree_transport(self, workingtree_format):
1239
"""See BzrDir.get_workingtree_transport()."""
1240
if workingtree_format is None:
1241
return self.transport.clone('checkout')
1243
workingtree_format.get_format_string()
1244
except NotImplementedError:
1245
raise errors.IncompatibleFormat(workingtree_format, self._format)
1247
self.transport.mkdir('checkout', mode=self._get_mkdir_mode())
1248
except errors.FileExists:
1250
return self.transport.clone('checkout')
1252
def has_workingtree(self):
1253
"""Tell if this bzrdir contains a working tree.
1255
Note: if you're going to open the working tree, you should just go
1256
ahead and try, and not ask permission first.
1258
from bzrlib.workingtree import WorkingTreeFormat
1260
WorkingTreeFormat.find_format_string(self)
1261
except errors.NoWorkingTree:
1265
def needs_format_conversion(self, format):
1266
"""See BzrDir.needs_format_conversion()."""
1267
if not isinstance(self._format, format.__class__):
1268
# it is not a meta dir format, conversion is needed.
1270
# we might want to push this down to the repository?
1272
if not isinstance(self.open_repository()._format,
1273
format.repository_format.__class__):
1274
# the repository needs an upgrade.
1276
except errors.NoRepositoryPresent:
1278
for branch in self.list_branches():
1279
if not isinstance(branch._format,
1280
format.get_branch_format().__class__):
1281
# the branch needs an upgrade.
1284
my_wt = self.open_workingtree(recommend_upgrade=False)
1285
if not isinstance(my_wt._format,
1286
format.workingtree_format.__class__):
1287
# the workingtree needs an upgrade.
1289
except (errors.NoWorkingTree, errors.NotLocalUrl):
1293
def open_branch(self, name=None, unsupported=False,
1294
ignore_fallbacks=False):
1295
"""See BzrDir.open_branch."""
1296
format = self.find_branch_format(name=name)
1297
format.check_support_status(unsupported)
1298
return format.open(self, name=name,
1299
_found=True, ignore_fallbacks=ignore_fallbacks)
1301
def open_repository(self, unsupported=False):
1302
"""See BzrDir.open_repository."""
1303
from bzrlib.repository import RepositoryFormat
1304
format = RepositoryFormat.find_format(self)
1305
format.check_support_status(unsupported)
1306
return format.open(self, _found=True)
1308
def open_workingtree(self, unsupported=False,
1309
recommend_upgrade=True):
1310
"""See BzrDir.open_workingtree."""
1311
from bzrlib.workingtree import WorkingTreeFormat
1312
format = WorkingTreeFormat.find_format(self)
1313
format.check_support_status(unsupported, recommend_upgrade,
1314
basedir=self.root_transport.base)
1315
return format.open(self, _found=True)
1317
def _get_config(self):
1318
return config.TransportConfig(self.transport, 'control.conf')
1321
class BzrProber(controldir.Prober):
1322
"""Prober for formats that use a .bzr/ control directory."""
1324
formats = registry.FormatRegistry(controldir.network_format_registry)
1325
"""The known .bzr formats."""
1328
@deprecated_method(deprecated_in((2, 4, 0)))
1329
def register_bzrdir_format(klass, format):
1330
klass.formats.register(format.get_format_string(), format)
1333
@deprecated_method(deprecated_in((2, 4, 0)))
1334
def unregister_bzrdir_format(klass, format):
1335
klass.formats.remove(format.get_format_string())
1338
def probe_transport(klass, transport):
1339
"""Return the .bzrdir style format present in a directory."""
1341
format_string = transport.get_bytes(".bzr/branch-format")
1342
except errors.NoSuchFile:
1343
raise errors.NotBranchError(path=transport.base)
1345
return klass.formats.get(format_string)
1347
raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
1350
def known_formats(cls):
1352
for name, format in cls.formats.iteritems():
1353
if callable(format):
1359
controldir.ControlDirFormat.register_prober(BzrProber)
1362
class RemoteBzrProber(controldir.Prober):
1363
"""Prober for remote servers that provide a Bazaar smart server."""
1366
def probe_transport(klass, transport):
1367
"""Return a RemoteBzrDirFormat object if it looks possible."""
1369
medium = transport.get_smart_medium()
1370
except (NotImplementedError, AttributeError,
1371
errors.TransportNotPossible, errors.NoSmartMedium,
1372
errors.SmartProtocolError):
1373
# no smart server, so not a branch for this format type.
1374
raise errors.NotBranchError(path=transport.base)
1376
# Decline to open it if the server doesn't support our required
1377
# version (3) so that the VFS-based transport will do it.
1378
if medium.should_probe():
1380
server_version = medium.protocol_version()
1381
except errors.SmartProtocolError:
1382
# Apparently there's no usable smart server there, even though
1383
# the medium supports the smart protocol.
1384
raise errors.NotBranchError(path=transport.base)
1385
if server_version != '2':
1386
raise errors.NotBranchError(path=transport.base)
1387
from bzrlib.remote import RemoteBzrDirFormat
1388
return RemoteBzrDirFormat()
1391
def known_formats(cls):
1392
from bzrlib.remote import RemoteBzrDirFormat
1393
return set([RemoteBzrDirFormat()])
1396
class BzrDirFormat(controldir.ControlDirFormat):
1397
"""ControlDirFormat base class for .bzr/ directories.
1399
Formats are placed in a dict by their format string for reference
1400
during bzrdir opening. These should be subclasses of BzrDirFormat
1403
Once a format is deprecated, just deprecate the initialize and open
1404
methods on the format class. Do not deprecate the object, as the
1405
object will be created every system load.
1408
_lock_file_name = 'branch-lock'
1410
# _lock_class must be set in subclasses to the lock type, typ.
1411
# TransportLock or LockDir
1414
def get_format_string(cls):
1415
"""Return the ASCII format string that identifies this format."""
1416
raise NotImplementedError(self.get_format_string)
1418
def initialize_on_transport(self, transport):
1419
"""Initialize a new bzrdir in the base directory of a Transport."""
1421
# can we hand off the request to the smart server rather than using
1423
client_medium = transport.get_smart_medium()
1424
except errors.NoSmartMedium:
1425
return self._initialize_on_transport_vfs(transport)
1427
# Current RPC's only know how to create bzr metadir1 instances, so
1428
# we still delegate to vfs methods if the requested format is not a
1430
if type(self) != BzrDirMetaFormat1:
1431
return self._initialize_on_transport_vfs(transport)
1432
from bzrlib.remote import RemoteBzrDirFormat
1433
remote_format = RemoteBzrDirFormat()
1434
self._supply_sub_formats_to(remote_format)
1435
return remote_format.initialize_on_transport(transport)
1437
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1438
create_prefix=False, force_new_repo=False, stacked_on=None,
1439
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1440
shared_repo=False, vfs_only=False):
1441
"""Create this format on transport.
1443
The directory to initialize will be created.
1445
:param force_new_repo: Do not use a shared repository for the target,
1446
even if one is available.
1447
:param create_prefix: Create any missing directories leading up to
1449
:param use_existing_dir: Use an existing directory if one exists.
1450
:param stacked_on: A url to stack any created branch on, None to follow
1451
any target stacking policy.
1452
:param stack_on_pwd: If stack_on is relative, the location it is
1454
:param repo_format_name: If non-None, a repository will be
1455
made-or-found. Should none be found, or if force_new_repo is True
1456
the repo_format_name is used to select the format of repository to
1458
:param make_working_trees: Control the setting of make_working_trees
1459
for a new shared repository when one is made. None to use whatever
1460
default the format has.
1461
:param shared_repo: Control whether made repositories are shared or
1463
:param vfs_only: If True do not attempt to use a smart server
1464
:return: repo, bzrdir, require_stacking, repository_policy. repo is
1465
None if none was created or found, bzrdir is always valid.
1466
require_stacking is the result of examining the stacked_on
1467
parameter and any stacking policy found for the target.
1470
# Try to hand off to a smart server
1472
client_medium = transport.get_smart_medium()
1473
except errors.NoSmartMedium:
1476
from bzrlib.remote import RemoteBzrDirFormat
1477
# TODO: lookup the local format from a server hint.
1478
remote_dir_format = RemoteBzrDirFormat()
1479
remote_dir_format._network_name = self.network_name()
1480
self._supply_sub_formats_to(remote_dir_format)
1481
return remote_dir_format.initialize_on_transport_ex(transport,
1482
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1483
force_new_repo=force_new_repo, stacked_on=stacked_on,
1484
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1485
make_working_trees=make_working_trees, shared_repo=shared_repo)
1486
# XXX: Refactor the create_prefix/no_create_prefix code into a
1487
# common helper function
1488
# The destination may not exist - if so make it according to policy.
1489
def make_directory(transport):
1490
transport.mkdir('.')
1492
def redirected(transport, e, redirection_notice):
1493
note(redirection_notice)
1494
return transport._redirected_to(e.source, e.target)
1496
transport = do_catching_redirections(make_directory, transport,
1498
except errors.FileExists:
1499
if not use_existing_dir:
1501
except errors.NoSuchFile:
1502
if not create_prefix:
1504
transport.create_prefix()
1506
require_stacking = (stacked_on is not None)
1507
# Now the target directory exists, but doesn't have a .bzr
1508
# directory. So we need to create it, along with any work to create
1509
# all of the dependent branches, etc.
1511
result = self.initialize_on_transport(transport)
1512
if repo_format_name:
1514
# use a custom format
1515
result._format.repository_format = \
1516
repository.network_format_registry.get(repo_format_name)
1517
except AttributeError:
1518
# The format didn't permit it to be set.
1520
# A repository is desired, either in-place or shared.
1521
repository_policy = result.determine_repository_policy(
1522
force_new_repo, stacked_on, stack_on_pwd,
1523
require_stacking=require_stacking)
1524
result_repo, is_new_repo = repository_policy.acquire_repository(
1525
make_working_trees, shared_repo)
1526
if not require_stacking and repository_policy._require_stacking:
1527
require_stacking = True
1528
result._format.require_stacking()
1529
result_repo.lock_write()
1532
repository_policy = None
1533
return result_repo, result, require_stacking, repository_policy
1535
def _initialize_on_transport_vfs(self, transport):
1536
"""Initialize a new bzrdir using VFS calls.
1538
:param transport: The transport to create the .bzr directory in.
1541
# Since we are creating a .bzr directory, inherit the
1542
# mode from the root directory
1543
temp_control = lockable_files.LockableFiles(transport,
1544
'', lockable_files.TransportLock)
1545
temp_control._transport.mkdir('.bzr',
1546
# FIXME: RBC 20060121 don't peek under
1548
mode=temp_control._dir_mode)
1549
if sys.platform == 'win32' and isinstance(transport, local.LocalTransport):
1550
win32utils.set_file_attr_hidden(transport._abspath('.bzr'))
1551
file_mode = temp_control._file_mode
1553
bzrdir_transport = transport.clone('.bzr')
1554
utf8_files = [('README',
1555
"This is a Bazaar control directory.\n"
1556
"Do not change any files in this directory.\n"
1557
"See http://bazaar.canonical.com/ for more information about Bazaar.\n"),
1558
('branch-format', self.get_format_string()),
1560
# NB: no need to escape relative paths that are url safe.
1561
control_files = lockable_files.LockableFiles(bzrdir_transport,
1562
self._lock_file_name, self._lock_class)
1563
control_files.create_lock()
1564
control_files.lock_write()
1566
for (filename, content) in utf8_files:
1567
bzrdir_transport.put_bytes(filename, content,
1570
control_files.unlock()
1571
return self.open(transport, _found=True)
1573
def open(self, transport, _found=False):
1574
"""Return an instance of this format for the dir transport points at.
1576
_found is a private parameter, do not use it.
1579
found_format = controldir.ControlDirFormat.find_format(transport)
1580
if not isinstance(found_format, self.__class__):
1581
raise AssertionError("%s was asked to open %s, but it seems to need "
1583
% (self, transport, found_format))
1584
# Allow subclasses - use the found format.
1585
self._supply_sub_formats_to(found_format)
1586
return found_format._open(transport)
1587
return self._open(transport)
1589
def _open(self, transport):
1590
"""Template method helper for opening BzrDirectories.
1592
This performs the actual open and any additional logic or parameter
1595
raise NotImplementedError(self._open)
1597
def _supply_sub_formats_to(self, other_format):
1598
"""Give other_format the same values for sub formats as this has.
1600
This method is expected to be used when parameterising a
1601
RemoteBzrDirFormat instance with the parameters from a
1602
BzrDirMetaFormat1 instance.
1604
:param other_format: other_format is a format which should be
1605
compatible with whatever sub formats are supported by self.
1610
class BzrDirMetaFormat1(BzrDirFormat):
1611
"""Bzr meta control format 1
1613
This is the first format with split out working tree, branch and repository
1616
- Format 3 working trees [optional]
1617
- Format 5 branches [optional]
1618
- Format 7 repositories [optional]
1621
_lock_class = lockdir.LockDir
1623
fixed_components = False
1626
self._workingtree_format = None
1627
self._branch_format = None
1628
self._repository_format = None
1630
def __eq__(self, other):
1631
if other.__class__ is not self.__class__:
1633
if other.repository_format != self.repository_format:
1635
if other.workingtree_format != self.workingtree_format:
1639
def __ne__(self, other):
1640
return not self == other
1642
def get_branch_format(self):
1643
if self._branch_format is None:
1644
from bzrlib.branch import format_registry as branch_format_registry
1645
self._branch_format = branch_format_registry.get_default()
1646
return self._branch_format
1648
def set_branch_format(self, format):
1649
self._branch_format = format
1651
def require_stacking(self, stack_on=None, possible_transports=None,
1653
"""We have a request to stack, try to ensure the formats support it.
1655
:param stack_on: If supplied, it is the URL to a branch that we want to
1656
stack on. Check to see if that format supports stacking before
1659
# Stacking is desired. requested by the target, but does the place it
1660
# points at support stacking? If it doesn't then we should
1661
# not implicitly upgrade. We check this here.
1662
new_repo_format = None
1663
new_branch_format = None
1665
# a bit of state for get_target_branch so that we don't try to open it
1666
# 2 times, for both repo *and* branch
1667
target = [None, False, None] # target_branch, checked, upgrade anyway
1668
def get_target_branch():
1670
# We've checked, don't check again
1672
if stack_on is None:
1673
# No target format, that means we want to force upgrading
1674
target[:] = [None, True, True]
1677
target_dir = BzrDir.open(stack_on,
1678
possible_transports=possible_transports)
1679
except errors.NotBranchError:
1680
# Nothing there, don't change formats
1681
target[:] = [None, True, False]
1683
except errors.JailBreak:
1684
# JailBreak, JFDI and upgrade anyway
1685
target[:] = [None, True, True]
1688
target_branch = target_dir.open_branch()
1689
except errors.NotBranchError:
1690
# No branch, don't upgrade formats
1691
target[:] = [None, True, False]
1693
target[:] = [target_branch, True, False]
1696
if (not _skip_repo and
1697
not self.repository_format.supports_external_lookups):
1698
# We need to upgrade the Repository.
1699
target_branch, _, do_upgrade = get_target_branch()
1700
if target_branch is None:
1701
# We don't have a target branch, should we upgrade anyway?
1703
# stack_on is inaccessible, JFDI.
1704
# TODO: bad monkey, hard-coded formats...
1705
if self.repository_format.rich_root_data:
1706
new_repo_format = knitpack_repo.RepositoryFormatKnitPack5RichRoot()
1708
new_repo_format = knitpack_repo.RepositoryFormatKnitPack5()
1710
# If the target already supports stacking, then we know the
1711
# project is already able to use stacking, so auto-upgrade
1713
new_repo_format = target_branch.repository._format
1714
if not new_repo_format.supports_external_lookups:
1715
# target doesn't, source doesn't, so don't auto upgrade
1717
new_repo_format = None
1718
if new_repo_format is not None:
1719
self.repository_format = new_repo_format
1720
note('Source repository format does not support stacking,'
1721
' using format:\n %s',
1722
new_repo_format.get_format_description())
1724
if not self.get_branch_format().supports_stacking():
1725
# We just checked the repo, now lets check if we need to
1726
# upgrade the branch format
1727
target_branch, _, do_upgrade = get_target_branch()
1728
if target_branch is None:
1730
# TODO: bad monkey, hard-coded formats...
1731
from bzrlib.branch import BzrBranchFormat7
1732
new_branch_format = BzrBranchFormat7()
1734
new_branch_format = target_branch._format
1735
if not new_branch_format.supports_stacking():
1736
new_branch_format = None
1737
if new_branch_format is not None:
1738
# Does support stacking, use its format.
1739
self.set_branch_format(new_branch_format)
1740
note('Source branch format does not support stacking,'
1741
' using format:\n %s',
1742
new_branch_format.get_format_description())
1744
def get_converter(self, format=None):
1745
"""See BzrDirFormat.get_converter()."""
1747
format = BzrDirFormat.get_default_format()
1748
if not isinstance(self, format.__class__):
1749
# converting away from metadir is not implemented
1750
raise NotImplementedError(self.get_converter)
1751
return ConvertMetaToMeta(format)
1754
def get_format_string(cls):
1755
"""See BzrDirFormat.get_format_string()."""
1756
return "Bazaar-NG meta directory, format 1\n"
1758
def get_format_description(self):
1759
"""See BzrDirFormat.get_format_description()."""
1760
return "Meta directory format 1"
1762
def network_name(self):
1763
return self.get_format_string()
1765
def _open(self, transport):
1766
"""See BzrDirFormat._open."""
1767
# Create a new format instance because otherwise initialisation of new
1768
# metadirs share the global default format object leading to alias
1770
format = BzrDirMetaFormat1()
1771
self._supply_sub_formats_to(format)
1772
return BzrDirMeta1(transport, format)
1774
def __return_repository_format(self):
1775
"""Circular import protection."""
1776
if self._repository_format:
1777
return self._repository_format
1778
from bzrlib.repository import format_registry
1779
return format_registry.get_default()
1781
def _set_repository_format(self, value):
1782
"""Allow changing the repository format for metadir formats."""
1783
self._repository_format = value
1785
repository_format = property(__return_repository_format,
1786
_set_repository_format)
1788
def _supply_sub_formats_to(self, other_format):
1789
"""Give other_format the same values for sub formats as this has.
1791
This method is expected to be used when parameterising a
1792
RemoteBzrDirFormat instance with the parameters from a
1793
BzrDirMetaFormat1 instance.
1795
:param other_format: other_format is a format which should be
1796
compatible with whatever sub formats are supported by self.
1799
if getattr(self, '_repository_format', None) is not None:
1800
other_format.repository_format = self.repository_format
1801
if self._branch_format is not None:
1802
other_format._branch_format = self._branch_format
1803
if self._workingtree_format is not None:
1804
other_format.workingtree_format = self.workingtree_format
1806
def __get_workingtree_format(self):
1807
if self._workingtree_format is None:
1808
from bzrlib.workingtree import (
1809
format_registry as wt_format_registry,
1811
self._workingtree_format = wt_format_registry.get_default()
1812
return self._workingtree_format
1814
def __set_workingtree_format(self, wt_format):
1815
self._workingtree_format = wt_format
1817
workingtree_format = property(__get_workingtree_format,
1818
__set_workingtree_format)
1821
# Register bzr formats
1822
BzrProber.formats.register(BzrDirMetaFormat1.get_format_string(),
1824
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1827
class ConvertMetaToMeta(controldir.Converter):
1828
"""Converts the components of metadirs."""
1830
def __init__(self, target_format):
1831
"""Create a metadir to metadir converter.
1833
:param target_format: The final metadir format that is desired.
1835
self.target_format = target_format
1837
def convert(self, to_convert, pb):
1838
"""See Converter.convert()."""
1839
self.bzrdir = to_convert
1840
self.pb = ui.ui_factory.nested_progress_bar()
1843
self.step('checking repository format')
1845
repo = self.bzrdir.open_repository()
1846
except errors.NoRepositoryPresent:
1849
if not isinstance(repo._format, self.target_format.repository_format.__class__):
1850
from bzrlib.repository import CopyConverter
1851
ui.ui_factory.note('starting repository conversion')
1852
converter = CopyConverter(self.target_format.repository_format)
1853
converter.convert(repo, pb)
1854
for branch in self.bzrdir.list_branches():
1855
# TODO: conversions of Branch and Tree should be done by
1856
# InterXFormat lookups/some sort of registry.
1857
# Avoid circular imports
1858
old = branch._format.__class__
1859
new = self.target_format.get_branch_format().__class__
1861
if (old == _mod_branch.BzrBranchFormat5 and
1862
new in (_mod_branch.BzrBranchFormat6,
1863
_mod_branch.BzrBranchFormat7,
1864
_mod_branch.BzrBranchFormat8)):
1865
branch_converter = _mod_branch.Converter5to6()
1866
elif (old == _mod_branch.BzrBranchFormat6 and
1867
new in (_mod_branch.BzrBranchFormat7,
1868
_mod_branch.BzrBranchFormat8)):
1869
branch_converter = _mod_branch.Converter6to7()
1870
elif (old == _mod_branch.BzrBranchFormat7 and
1871
new is _mod_branch.BzrBranchFormat8):
1872
branch_converter = _mod_branch.Converter7to8()
1874
raise errors.BadConversionTarget("No converter", new,
1876
branch_converter.convert(branch)
1877
branch = self.bzrdir.open_branch()
1878
old = branch._format.__class__
1880
tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
1881
except (errors.NoWorkingTree, errors.NotLocalUrl):
1884
# TODO: conversions of Branch and Tree should be done by
1885
# InterXFormat lookups
1886
if (isinstance(tree, workingtree.WorkingTree3) and
1887
not isinstance(tree, workingtree_4.DirStateWorkingTree) and
1888
isinstance(self.target_format.workingtree_format,
1889
workingtree_4.DirStateWorkingTreeFormat)):
1890
workingtree_4.Converter3to4().convert(tree)
1891
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1892
not isinstance(tree, workingtree_4.WorkingTree5) and
1893
isinstance(self.target_format.workingtree_format,
1894
workingtree_4.WorkingTreeFormat5)):
1895
workingtree_4.Converter4to5().convert(tree)
1896
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1897
not isinstance(tree, workingtree_4.WorkingTree6) and
1898
isinstance(self.target_format.workingtree_format,
1899
workingtree_4.WorkingTreeFormat6)):
1900
workingtree_4.Converter4or5to6().convert(tree)
1905
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
1908
class RepositoryAcquisitionPolicy(object):
1909
"""Abstract base class for repository acquisition policies.
1911
A repository acquisition policy decides how a BzrDir acquires a repository
1912
for a branch that is being created. The most basic policy decision is
1913
whether to create a new repository or use an existing one.
1915
def __init__(self, stack_on, stack_on_pwd, require_stacking):
1918
:param stack_on: A location to stack on
1919
:param stack_on_pwd: If stack_on is relative, the location it is
1921
:param require_stacking: If True, it is a failure to not stack.
1923
self._stack_on = stack_on
1924
self._stack_on_pwd = stack_on_pwd
1925
self._require_stacking = require_stacking
1927
def configure_branch(self, branch):
1928
"""Apply any configuration data from this policy to the branch.
1930
Default implementation sets repository stacking.
1932
if self._stack_on is None:
1934
if self._stack_on_pwd is None:
1935
stack_on = self._stack_on
1938
stack_on = urlutils.rebase_url(self._stack_on,
1941
except errors.InvalidRebaseURLs:
1942
stack_on = self._get_full_stack_on()
1944
branch.set_stacked_on_url(stack_on)
1945
except (errors.UnstackableBranchFormat,
1946
errors.UnstackableRepositoryFormat):
1947
if self._require_stacking:
1950
def requires_stacking(self):
1951
"""Return True if this policy requires stacking."""
1952
return self._stack_on is not None and self._require_stacking
1954
def _get_full_stack_on(self):
1955
"""Get a fully-qualified URL for the stack_on location."""
1956
if self._stack_on is None:
1958
if self._stack_on_pwd is None:
1959
return self._stack_on
1961
return urlutils.join(self._stack_on_pwd, self._stack_on)
1963
def _add_fallback(self, repository, possible_transports=None):
1964
"""Add a fallback to the supplied repository, if stacking is set."""
1965
stack_on = self._get_full_stack_on()
1966
if stack_on is None:
1969
stacked_dir = BzrDir.open(stack_on,
1970
possible_transports=possible_transports)
1971
except errors.JailBreak:
1972
# We keep the stacking details, but we are in the server code so
1973
# actually stacking is not needed.
1976
stacked_repo = stacked_dir.open_branch().repository
1977
except errors.NotBranchError:
1978
stacked_repo = stacked_dir.open_repository()
1980
repository.add_fallback_repository(stacked_repo)
1981
except errors.UnstackableRepositoryFormat:
1982
if self._require_stacking:
1985
self._require_stacking = True
1987
def acquire_repository(self, make_working_trees=None, shared=False):
1988
"""Acquire a repository for this bzrdir.
1990
Implementations may create a new repository or use a pre-exising
1992
:param make_working_trees: If creating a repository, set
1993
make_working_trees to this value (if non-None)
1994
:param shared: If creating a repository, make it shared if True
1995
:return: A repository, is_new_flag (True if the repository was
1998
raise NotImplemented(RepositoryAcquisitionPolicy.acquire_repository)
2001
class CreateRepository(RepositoryAcquisitionPolicy):
2002
"""A policy of creating a new repository"""
2004
def __init__(self, bzrdir, stack_on=None, stack_on_pwd=None,
2005
require_stacking=False):
2008
:param bzrdir: The bzrdir to create the repository on.
2009
:param stack_on: A location to stack on
2010
:param stack_on_pwd: If stack_on is relative, the location it is
2013
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2015
self._bzrdir = bzrdir
2017
def acquire_repository(self, make_working_trees=None, shared=False):
2018
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2020
Creates the desired repository in the bzrdir we already have.
2022
stack_on = self._get_full_stack_on()
2024
format = self._bzrdir._format
2025
format.require_stacking(stack_on=stack_on,
2026
possible_transports=[self._bzrdir.root_transport])
2027
if not self._require_stacking:
2028
# We have picked up automatic stacking somewhere.
2029
note('Using default stacking branch %s at %s', self._stack_on,
2031
repository = self._bzrdir.create_repository(shared=shared)
2032
self._add_fallback(repository,
2033
possible_transports=[self._bzrdir.transport])
2034
if make_working_trees is not None:
2035
repository.set_make_working_trees(make_working_trees)
2036
return repository, True
2039
class UseExistingRepository(RepositoryAcquisitionPolicy):
2040
"""A policy of reusing an existing repository"""
2042
def __init__(self, repository, stack_on=None, stack_on_pwd=None,
2043
require_stacking=False):
2046
:param repository: The repository to use.
2047
:param stack_on: A location to stack on
2048
:param stack_on_pwd: If stack_on is relative, the location it is
2051
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2053
self._repository = repository
2055
def acquire_repository(self, make_working_trees=None, shared=False):
2056
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2058
Returns an existing repository to use.
2060
self._add_fallback(self._repository,
2061
possible_transports=[self._repository.bzrdir.transport])
2062
return self._repository, False
2065
def register_metadir(registry, key,
2066
repository_format, help, native=True, deprecated=False,
2072
"""Register a metadir subformat.
2074
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
2075
by the Repository/Branch/WorkingTreeformats.
2077
:param repository_format: The fully-qualified repository format class
2079
:param branch_format: Fully-qualified branch format class name as
2081
:param tree_format: Fully-qualified tree format class name as
2084
# This should be expanded to support setting WorkingTree and Branch
2085
# formats, once BzrDirMetaFormat1 supports that.
2086
def _load(full_name):
2087
mod_name, factory_name = full_name.rsplit('.', 1)
2089
factory = pyutils.get_named_object(mod_name, factory_name)
2090
except ImportError, e:
2091
raise ImportError('failed to load %s: %s' % (full_name, e))
2092
except AttributeError:
2093
raise AttributeError('no factory %s in module %r'
2094
% (full_name, sys.modules[mod_name]))
2098
bd = BzrDirMetaFormat1()
2099
if branch_format is not None:
2100
bd.set_branch_format(_load(branch_format))
2101
if tree_format is not None:
2102
bd.workingtree_format = _load(tree_format)
2103
if repository_format is not None:
2104
bd.repository_format = _load(repository_format)
2106
registry.register(key, helper, help, native, deprecated, hidden,
2107
experimental, alias)
2109
register_metadir(controldir.format_registry, 'knit',
2110
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2111
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
2112
branch_format='bzrlib.branch.BzrBranchFormat5',
2113
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
2116
register_metadir(controldir.format_registry, 'dirstate',
2117
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2118
help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
2119
'above when accessed over the network.',
2120
branch_format='bzrlib.branch.BzrBranchFormat5',
2121
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2124
register_metadir(controldir.format_registry, 'dirstate-tags',
2125
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2126
help='New in 0.15: Fast local operations and improved scaling for '
2127
'network operations. Additionally adds support for tags.'
2128
' Incompatible with bzr < 0.15.',
2129
branch_format='bzrlib.branch.BzrBranchFormat6',
2130
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2133
register_metadir(controldir.format_registry, 'rich-root',
2134
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
2135
help='New in 1.0. Better handling of tree roots. Incompatible with'
2137
branch_format='bzrlib.branch.BzrBranchFormat6',
2138
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2141
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
2142
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2143
help='New in 0.15: Fast local operations and improved scaling for '
2144
'network operations. Additionally adds support for versioning nested '
2145
'bzr branches. Incompatible with bzr < 0.15.',
2146
branch_format='bzrlib.branch.BzrBranchFormat6',
2147
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2151
register_metadir(controldir.format_registry, 'pack-0.92',
2152
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
2153
help='New in 0.92: Pack-based format with data compatible with '
2154
'dirstate-tags format repositories. Interoperates with '
2155
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2157
branch_format='bzrlib.branch.BzrBranchFormat6',
2158
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2160
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2161
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
2162
help='New in 0.92: Pack-based format with data compatible with '
2163
'dirstate-with-subtree format repositories. Interoperates with '
2164
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2166
branch_format='bzrlib.branch.BzrBranchFormat6',
2167
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2171
register_metadir(controldir.format_registry, 'rich-root-pack',
2172
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
2173
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
2174
'(needed for bzr-svn and bzr-git).',
2175
branch_format='bzrlib.branch.BzrBranchFormat6',
2176
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2179
register_metadir(controldir.format_registry, '1.6',
2180
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
2181
help='A format that allows a branch to indicate that there is another '
2182
'(stacked) repository that should be used to access data that is '
2183
'not present locally.',
2184
branch_format='bzrlib.branch.BzrBranchFormat7',
2185
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2188
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2189
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
2190
help='A variant of 1.6 that supports rich-root data '
2191
'(needed for bzr-svn and bzr-git).',
2192
branch_format='bzrlib.branch.BzrBranchFormat7',
2193
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2196
register_metadir(controldir.format_registry, '1.9',
2197
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2198
help='A repository format using B+tree indexes. These indexes '
2199
'are smaller in size, have smarter caching and provide faster '
2200
'performance for most operations.',
2201
branch_format='bzrlib.branch.BzrBranchFormat7',
2202
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2205
register_metadir(controldir.format_registry, '1.9-rich-root',
2206
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2207
help='A variant of 1.9 that supports rich-root data '
2208
'(needed for bzr-svn and bzr-git).',
2209
branch_format='bzrlib.branch.BzrBranchFormat7',
2210
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2213
register_metadir(controldir.format_registry, '1.14',
2214
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2215
help='A working-tree format that supports content filtering.',
2216
branch_format='bzrlib.branch.BzrBranchFormat7',
2217
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2219
register_metadir(controldir.format_registry, '1.14-rich-root',
2220
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2221
help='A variant of 1.14 that supports rich-root data '
2222
'(needed for bzr-svn and bzr-git).',
2223
branch_format='bzrlib.branch.BzrBranchFormat7',
2224
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2226
# The following un-numbered 'development' formats should always just be aliases.
2227
register_metadir(controldir.format_registry, 'development-subtree',
2228
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2aSubtree',
2229
help='Current development format, subtree variant. Can convert data to and '
2230
'from pack-0.92-subtree (and anything compatible with '
2231
'pack-0.92-subtree) format repositories. Repositories and branches in '
2232
'this format can only be read by bzr.dev. Please read '
2233
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2235
branch_format='bzrlib.branch.BzrBranchFormat7',
2236
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2239
alias=False, # Restore to being an alias when an actual development subtree format is added
2240
# This current non-alias status is simply because we did not introduce a
2241
# chk based subtree format.
2243
register_metadir(controldir.format_registry, 'development5-subtree',
2244
'bzrlib.repofmt.knitpack_repo.RepositoryFormatPackDevelopment2Subtree',
2245
help='Development format, subtree variant. Can convert data to and '
2246
'from pack-0.92-subtree (and anything compatible with '
2247
'pack-0.92-subtree) format repositories. Repositories and branches in '
2248
'this format can only be read by bzr.dev. Please read '
2249
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2251
branch_format='bzrlib.branch.BzrBranchFormat7',
2252
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2258
# And the development formats above will have aliased one of the following:
2260
# Finally, the current format.
2261
register_metadir(controldir.format_registry, '2a',
2262
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2263
help='First format for bzr 2.0 series.\n'
2264
'Uses group-compress storage.\n'
2265
'Provides rich roots which are a one-way transition.\n',
2266
# 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
2267
# 'rich roots. Supported by bzr 1.16 and later.',
2268
branch_format='bzrlib.branch.BzrBranchFormat7',
2269
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2273
# The following format should be an alias for the rich root equivalent
2274
# of the default format
2275
register_metadir(controldir.format_registry, 'default-rich-root',
2276
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2277
branch_format='bzrlib.branch.BzrBranchFormat7',
2278
tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
2283
# The current format that is made on 'bzr init'.
2284
format_name = config.GlobalConfig().get_user_option('default_format')
2285
if format_name is None:
2286
controldir.format_registry.set_default('2a')
2288
controldir.format_registry.set_default(format_name)
2290
# XXX 2010-08-20 JRV: There is still a lot of code relying on
2291
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc
2292
# get changed to ControlDir.create/ControlDir.open/etc this should be removed.
2293
format_registry = controldir.format_registry