112
116
thing_to_unlock.break_lock()
118
def can_convert_format(self):
119
"""Return true if this bzrdir is one whose format we can convert from."""
114
122
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
123
target_repo_format = target_format.repository_format
120
self.open_repository()._format.check_conversion_target(
122
except errors.NoRepositoryPresent:
123
# No repo, no problem.
124
source_repo_format = self._format.repository_format
125
source_repo_format.check_conversion_target(target_repo_format)
128
def _check_supported(format, allow_unsupported,
129
recommend_upgrade=True,
131
"""Give an error or warning on old formats.
133
:param format: may be any kind of format - workingtree, branch,
136
:param allow_unsupported: If true, allow opening
137
formats that are strongly deprecated, and which may
138
have limited functionality.
140
:param recommend_upgrade: If true (default), warn
141
the user through the ui object that they may wish
142
to upgrade the object.
144
# TODO: perhaps move this into a base Format class; it's not BzrDir
145
# specific. mbp 20070323
146
if not allow_unsupported and not format.is_supported():
147
# see open_downlevel to open legacy branches.
148
raise errors.UnsupportedFormatError(format=format)
149
if recommend_upgrade \
150
and getattr(format, 'upgrade_recommended', False):
151
ui.ui_factory.recommend_upgrade(
152
format.get_format_description(),
155
def clone(self, url, revision_id=None, force_new_repo=False):
156
"""Clone this bzrdir and its contents to url verbatim.
158
If url's last component does not exist, it will be created.
160
if revision_id is not None, then the clone operation may tune
161
itself to download less data.
162
:param force_new_repo: Do not use a shared repository for the target
163
even if one is available.
165
return self.clone_on_transport(get_transport(url),
166
revision_id=revision_id,
167
force_new_repo=force_new_repo)
126
169
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):
170
force_new_repo=False):
129
171
"""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
173
If the target directory does not exist, it will be created.
175
if revision_id is not None, then the clone operation may tune
135
176
itself to download less data.
136
:param force_new_repo: Do not use a shared repository for the target,
177
:param force_new_repo: Do not use a shared repository for the target
137
178
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:
180
transport.ensure_base()
181
result = self._format.initialize_on_transport(transport)
155
183
local_repo = self.find_repository()
156
184
except errors.NoRepositoryPresent:
157
185
local_repo = None
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)
187
# may need to copy content in
189
result_repo = local_repo.clone(
191
revision_id=revision_id)
192
result_repo.set_make_working_trees(local_repo.make_working_trees())
195
result_repo = result.find_repository()
196
# fetch content this dir needs.
207
197
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)
198
except errors.NoRepositoryPresent:
199
# needed to make one anyway.
200
result_repo = local_repo.clone(
202
revision_id=revision_id)
203
result_repo.set_make_working_trees(local_repo.make_working_trees())
213
204
# 1 if there is a branch present
214
205
# 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)
208
self.open_branch().clone(result, revision_id=revision_id)
209
except errors.NotBranchError:
212
self.open_workingtree().clone(result)
225
213
except (errors.NoWorkingTree, errors.NotLocalUrl):
229
217
# TODO: This should be given a Transport, and should chdir up; otherwise
230
218
# this will open a new connection.
231
219
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:
220
t = get_transport(url)
224
def create(cls, base, format=None, possible_transports=None):
225
"""Create a new BzrDir at the url 'base'.
227
:param format: If supplied, the format of branch to create. If not
228
supplied, the default is used.
229
:param possible_transports: If supplied, a list of transports that
230
can be reused to share a remote connection.
232
if cls is not BzrDir:
233
raise AssertionError("BzrDir.create always creates the default"
234
" format, not one of %r" % cls)
235
t = get_transport(base, possible_transports)
238
format = BzrDirFormat.get_default_format()
239
return format.initialize_on_transport(t)
241
def create_branch(self):
242
"""Create a branch in this BzrDir.
244
The bzrdir's format will control what branch format is created.
245
For more control see BranchFormatXX.create(a_bzrdir).
247
raise NotImplementedError(self.create_branch)
249
def destroy_branch(self):
250
"""Destroy the branch in this BzrDir"""
251
raise NotImplementedError(self.destroy_branch)
305
254
def create_branch_and_repo(base, force_new_repo=False, format=None):
306
255
"""Create a new BzrDir, Branch and Repository at the url 'base'.
308
257
This will use the current default BzrDirFormat unless one is
309
specified, and use whatever
258
specified, and use whatever
310
259
repository format that that uses via bzrdir.create_branch and
311
260
create_repository. If a shared repository is available that is used
322
271
bzrdir._find_or_create_repository(force_new_repo)
323
272
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
274
def _find_or_create_repository(self, force_new_repo):
387
275
"""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.
277
return self.create_repository()
279
return self.find_repository()
280
except errors.NoRepositoryPresent:
281
return self.create_repository()
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
284
def create_branch_convenience(base, force_new_repo=False,
548
285
force_new_tree=None, format=None,
700
424
new branches as well as to hook existing branches up to their
703
def usable_repository(found_bzrdir):
428
return self.open_repository()
429
except errors.NoRepositoryPresent:
431
next_transport = self.root_transport.clone('..')
433
# find the next containing bzrdir
435
found_bzrdir = BzrDir.open_containing_from_transport(
437
except errors.NotBranchError:
439
raise errors.NoRepositoryPresent(self)
704
440
# does it have a repository ?
706
442
repository = found_bzrdir.open_repository()
707
443
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."""
444
next_transport = found_bzrdir.root_transport.clone('..')
445
if (found_bzrdir.root_transport.base == next_transport.base):
446
# top of the file system
450
if ((found_bzrdir.root_transport.base ==
451
self.root_transport.base) or repository.is_shared()):
454
raise errors.NoRepositoryPresent(self)
455
raise errors.NoRepositoryPresent(self)
457
def get_branch_reference(self):
458
"""Return the referenced URL for the branch in this bzrdir.
460
:raises NotBranchError: If there is no Branch.
461
:return: The URL the branch in this bzrdir references if it is a
462
reference branch, or None for regular branches.
466
def get_branch_transport(self, branch_format):
467
"""Get the transport for use by branch format in this BzrDir.
469
Note that bzr dirs that do not support format strings will raise
470
IncompatibleFormat if the branch format they are given has
471
a format string, and vice versa.
473
If branch_format is None, the transport is returned with no
474
checking. If it is not None, then the returned transport is
475
guaranteed to point to an existing directory ready for use.
477
raise NotImplementedError(self.get_branch_transport)
479
def get_repository_transport(self, repository_format):
480
"""Get the transport for use by repository format in this BzrDir.
482
Note that bzr dirs that do not support format strings will raise
483
IncompatibleFormat if the repository format they are given has
484
a format string, and vice versa.
486
If repository_format is None, the transport is returned with no
487
checking. If it is not None, then the returned transport is
488
guaranteed to point to an existing directory ready for use.
490
raise NotImplementedError(self.get_repository_transport)
492
def get_workingtree_transport(self, tree_format):
493
"""Get the transport for use by workingtree format in this BzrDir.
495
Note that bzr dirs that do not support format strings will raise
496
IncompatibleFormat if the workingtree format they are given has a
497
format string, and vice versa.
499
If workingtree_format is None, the transport is returned with no
500
checking. If it is not None, then the returned transport is
501
guaranteed to point to an existing directory ready for use.
503
raise NotImplementedError(self.get_workingtree_transport)
773
505
def __init__(self, _transport, _format):
774
506
"""Initialize a Bzr control dir object.
776
508
Only really common logic should reside here, concrete classes should be
777
509
made with varying behaviours.
926
665
relpath is the portion of the path that is contained by the branch.
928
667
bzrdir, relpath = klass.open_containing(location)
929
tree, branch = bzrdir._get_tree_branch()
669
tree = bzrdir.open_workingtree()
670
except (errors.NoWorkingTree, errors.NotLocalUrl):
672
branch = bzrdir.open_branch()
930
675
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)
677
def open_repository(self, _unsupported=False):
678
"""Open the repository object at this BzrDir if one is present.
680
This will not follow the Branch object pointer - it's strictly a direct
681
open facility. Most client code should use open_branch().repository to
684
:param _unsupported: a private parameter, not part of the api.
685
TODO: static convenience version of this?
687
raise NotImplementedError(self.open_repository)
689
def open_workingtree(self, _unsupported=False,
690
recommend_upgrade=True):
691
"""Open the workingtree object at this BzrDir if one is present.
693
:param recommend_upgrade: Optional keyword parameter, when True (the
694
default), emit through the ui module a recommendation that the user
695
upgrade the working tree when the workingtree being opened is old
696
(but still fully supported).
698
raise NotImplementedError(self.open_workingtree)
700
def has_branch(self):
701
"""Tell if this bzrdir contains a branch.
703
Note: if you're going to open the branch, you should just go ahead
704
and try, and not ask permission first. (This method just opens the
705
branch and discards it, and that's somewhat expensive.)
948
tree, branch = bzrdir._get_tree_branch()
949
710
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
713
def has_workingtree(self):
714
"""Tell if this bzrdir contains a working tree.
716
This will still raise an exception if the bzrdir has a workingtree that
717
is remote & inaccessible.
719
Note: if you're going to open the working tree, you should just go ahead
720
and try, and not ask permission first. (This method just opens the
721
workingtree and discards it, and that's somewhat expensive.)
724
self.open_workingtree(recommend_upgrade=False)
726
except errors.NoWorkingTree:
957
729
def _cloning_metadir(self):
958
"""Produce a metadir suitable for cloning with.
960
:returns: (destination_bzrdir_format, source_repository)
730
"""Produce a metadir suitable for cloning with."""
962
731
result_format = self._format.__class__()
965
branch = self.open_branch(ignore_fallbacks=True)
734
branch = self.open_branch()
966
735
source_repository = branch.repository
967
result_format._branch_format = branch._format
968
736
except errors.NotBranchError:
969
737
source_branch = None
970
738
source_repository = self.open_repository()
990
756
result_format.workingtree_format = tree._format.__class__()
991
757
return result_format, source_repository
993
def cloning_metadir(self, require_stacking=False):
759
def cloning_metadir(self):
994
760
"""Produce a metadir suitable for cloning or sprouting with.
996
762
These operations may produce workingtrees (yes, even though they're
997
763
"cloning" something that doesn't have a tree), so a viable workingtree
998
764
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
766
format, repository = self._cloning_metadir()
1007
767
if format._workingtree_format is None:
1009
768
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
770
tree_format = repository._format._matchingbzrdir.workingtree_format
1015
771
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.
774
def checkout_metadir(self):
775
return self.cloning_metadir()
777
def sprout(self, url, revision_id=None, force_new_repo=False,
778
recurse='down', possible_transports=None):
779
"""Create a copy of this bzrdir prepared for use as a new line of
782
If url's last component does not exist, it will be created.
784
Attributes related to the identity of the source branch like
785
branch nickname will be cleaned, a working tree is created
786
whether one existed before or not; and a local branch is always
789
if revision_id is not None, then the clone operation may tune
790
itself to download less data.
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)
792
target_transport = get_transport(url, possible_transports)
793
target_transport.ensure_base()
794
cloning_format = self.cloning_metadir()
795
result = cloning_format.initialize_on_transport(target_transport)
797
source_branch = self.open_branch()
798
source_repository = source_branch.repository
799
except errors.NotBranchError:
802
source_repository = self.open_repository()
803
except errors.NoRepositoryPresent:
804
source_repository = None
809
result_repo = result.find_repository()
810
except errors.NoRepositoryPresent:
812
if source_repository is None and result_repo is not None:
814
elif source_repository is None and result_repo is None:
815
# no repo available, make a new one
816
result.create_repository()
817
elif source_repository is not None and result_repo is None:
818
# have source, and want to make a new target repo
819
result_repo = source_repository.sprout(result,
820
revision_id=revision_id)
822
# fetch needed content into target.
823
if source_repository is not None:
825
# source_repository.copy_content_into(result_repo,
826
# revision_id=revision_id)
827
# so we can override the copy method
828
result_repo.fetch(source_repository, revision_id=revision_id)
829
if source_branch is not None:
830
source_branch.sprout(result, revision_id=revision_id)
832
result.create_branch()
833
if isinstance(target_transport, LocalTransport) and (
834
result_repo is None or result_repo.make_working_trees()):
835
wt = result.create_workingtree()
838
if wt.path2id('') is None:
840
wt.set_root_id(self.open_workingtree.get_root_id())
841
except errors.NoWorkingTree:
847
if recurse == 'down':
849
basis = wt.basis_tree()
851
subtrees = basis.iter_references()
852
recurse_branch = wt.branch
853
elif source_branch is not None:
854
basis = source_branch.basis_tree()
856
subtrees = basis.iter_references()
857
recurse_branch = source_branch
862
for path, file_id in subtrees:
863
target = urlutils.join(url, urlutils.escape(path))
864
sublocation = source_branch.reference_parent(file_id, path)
865
sublocation.bzrdir.sprout(target,
866
basis.get_reference_revision(file_id, path),
867
force_new_repo=force_new_repo, recurse=recurse)
869
if basis is not None:
874
class BzrDirPreSplitOut(BzrDir):
875
"""A common class for the all-in-one formats."""
877
def __init__(self, _transport, _format):
878
"""See BzrDir.__init__."""
879
super(BzrDirPreSplitOut, self).__init__(_transport, _format)
880
assert self._format._lock_class == lockable_files.TransportLock
881
assert self._format._lock_file_name == 'branch-lock'
882
self._control_files = lockable_files.LockableFiles(
883
self.get_branch_transport(None),
884
self._format._lock_file_name,
885
self._format._lock_class)
887
def break_lock(self):
888
"""Pre-splitout bzrdirs do not suffer from stale locks."""
889
raise NotImplementedError(self.break_lock)
891
def clone(self, url, revision_id=None, force_new_repo=False):
892
"""See BzrDir.clone()."""
893
from bzrlib.workingtree import WorkingTreeFormat2
895
result = self._format._initialize_for_clone(url)
896
self.open_repository().clone(result, revision_id=revision_id)
897
from_branch = self.open_branch()
898
from_branch.clone(result, revision_id=revision_id)
900
self.open_workingtree().clone(result)
901
except errors.NotLocalUrl:
902
# make a new one, this format always has to have one.
904
WorkingTreeFormat2().initialize(result)
905
except errors.NotLocalUrl:
906
# but we cannot do it for remote trees.
907
to_branch = result.open_branch()
908
WorkingTreeFormat2().stub_initialize_remote(to_branch.control_files)
911
def create_branch(self):
912
"""See BzrDir.create_branch."""
913
return self.open_branch()
915
def destroy_branch(self):
916
"""See BzrDir.destroy_branch."""
917
raise errors.UnsupportedOperation(self.destroy_branch, self)
919
def create_repository(self, shared=False):
920
"""See BzrDir.create_repository."""
922
raise errors.IncompatibleFormat('shared repository', self._format)
923
return self.open_repository()
925
def create_workingtree(self, revision_id=None):
926
"""See BzrDir.create_workingtree."""
927
# this looks buggy but is not -really-
928
# because this format creates the workingtree when the bzrdir is
930
# clone and sprout will have set the revision_id
931
# and that will have set it for us, its only
932
# specific uses of create_workingtree in isolation
933
# that can do wonky stuff here, and that only
934
# happens for creating checkouts, which cannot be
935
# done on this format anyway. So - acceptable wart.
936
result = self.open_workingtree(recommend_upgrade=False)
937
if revision_id is not None:
938
if revision_id == _mod_revision.NULL_REVISION:
939
result.set_parent_ids([])
941
result.set_parent_ids([revision_id])
944
def destroy_workingtree(self):
945
"""See BzrDir.destroy_workingtree."""
946
raise errors.UnsupportedOperation(self.destroy_workingtree, self)
948
def destroy_workingtree_metadata(self):
949
"""See BzrDir.destroy_workingtree_metadata."""
950
raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
953
def get_branch_transport(self, branch_format):
954
"""See BzrDir.get_branch_transport()."""
955
if branch_format is None:
956
return self.transport
958
branch_format.get_format_string()
959
except NotImplementedError:
960
return self.transport
961
raise errors.IncompatibleFormat(branch_format, self._format)
963
def get_repository_transport(self, repository_format):
964
"""See BzrDir.get_repository_transport()."""
965
if repository_format is None:
966
return self.transport
968
repository_format.get_format_string()
969
except NotImplementedError:
970
return self.transport
971
raise errors.IncompatibleFormat(repository_format, self._format)
973
def get_workingtree_transport(self, workingtree_format):
974
"""See BzrDir.get_workingtree_transport()."""
975
if workingtree_format is None:
976
return self.transport
978
workingtree_format.get_format_string()
979
except NotImplementedError:
980
return self.transport
981
raise errors.IncompatibleFormat(workingtree_format, self._format)
983
def needs_format_conversion(self, format=None):
984
"""See BzrDir.needs_format_conversion()."""
985
# if the format is not the same as the system default,
986
# an upgrade is needed.
1034
987
if format is None:
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__,
988
format = BzrDirFormat.get_default_format()
989
return not isinstance(self._format, format.__class__)
991
def open_branch(self, unsupported=False):
992
"""See BzrDir.open_branch."""
993
from bzrlib.branch import BzrBranchFormat4
994
format = BzrBranchFormat4()
995
self._check_supported(format, unsupported)
996
return format.open(self, _found=True)
998
def sprout(self, url, revision_id=None, force_new_repo=False,
999
possible_transports=None):
1000
"""See BzrDir.sprout()."""
1001
from bzrlib.workingtree import WorkingTreeFormat2
1002
self._make_tail(url)
1003
result = self._format._initialize_for_clone(url)
1005
self.open_repository().clone(result, revision_id=revision_id)
1006
except errors.NoRepositoryPresent:
1009
self.open_branch().sprout(result, revision_id=revision_id)
1010
except errors.NotBranchError:
1012
# we always want a working tree
1013
WorkingTreeFormat2().initialize(result)
1017
class BzrDir4(BzrDirPreSplitOut):
1018
"""A .bzr version 4 control object.
1020
This is a deprecated format and may be removed after sept 2006.
1023
def create_repository(self, shared=False):
1024
"""See BzrDir.create_repository."""
1025
return self._format.repository_format.initialize(self, shared)
1027
def needs_format_conversion(self, format=None):
1028
"""Format 4 dirs are always in need of conversion."""
1031
def open_repository(self):
1032
"""See BzrDir.open_repository."""
1033
from bzrlib.repofmt.weaverepo import RepositoryFormat4
1034
return RepositoryFormat4().open(self, _found=True)
1037
class BzrDir5(BzrDirPreSplitOut):
1038
"""A .bzr version 5 control object.
1040
This is a deprecated format and may be removed after sept 2006.
1043
def open_repository(self):
1044
"""See BzrDir.open_repository."""
1045
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1046
return RepositoryFormat5().open(self, _found=True)
1048
def open_workingtree(self, _unsupported=False,
1049
recommend_upgrade=True):
1050
"""See BzrDir.create_workingtree."""
1051
from bzrlib.workingtree import WorkingTreeFormat2
1052
wt_format = WorkingTreeFormat2()
1053
# we don't warn here about upgrades; that ought to be handled for the
1055
return wt_format.open(self, _found=True)
1058
class BzrDir6(BzrDirPreSplitOut):
1059
"""A .bzr version 6 control object.
1061
This is a deprecated format and may be removed after sept 2006.
1064
def open_repository(self):
1065
"""See BzrDir.open_repository."""
1066
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1067
return RepositoryFormat6().open(self, _found=True)
1069
def open_workingtree(self, _unsupported=False,
1070
recommend_upgrade=True):
1071
"""See BzrDir.create_workingtree."""
1072
# we don't warn here about upgrades; that ought to be handled for the
1074
from bzrlib.workingtree import WorkingTreeFormat2
1075
return WorkingTreeFormat2().open(self, _found=True)
1133
1078
class BzrDirMeta1(BzrDir):
1134
1079
"""A .bzr meta version 1 control object.
1136
This is the first control object where the
1081
This is the first control object where the
1137
1082
individual aspects are really split out: there are separate repository,
1138
1083
workingtree and branch subdirectories and any subset of the three can be
1139
1084
present within a BzrDir.
1313
1228
"""See BzrDir.open_workingtree."""
1314
1229
from bzrlib.workingtree import WorkingTreeFormat
1315
1230
format = WorkingTreeFormat.find_format(self)
1316
format.check_support_status(unsupported, recommend_upgrade,
1231
self._check_supported(format, unsupported,
1317
1233
basedir=self.root_transport.base)
1318
1234
return format.open(self, _found=True)
1320
def _get_config(self):
1321
return config.TransportConfig(self.transport, 'control.conf')
1324
class BzrProber(controldir.Prober):
1325
"""Prober for formats that use a .bzr/ control directory."""
1327
formats = registry.FormatRegistry(controldir.network_format_registry)
1328
"""The known .bzr formats."""
1331
@deprecated_method(deprecated_in((2, 4, 0)))
1332
def register_bzrdir_format(klass, format):
1333
klass.formats.register(format.get_format_string(), format)
1336
@deprecated_method(deprecated_in((2, 4, 0)))
1337
def unregister_bzrdir_format(klass, format):
1338
klass.formats.remove(format.get_format_string())
1341
def probe_transport(klass, transport):
1342
"""Return the .bzrdir style format present in a directory."""
1344
format_string = transport.get_bytes(".bzr/branch-format")
1345
except errors.NoSuchFile:
1346
raise errors.NotBranchError(path=transport.base)
1348
return klass.formats.get(format_string)
1350
raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
1353
def known_formats(cls):
1355
for name, format in cls.formats.iteritems():
1356
if callable(format):
1362
controldir.ControlDirFormat.register_prober(BzrProber)
1365
class RemoteBzrProber(controldir.Prober):
1366
"""Prober for remote servers that provide a Bazaar smart server."""
1369
def probe_transport(klass, transport):
1370
"""Return a RemoteBzrDirFormat object if it looks possible."""
1372
medium = transport.get_smart_medium()
1373
except (NotImplementedError, AttributeError,
1374
errors.TransportNotPossible, errors.NoSmartMedium,
1375
errors.SmartProtocolError):
1376
# no smart server, so not a branch for this format type.
1377
raise errors.NotBranchError(path=transport.base)
1379
# Decline to open it if the server doesn't support our required
1380
# version (3) so that the VFS-based transport will do it.
1381
if medium.should_probe():
1383
server_version = medium.protocol_version()
1384
except errors.SmartProtocolError:
1385
# Apparently there's no usable smart server there, even though
1386
# the medium supports the smart protocol.
1387
raise errors.NotBranchError(path=transport.base)
1388
if server_version != '2':
1389
raise errors.NotBranchError(path=transport.base)
1390
from bzrlib.remote import RemoteBzrDirFormat
1391
return RemoteBzrDirFormat()
1394
def known_formats(cls):
1395
from bzrlib.remote import RemoteBzrDirFormat
1396
return set([RemoteBzrDirFormat()])
1399
class BzrDirFormat(controldir.ControlDirFormat):
1400
"""ControlDirFormat base class for .bzr/ directories.
1402
Formats are placed in a dict by their format string for reference
1237
class BzrDirFormat(object):
1238
"""An encapsulation of the initialization and open routines for a format.
1240
Formats provide three things:
1241
* An initialization routine,
1245
Formats are placed in a dict by their format string for reference
1403
1246
during bzrdir opening. These should be subclasses of BzrDirFormat
1404
1247
for consistency.
1406
1249
Once a format is deprecated, just deprecate the initialize and open
1407
methods on the format class. Do not deprecate the object, as the
1250
methods on the format class. Do not deprecate the object, as the
1408
1251
object will be created every system load.
1254
_default_format = None
1255
"""The default format used for new .bzr dirs."""
1258
"""The known formats."""
1260
_control_formats = []
1261
"""The registered control formats - .bzr, ....
1263
This is a list of BzrDirFormat objects.
1266
_control_server_formats = []
1267
"""The registered control server formats, e.g. RemoteBzrDirs.
1269
This is a list of BzrDirFormat objects.
1411
1272
_lock_file_name = 'branch-lock'
1413
1274
# _lock_class must be set in subclasses to the lock type, typ.
1414
1275
# TransportLock or LockDir
1417
def get_format_string(cls):
1278
def find_format(klass, transport, _server_formats=True):
1279
"""Return the format present at transport."""
1281
formats = klass._control_server_formats + klass._control_formats
1283
formats = klass._control_formats
1284
for format in formats:
1286
return format.probe_transport(transport)
1287
except errors.NotBranchError:
1288
# this format does not find a control dir here.
1290
raise errors.NotBranchError(path=transport.base)
1293
def probe_transport(klass, transport):
1294
"""Return the .bzrdir style format present in a directory."""
1296
format_string = transport.get(".bzr/branch-format").read()
1297
except errors.NoSuchFile:
1298
raise errors.NotBranchError(path=transport.base)
1301
return klass._formats[format_string]
1303
raise errors.UnknownFormatError(format=format_string)
1306
def get_default_format(klass):
1307
"""Return the current default format."""
1308
return klass._default_format
1310
def get_format_string(self):
1418
1311
"""Return the ASCII format string that identifies this format."""
1419
1312
raise NotImplementedError(self.get_format_string)
1314
def get_format_description(self):
1315
"""Return the short description for this format."""
1316
raise NotImplementedError(self.get_format_description)
1318
def get_converter(self, format=None):
1319
"""Return the converter to use to convert bzrdirs needing converts.
1321
This returns a bzrlib.bzrdir.Converter object.
1323
This should return the best upgrader to step this format towards the
1324
current default format. In the case of plugins we can/should provide
1325
some means for them to extend the range of returnable converters.
1327
:param format: Optional format to override the default format of the
1330
raise NotImplementedError(self.get_converter)
1332
def initialize(self, url, possible_transports=None):
1333
"""Create a bzr control dir at this url and return an opened copy.
1335
Subclasses should typically override initialize_on_transport
1336
instead of this method.
1338
return self.initialize_on_transport(get_transport(url,
1339
possible_transports))
1421
1341
def initialize_on_transport(self, transport):
1422
1342
"""Initialize a new bzrdir in the base directory of a Transport."""
1424
# can we hand off the request to the smart server rather than using
1426
client_medium = transport.get_smart_medium()
1427
except errors.NoSmartMedium:
1428
return self._initialize_on_transport_vfs(transport)
1430
# Current RPC's only know how to create bzr metadir1 instances, so
1431
# we still delegate to vfs methods if the requested format is not a
1433
if type(self) != BzrDirMetaFormat1:
1434
return self._initialize_on_transport_vfs(transport)
1435
from bzrlib.remote import RemoteBzrDirFormat
1436
remote_format = RemoteBzrDirFormat()
1437
self._supply_sub_formats_to(remote_format)
1438
return remote_format.initialize_on_transport(transport)
1440
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1441
create_prefix=False, force_new_repo=False, stacked_on=None,
1442
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1443
shared_repo=False, vfs_only=False):
1444
"""Create this format on transport.
1446
The directory to initialize will be created.
1448
:param force_new_repo: Do not use a shared repository for the target,
1449
even if one is available.
1450
:param create_prefix: Create any missing directories leading up to
1452
:param use_existing_dir: Use an existing directory if one exists.
1453
:param stacked_on: A url to stack any created branch on, None to follow
1454
any target stacking policy.
1455
:param stack_on_pwd: If stack_on is relative, the location it is
1457
:param repo_format_name: If non-None, a repository will be
1458
made-or-found. Should none be found, or if force_new_repo is True
1459
the repo_format_name is used to select the format of repository to
1461
:param make_working_trees: Control the setting of make_working_trees
1462
for a new shared repository when one is made. None to use whatever
1463
default the format has.
1464
:param shared_repo: Control whether made repositories are shared or
1466
:param vfs_only: If True do not attempt to use a smart server
1467
:return: repo, bzrdir, require_stacking, repository_policy. repo is
1468
None if none was created or found, bzrdir is always valid.
1469
require_stacking is the result of examining the stacked_on
1470
parameter and any stacking policy found for the target.
1473
# Try to hand off to a smart server
1475
client_medium = transport.get_smart_medium()
1476
except errors.NoSmartMedium:
1479
from bzrlib.remote import RemoteBzrDirFormat
1480
# TODO: lookup the local format from a server hint.
1481
remote_dir_format = RemoteBzrDirFormat()
1482
remote_dir_format._network_name = self.network_name()
1483
self._supply_sub_formats_to(remote_dir_format)
1484
return remote_dir_format.initialize_on_transport_ex(transport,
1485
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1486
force_new_repo=force_new_repo, stacked_on=stacked_on,
1487
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1488
make_working_trees=make_working_trees, shared_repo=shared_repo)
1489
# XXX: Refactor the create_prefix/no_create_prefix code into a
1490
# common helper function
1491
# The destination may not exist - if so make it according to policy.
1492
def make_directory(transport):
1493
transport.mkdir('.')
1495
def redirected(transport, e, redirection_notice):
1496
note(redirection_notice)
1497
return transport._redirected_to(e.source, e.target)
1499
transport = do_catching_redirections(make_directory, transport,
1501
except errors.FileExists:
1502
if not use_existing_dir:
1504
except errors.NoSuchFile:
1505
if not create_prefix:
1507
transport.create_prefix()
1509
require_stacking = (stacked_on is not None)
1510
# Now the target directory exists, but doesn't have a .bzr
1511
# directory. So we need to create it, along with any work to create
1512
# all of the dependent branches, etc.
1514
result = self.initialize_on_transport(transport)
1515
if repo_format_name:
1517
# use a custom format
1518
result._format.repository_format = \
1519
repository.network_format_registry.get(repo_format_name)
1520
except AttributeError:
1521
# The format didn't permit it to be set.
1523
# A repository is desired, either in-place or shared.
1524
repository_policy = result.determine_repository_policy(
1525
force_new_repo, stacked_on, stack_on_pwd,
1526
require_stacking=require_stacking)
1527
result_repo, is_new_repo = repository_policy.acquire_repository(
1528
make_working_trees, shared_repo)
1529
if not require_stacking and repository_policy._require_stacking:
1530
require_stacking = True
1531
result._format.require_stacking()
1532
result_repo.lock_write()
1535
repository_policy = None
1536
return result_repo, result, require_stacking, repository_policy
1538
def _initialize_on_transport_vfs(self, transport):
1539
"""Initialize a new bzrdir using VFS calls.
1541
:param transport: The transport to create the .bzr directory in.
1544
# Since we are creating a .bzr directory, inherit the
1343
# Since we don't have a .bzr directory, inherit the
1545
1344
# mode from the root directory
1546
1345
temp_control = lockable_files.LockableFiles(transport,
1547
1346
'', lockable_files.TransportLock)
1598
1423
raise NotImplementedError(self._open)
1600
def _supply_sub_formats_to(self, other_format):
1601
"""Give other_format the same values for sub formats as this has.
1603
This method is expected to be used when parameterising a
1604
RemoteBzrDirFormat instance with the parameters from a
1605
BzrDirMetaFormat1 instance.
1607
:param other_format: other_format is a format which should be
1608
compatible with whatever sub formats are supported by self.
1426
def register_format(klass, format):
1427
klass._formats[format.get_format_string()] = format
1430
def register_control_format(klass, format):
1431
"""Register a format that does not use '.bzr' for its control dir.
1433
TODO: This should be pulled up into a 'ControlDirFormat' base class
1434
which BzrDirFormat can inherit from, and renamed to register_format
1435
there. It has been done without that for now for simplicity of
1438
klass._control_formats.append(format)
1441
def register_control_server_format(klass, format):
1442
"""Register a control format for client-server environments.
1444
These formats will be tried before ones registered with
1445
register_control_format. This gives implementations that decide to the
1446
chance to grab it before anything looks at the contents of the format
1449
klass._control_server_formats.append(format)
1452
@symbol_versioning.deprecated_method(symbol_versioning.zero_fourteen)
1453
def set_default_format(klass, format):
1454
klass._set_default_format(format)
1457
def _set_default_format(klass, format):
1458
"""Set default format (for testing behavior of defaults only)"""
1459
klass._default_format = format
1463
return self.get_format_string().rstrip()
1466
def unregister_format(klass, format):
1467
assert klass._formats[format.get_format_string()] is format
1468
del klass._formats[format.get_format_string()]
1471
def unregister_control_format(klass, format):
1472
klass._control_formats.remove(format)
1475
class BzrDirFormat4(BzrDirFormat):
1476
"""Bzr dir format 4.
1478
This format is a combined format for working tree, branch and repository.
1480
- Format 1 working trees [always]
1481
- Format 4 branches [always]
1482
- Format 4 repositories [always]
1484
This format is deprecated: it indexes texts using a text it which is
1485
removed in format 5; write support for this format has been removed.
1488
_lock_class = lockable_files.TransportLock
1490
def get_format_string(self):
1491
"""See BzrDirFormat.get_format_string()."""
1492
return "Bazaar-NG branch, format 0.0.4\n"
1494
def get_format_description(self):
1495
"""See BzrDirFormat.get_format_description()."""
1496
return "All-in-one format 4"
1498
def get_converter(self, format=None):
1499
"""See BzrDirFormat.get_converter()."""
1500
# there is one and only one upgrade path here.
1501
return ConvertBzrDir4To5()
1503
def initialize_on_transport(self, transport):
1504
"""Format 4 branches cannot be created."""
1505
raise errors.UninitializableFormat(self)
1507
def is_supported(self):
1508
"""Format 4 is not supported.
1510
It is not supported because the model changed from 4 to 5 and the
1511
conversion logic is expensive - so doing it on the fly was not
1516
def _open(self, transport):
1517
"""See BzrDirFormat._open."""
1518
return BzrDir4(transport, self)
1520
def __return_repository_format(self):
1521
"""Circular import protection."""
1522
from bzrlib.repofmt.weaverepo import RepositoryFormat4
1523
return RepositoryFormat4()
1524
repository_format = property(__return_repository_format)
1527
class BzrDirFormat5(BzrDirFormat):
1528
"""Bzr control format 5.
1530
This format is a combined format for working tree, branch and repository.
1532
- Format 2 working trees [always]
1533
- Format 4 branches [always]
1534
- Format 5 repositories [always]
1535
Unhashed stores in the repository.
1538
_lock_class = lockable_files.TransportLock
1540
def get_format_string(self):
1541
"""See BzrDirFormat.get_format_string()."""
1542
return "Bazaar-NG branch, format 5\n"
1544
def get_format_description(self):
1545
"""See BzrDirFormat.get_format_description()."""
1546
return "All-in-one format 5"
1548
def get_converter(self, format=None):
1549
"""See BzrDirFormat.get_converter()."""
1550
# there is one and only one upgrade path here.
1551
return ConvertBzrDir5To6()
1553
def _initialize_for_clone(self, url):
1554
return self.initialize_on_transport(get_transport(url), _cloning=True)
1556
def initialize_on_transport(self, transport, _cloning=False):
1557
"""Format 5 dirs always have working tree, branch and repository.
1559
Except when they are being cloned.
1561
from bzrlib.branch import BzrBranchFormat4
1562
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1563
from bzrlib.workingtree import WorkingTreeFormat2
1564
result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
1565
RepositoryFormat5().initialize(result, _internal=True)
1567
branch = BzrBranchFormat4().initialize(result)
1569
WorkingTreeFormat2().initialize(result)
1570
except errors.NotLocalUrl:
1571
# Even though we can't access the working tree, we need to
1572
# create its control files.
1573
WorkingTreeFormat2().stub_initialize_remote(branch.control_files)
1576
def _open(self, transport):
1577
"""See BzrDirFormat._open."""
1578
return BzrDir5(transport, self)
1580
def __return_repository_format(self):
1581
"""Circular import protection."""
1582
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1583
return RepositoryFormat5()
1584
repository_format = property(__return_repository_format)
1587
class BzrDirFormat6(BzrDirFormat):
1588
"""Bzr control format 6.
1590
This format is a combined format for working tree, branch and repository.
1592
- Format 2 working trees [always]
1593
- Format 4 branches [always]
1594
- Format 6 repositories [always]
1597
_lock_class = lockable_files.TransportLock
1599
def get_format_string(self):
1600
"""See BzrDirFormat.get_format_string()."""
1601
return "Bazaar-NG branch, format 6\n"
1603
def get_format_description(self):
1604
"""See BzrDirFormat.get_format_description()."""
1605
return "All-in-one format 6"
1607
def get_converter(self, format=None):
1608
"""See BzrDirFormat.get_converter()."""
1609
# there is one and only one upgrade path here.
1610
return ConvertBzrDir6ToMeta()
1612
def _initialize_for_clone(self, url):
1613
return self.initialize_on_transport(get_transport(url), _cloning=True)
1615
def initialize_on_transport(self, transport, _cloning=False):
1616
"""Format 6 dirs always have working tree, branch and repository.
1618
Except when they are being cloned.
1620
from bzrlib.branch import BzrBranchFormat4
1621
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1622
from bzrlib.workingtree import WorkingTreeFormat2
1623
result = super(BzrDirFormat6, self).initialize_on_transport(transport)
1624
RepositoryFormat6().initialize(result, _internal=True)
1626
branch = BzrBranchFormat4().initialize(result)
1628
WorkingTreeFormat2().initialize(result)
1629
except errors.NotLocalUrl:
1630
# Even though we can't access the working tree, we need to
1631
# create its control files.
1632
WorkingTreeFormat2().stub_initialize_remote(branch.control_files)
1635
def _open(self, transport):
1636
"""See BzrDirFormat._open."""
1637
return BzrDir6(transport, self)
1639
def __return_repository_format(self):
1640
"""Circular import protection."""
1641
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1642
return RepositoryFormat6()
1643
repository_format = property(__return_repository_format)
1613
1646
class BzrDirMetaFormat1(BzrDirFormat):
1645
1675
def get_branch_format(self):
1646
1676
if self._branch_format is None:
1647
from bzrlib.branch import format_registry as branch_format_registry
1648
self._branch_format = branch_format_registry.get_default()
1677
from bzrlib.branch import BranchFormat
1678
self._branch_format = BranchFormat.get_default_format()
1649
1679
return self._branch_format
1651
1681
def set_branch_format(self, format):
1652
1682
self._branch_format = format
1654
def require_stacking(self, stack_on=None, possible_transports=None,
1656
"""We have a request to stack, try to ensure the formats support it.
1658
:param stack_on: If supplied, it is the URL to a branch that we want to
1659
stack on. Check to see if that format supports stacking before
1662
# Stacking is desired. requested by the target, but does the place it
1663
# points at support stacking? If it doesn't then we should
1664
# not implicitly upgrade. We check this here.
1665
new_repo_format = None
1666
new_branch_format = None
1668
# a bit of state for get_target_branch so that we don't try to open it
1669
# 2 times, for both repo *and* branch
1670
target = [None, False, None] # target_branch, checked, upgrade anyway
1671
def get_target_branch():
1673
# We've checked, don't check again
1675
if stack_on is None:
1676
# No target format, that means we want to force upgrading
1677
target[:] = [None, True, True]
1680
target_dir = BzrDir.open(stack_on,
1681
possible_transports=possible_transports)
1682
except errors.NotBranchError:
1683
# Nothing there, don't change formats
1684
target[:] = [None, True, False]
1686
except errors.JailBreak:
1687
# JailBreak, JFDI and upgrade anyway
1688
target[:] = [None, True, True]
1691
target_branch = target_dir.open_branch()
1692
except errors.NotBranchError:
1693
# No branch, don't upgrade formats
1694
target[:] = [None, True, False]
1696
target[:] = [target_branch, True, False]
1699
if (not _skip_repo and
1700
not self.repository_format.supports_external_lookups):
1701
# We need to upgrade the Repository.
1702
target_branch, _, do_upgrade = get_target_branch()
1703
if target_branch is None:
1704
# We don't have a target branch, should we upgrade anyway?
1706
# stack_on is inaccessible, JFDI.
1707
# TODO: bad monkey, hard-coded formats...
1708
if self.repository_format.rich_root_data:
1709
new_repo_format = knitpack_repo.RepositoryFormatKnitPack5RichRoot()
1711
new_repo_format = knitpack_repo.RepositoryFormatKnitPack5()
1713
# If the target already supports stacking, then we know the
1714
# project is already able to use stacking, so auto-upgrade
1716
new_repo_format = target_branch.repository._format
1717
if not new_repo_format.supports_external_lookups:
1718
# target doesn't, source doesn't, so don't auto upgrade
1720
new_repo_format = None
1721
if new_repo_format is not None:
1722
self.repository_format = new_repo_format
1723
note('Source repository format does not support stacking,'
1724
' using format:\n %s',
1725
new_repo_format.get_format_description())
1727
if not self.get_branch_format().supports_stacking():
1728
# We just checked the repo, now lets check if we need to
1729
# upgrade the branch format
1730
target_branch, _, do_upgrade = get_target_branch()
1731
if target_branch is None:
1733
# TODO: bad monkey, hard-coded formats...
1734
from bzrlib.branch import BzrBranchFormat7
1735
new_branch_format = BzrBranchFormat7()
1737
new_branch_format = target_branch._format
1738
if not new_branch_format.supports_stacking():
1739
new_branch_format = None
1740
if new_branch_format is not None:
1741
# Does support stacking, use its format.
1742
self.set_branch_format(new_branch_format)
1743
note('Source branch format does not support stacking,'
1744
' using format:\n %s',
1745
new_branch_format.get_format_description())
1747
1684
def get_converter(self, format=None):
1748
1685
"""See BzrDirFormat.get_converter()."""
1749
1686
if format is None:
1821
1728
__set_workingtree_format)
1731
# Register bzr control format
1732
BzrDirFormat.register_control_format(BzrDirFormat)
1824
1734
# Register bzr formats
1825
BzrProber.formats.register(BzrDirMetaFormat1.get_format_string(),
1827
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1830
class ConvertMetaToMeta(controldir.Converter):
1735
BzrDirFormat.register_format(BzrDirFormat4())
1736
BzrDirFormat.register_format(BzrDirFormat5())
1737
BzrDirFormat.register_format(BzrDirFormat6())
1738
__default_format = BzrDirMetaFormat1()
1739
BzrDirFormat.register_format(__default_format)
1740
BzrDirFormat._default_format = __default_format
1743
class Converter(object):
1744
"""Converts a disk format object from one format to another."""
1746
def convert(self, to_convert, pb):
1747
"""Perform the conversion of to_convert, giving feedback via pb.
1749
:param to_convert: The disk object to convert.
1750
:param pb: a progress bar to use for progress information.
1753
def step(self, message):
1754
"""Update the pb by a step."""
1756
self.pb.update(message, self.count, self.total)
1759
class ConvertBzrDir4To5(Converter):
1760
"""Converts format 4 bzr dirs to format 5."""
1763
super(ConvertBzrDir4To5, self).__init__()
1764
self.converted_revs = set()
1765
self.absent_revisions = set()
1769
def convert(self, to_convert, pb):
1770
"""See Converter.convert()."""
1771
self.bzrdir = to_convert
1773
self.pb.note('starting upgrade from format 4 to 5')
1774
if isinstance(self.bzrdir.transport, LocalTransport):
1775
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
1776
self._convert_to_weaves()
1777
return BzrDir.open(self.bzrdir.root_transport.base)
1779
def _convert_to_weaves(self):
1780
self.pb.note('note: upgrade may be faster if all store files are ungzipped first')
1783
stat = self.bzrdir.transport.stat('weaves')
1784
if not S_ISDIR(stat.st_mode):
1785
self.bzrdir.transport.delete('weaves')
1786
self.bzrdir.transport.mkdir('weaves')
1787
except errors.NoSuchFile:
1788
self.bzrdir.transport.mkdir('weaves')
1789
# deliberately not a WeaveFile as we want to build it up slowly.
1790
self.inv_weave = Weave('inventory')
1791
# holds in-memory weaves for all files
1792
self.text_weaves = {}
1793
self.bzrdir.transport.delete('branch-format')
1794
self.branch = self.bzrdir.open_branch()
1795
self._convert_working_inv()
1796
rev_history = self.branch.revision_history()
1797
# to_read is a stack holding the revisions we still need to process;
1798
# appending to it adds new highest-priority revisions
1799
self.known_revisions = set(rev_history)
1800
self.to_read = rev_history[-1:]
1802
rev_id = self.to_read.pop()
1803
if (rev_id not in self.revisions
1804
and rev_id not in self.absent_revisions):
1805
self._load_one_rev(rev_id)
1807
to_import = self._make_order()
1808
for i, rev_id in enumerate(to_import):
1809
self.pb.update('converting revision', i, len(to_import))
1810
self._convert_one_rev(rev_id)
1812
self._write_all_weaves()
1813
self._write_all_revs()
1814
self.pb.note('upgraded to weaves:')
1815
self.pb.note(' %6d revisions and inventories', len(self.revisions))
1816
self.pb.note(' %6d revisions not present', len(self.absent_revisions))
1817
self.pb.note(' %6d texts', self.text_count)
1818
self._cleanup_spare_files_after_format4()
1819
self.branch.control_files.put_utf8('branch-format', BzrDirFormat5().get_format_string())
1821
def _cleanup_spare_files_after_format4(self):
1822
# FIXME working tree upgrade foo.
1823
for n in 'merged-patches', 'pending-merged-patches':
1825
## assert os.path.getsize(p) == 0
1826
self.bzrdir.transport.delete(n)
1827
except errors.NoSuchFile:
1829
self.bzrdir.transport.delete_tree('inventory-store')
1830
self.bzrdir.transport.delete_tree('text-store')
1832
def _convert_working_inv(self):
1833
inv = xml4.serializer_v4.read_inventory(
1834
self.branch.control_files.get('inventory'))
1835
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv, working=True)
1836
# FIXME inventory is a working tree change.
1837
self.branch.control_files.put('inventory', StringIO(new_inv_xml))
1839
def _write_all_weaves(self):
1840
controlweaves = WeaveStore(self.bzrdir.transport, prefixed=False)
1841
weave_transport = self.bzrdir.transport.clone('weaves')
1842
weaves = WeaveStore(weave_transport, prefixed=False)
1843
transaction = WriteTransaction()
1847
for file_id, file_weave in self.text_weaves.items():
1848
self.pb.update('writing weave', i, len(self.text_weaves))
1849
weaves._put_weave(file_id, file_weave, transaction)
1851
self.pb.update('inventory', 0, 1)
1852
controlweaves._put_weave('inventory', self.inv_weave, transaction)
1853
self.pb.update('inventory', 1, 1)
1857
def _write_all_revs(self):
1858
"""Write all revisions out in new form."""
1859
self.bzrdir.transport.delete_tree('revision-store')
1860
self.bzrdir.transport.mkdir('revision-store')
1861
revision_transport = self.bzrdir.transport.clone('revision-store')
1863
_revision_store = TextRevisionStore(TextStore(revision_transport,
1867
transaction = WriteTransaction()
1868
for i, rev_id in enumerate(self.converted_revs):
1869
self.pb.update('write revision', i, len(self.converted_revs))
1870
_revision_store.add_revision(self.revisions[rev_id], transaction)
1874
def _load_one_rev(self, rev_id):
1875
"""Load a revision object into memory.
1877
Any parents not either loaded or abandoned get queued to be
1879
self.pb.update('loading revision',
1880
len(self.revisions),
1881
len(self.known_revisions))
1882
if not self.branch.repository.has_revision(rev_id):
1884
self.pb.note('revision {%s} not present in branch; '
1885
'will be converted as a ghost',
1887
self.absent_revisions.add(rev_id)
1889
rev = self.branch.repository._revision_store.get_revision(rev_id,
1890
self.branch.repository.get_transaction())
1891
for parent_id in rev.parent_ids:
1892
self.known_revisions.add(parent_id)
1893
self.to_read.append(parent_id)
1894
self.revisions[rev_id] = rev
1896
def _load_old_inventory(self, rev_id):
1897
assert rev_id not in self.converted_revs
1898
old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
1899
inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
1900
inv.revision_id = rev_id
1901
rev = self.revisions[rev_id]
1902
if rev.inventory_sha1:
1903
assert rev.inventory_sha1 == sha_string(old_inv_xml), \
1904
'inventory sha mismatch for {%s}' % rev_id
1907
def _load_updated_inventory(self, rev_id):
1908
assert rev_id in self.converted_revs
1909
inv_xml = self.inv_weave.get_text(rev_id)
1910
inv = xml5.serializer_v5.read_inventory_from_string(inv_xml)
1913
def _convert_one_rev(self, rev_id):
1914
"""Convert revision and all referenced objects to new format."""
1915
rev = self.revisions[rev_id]
1916
inv = self._load_old_inventory(rev_id)
1917
present_parents = [p for p in rev.parent_ids
1918
if p not in self.absent_revisions]
1919
self._convert_revision_contents(rev, inv, present_parents)
1920
self._store_new_inv(rev, inv, present_parents)
1921
self.converted_revs.add(rev_id)
1923
def _store_new_inv(self, rev, inv, present_parents):
1924
# the XML is now updated with text versions
1926
entries = inv.iter_entries()
1928
for path, ie in entries:
1929
assert getattr(ie, 'revision', None) is not None, \
1930
'no revision on {%s} in {%s}' % \
1931
(file_id, rev.revision_id)
1932
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
1933
new_inv_sha1 = sha_string(new_inv_xml)
1934
self.inv_weave.add_lines(rev.revision_id,
1936
new_inv_xml.splitlines(True))
1937
rev.inventory_sha1 = new_inv_sha1
1939
def _convert_revision_contents(self, rev, inv, present_parents):
1940
"""Convert all the files within a revision.
1942
Also upgrade the inventory to refer to the text revision ids."""
1943
rev_id = rev.revision_id
1944
mutter('converting texts of revision {%s}',
1946
parent_invs = map(self._load_updated_inventory, present_parents)
1947
entries = inv.iter_entries()
1949
for path, ie in entries:
1950
self._convert_file_version(rev, ie, parent_invs)
1952
def _convert_file_version(self, rev, ie, parent_invs):
1953
"""Convert one version of one file.
1955
The file needs to be added into the weave if it is a merge
1956
of >=2 parents or if it's changed from its parent.
1958
file_id = ie.file_id
1959
rev_id = rev.revision_id
1960
w = self.text_weaves.get(file_id)
1963
self.text_weaves[file_id] = w
1964
text_changed = False
1965
parent_candiate_entries = ie.parent_candidates(parent_invs)
1966
for old_revision in parent_candiate_entries.keys():
1967
# if this fails, its a ghost ?
1968
assert old_revision in self.converted_revs, \
1969
"Revision {%s} not in converted_revs" % old_revision
1970
heads = graph.Graph(self).heads(parent_candiate_entries.keys())
1971
# XXX: Note that this is unordered - and this is tolerable because
1972
# the previous code was also unordered.
1973
previous_entries = dict((head, parent_candiate_entries[head]) for head
1975
self.snapshot_ie(previous_entries, ie, w, rev_id)
1977
assert getattr(ie, 'revision', None) is not None
1979
def get_parents(self, revision_ids):
1980
for revision_id in revision_ids:
1981
yield self.revisions[revision_id].parent_ids
1983
def snapshot_ie(self, previous_revisions, ie, w, rev_id):
1984
# TODO: convert this logic, which is ~= snapshot to
1985
# a call to:. This needs the path figured out. rather than a work_tree
1986
# a v4 revision_tree can be given, or something that looks enough like
1987
# one to give the file content to the entry if it needs it.
1988
# and we need something that looks like a weave store for snapshot to
1990
#ie.snapshot(rev, PATH, previous_revisions, REVISION_TREE, InMemoryWeaveStore(self.text_weaves))
1991
if len(previous_revisions) == 1:
1992
previous_ie = previous_revisions.values()[0]
1993
if ie._unchanged(previous_ie):
1994
ie.revision = previous_ie.revision
1997
text = self.branch.repository.weave_store.get(ie.text_id)
1998
file_lines = text.readlines()
1999
assert sha_strings(file_lines) == ie.text_sha1
2000
assert sum(map(len, file_lines)) == ie.text_size
2001
w.add_lines(rev_id, previous_revisions, file_lines)
2002
self.text_count += 1
2004
w.add_lines(rev_id, previous_revisions, [])
2005
ie.revision = rev_id
2007
def _make_order(self):
2008
"""Return a suitable order for importing revisions.
2010
The order must be such that an revision is imported after all
2011
its (present) parents.
2013
todo = set(self.revisions.keys())
2014
done = self.absent_revisions.copy()
2017
# scan through looking for a revision whose parents
2019
for rev_id in sorted(list(todo)):
2020
rev = self.revisions[rev_id]
2021
parent_ids = set(rev.parent_ids)
2022
if parent_ids.issubset(done):
2023
# can take this one now
2024
order.append(rev_id)
2030
class ConvertBzrDir5To6(Converter):
2031
"""Converts format 5 bzr dirs to format 6."""
2033
def convert(self, to_convert, pb):
2034
"""See Converter.convert()."""
2035
self.bzrdir = to_convert
2037
self.pb.note('starting upgrade from format 5 to 6')
2038
self._convert_to_prefixed()
2039
return BzrDir.open(self.bzrdir.root_transport.base)
2041
def _convert_to_prefixed(self):
2042
from bzrlib.store import TransportStore
2043
self.bzrdir.transport.delete('branch-format')
2044
for store_name in ["weaves", "revision-store"]:
2045
self.pb.note("adding prefixes to %s" % store_name)
2046
store_transport = self.bzrdir.transport.clone(store_name)
2047
store = TransportStore(store_transport, prefixed=True)
2048
for urlfilename in store_transport.list_dir('.'):
2049
filename = urlutils.unescape(urlfilename)
2050
if (filename.endswith(".weave") or
2051
filename.endswith(".gz") or
2052
filename.endswith(".sig")):
2053
file_id = os.path.splitext(filename)[0]
2056
prefix_dir = store.hash_prefix(file_id)
2057
# FIXME keep track of the dirs made RBC 20060121
2059
store_transport.move(filename, prefix_dir + '/' + filename)
2060
except errors.NoSuchFile: # catches missing dirs strangely enough
2061
store_transport.mkdir(prefix_dir)
2062
store_transport.move(filename, prefix_dir + '/' + filename)
2063
self.bzrdir._control_files.put_utf8('branch-format', BzrDirFormat6().get_format_string())
2066
class ConvertBzrDir6ToMeta(Converter):
2067
"""Converts format 6 bzr dirs to metadirs."""
2069
def convert(self, to_convert, pb):
2070
"""See Converter.convert()."""
2071
from bzrlib.repofmt.weaverepo import RepositoryFormat7
2072
from bzrlib.branch import BzrBranchFormat5
2073
self.bzrdir = to_convert
2076
self.total = 20 # the steps we know about
2077
self.garbage_inventories = []
2079
self.pb.note('starting upgrade from format 6 to metadir')
2080
self.bzrdir._control_files.put_utf8('branch-format', "Converting to format 6")
2081
# its faster to move specific files around than to open and use the apis...
2082
# first off, nuke ancestry.weave, it was never used.
2084
self.step('Removing ancestry.weave')
2085
self.bzrdir.transport.delete('ancestry.weave')
2086
except errors.NoSuchFile:
2088
# find out whats there
2089
self.step('Finding branch files')
2090
last_revision = self.bzrdir.open_branch().last_revision()
2091
bzrcontents = self.bzrdir.transport.list_dir('.')
2092
for name in bzrcontents:
2093
if name.startswith('basis-inventory.'):
2094
self.garbage_inventories.append(name)
2095
# create new directories for repository, working tree and branch
2096
self.dir_mode = self.bzrdir._control_files._dir_mode
2097
self.file_mode = self.bzrdir._control_files._file_mode
2098
repository_names = [('inventory.weave', True),
2099
('revision-store', True),
2101
self.step('Upgrading repository ')
2102
self.bzrdir.transport.mkdir('repository', mode=self.dir_mode)
2103
self.make_lock('repository')
2104
# we hard code the formats here because we are converting into
2105
# the meta format. The meta format upgrader can take this to a
2106
# future format within each component.
2107
self.put_format('repository', RepositoryFormat7())
2108
for entry in repository_names:
2109
self.move_entry('repository', entry)
2111
self.step('Upgrading branch ')
2112
self.bzrdir.transport.mkdir('branch', mode=self.dir_mode)
2113
self.make_lock('branch')
2114
self.put_format('branch', BzrBranchFormat5())
2115
branch_files = [('revision-history', True),
2116
('branch-name', True),
2118
for entry in branch_files:
2119
self.move_entry('branch', entry)
2121
checkout_files = [('pending-merges', True),
2122
('inventory', True),
2123
('stat-cache', False)]
2124
# If a mandatory checkout file is not present, the branch does not have
2125
# a functional checkout. Do not create a checkout in the converted
2127
for name, mandatory in checkout_files:
2128
if mandatory and name not in bzrcontents:
2129
has_checkout = False
2133
if not has_checkout:
2134
self.pb.note('No working tree.')
2135
# If some checkout files are there, we may as well get rid of them.
2136
for name, mandatory in checkout_files:
2137
if name in bzrcontents:
2138
self.bzrdir.transport.delete(name)
2140
from bzrlib.workingtree import WorkingTreeFormat3
2141
self.step('Upgrading working tree')
2142
self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
2143
self.make_lock('checkout')
2145
'checkout', WorkingTreeFormat3())
2146
self.bzrdir.transport.delete_multi(
2147
self.garbage_inventories, self.pb)
2148
for entry in checkout_files:
2149
self.move_entry('checkout', entry)
2150
if last_revision is not None:
2151
self.bzrdir._control_files.put_utf8(
2152
'checkout/last-revision', last_revision)
2153
self.bzrdir._control_files.put_utf8(
2154
'branch-format', BzrDirMetaFormat1().get_format_string())
2155
return BzrDir.open(self.bzrdir.root_transport.base)
2157
def make_lock(self, name):
2158
"""Make a lock for the new control dir name."""
2159
self.step('Make %s lock' % name)
2160
ld = lockdir.LockDir(self.bzrdir.transport,
2162
file_modebits=self.file_mode,
2163
dir_modebits=self.dir_mode)
2166
def move_entry(self, new_dir, entry):
2167
"""Move then entry name into new_dir."""
2169
mandatory = entry[1]
2170
self.step('Moving %s' % name)
2172
self.bzrdir.transport.move(name, '%s/%s' % (new_dir, name))
2173
except errors.NoSuchFile:
2177
def put_format(self, dirname, format):
2178
self.bzrdir._control_files.put_utf8('%s/format' % dirname, format.get_format_string())
2181
class ConvertMetaToMeta(Converter):
1831
2182
"""Converts the components of metadirs."""
1833
2184
def __init__(self, target_format):
1887
2227
# TODO: conversions of Branch and Tree should be done by
1888
2228
# InterXFormat lookups
1889
2229
if (isinstance(tree, workingtree.WorkingTree3) and
1890
not isinstance(tree, workingtree_4.DirStateWorkingTree) and
2230
not isinstance(tree, workingtree_4.WorkingTree4) and
1891
2231
isinstance(self.target_format.workingtree_format,
1892
workingtree_4.DirStateWorkingTreeFormat)):
2232
workingtree_4.WorkingTreeFormat4)):
1893
2233
workingtree_4.Converter3to4().convert(tree)
1894
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1895
not isinstance(tree, workingtree_4.WorkingTree5) and
1896
isinstance(self.target_format.workingtree_format,
1897
workingtree_4.WorkingTreeFormat5)):
1898
workingtree_4.Converter4to5().convert(tree)
1899
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
1900
not isinstance(tree, workingtree_4.WorkingTree6) and
1901
isinstance(self.target_format.workingtree_format,
1902
workingtree_4.WorkingTreeFormat6)):
1903
workingtree_4.Converter4or5to6().convert(tree)
1905
2234
return to_convert
1908
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
1911
class RepositoryAcquisitionPolicy(object):
1912
"""Abstract base class for repository acquisition policies.
1914
A repository acquisition policy decides how a BzrDir acquires a repository
1915
for a branch that is being created. The most basic policy decision is
1916
whether to create a new repository or use an existing one.
1918
def __init__(self, stack_on, stack_on_pwd, require_stacking):
1921
:param stack_on: A location to stack on
1922
:param stack_on_pwd: If stack_on is relative, the location it is
1924
:param require_stacking: If True, it is a failure to not stack.
1926
self._stack_on = stack_on
1927
self._stack_on_pwd = stack_on_pwd
1928
self._require_stacking = require_stacking
1930
def configure_branch(self, branch):
1931
"""Apply any configuration data from this policy to the branch.
1933
Default implementation sets repository stacking.
1935
if self._stack_on is None:
1937
if self._stack_on_pwd is None:
1938
stack_on = self._stack_on
1941
stack_on = urlutils.rebase_url(self._stack_on,
1944
except errors.InvalidRebaseURLs:
1945
stack_on = self._get_full_stack_on()
1947
branch.set_stacked_on_url(stack_on)
1948
except (errors.UnstackableBranchFormat,
1949
errors.UnstackableRepositoryFormat):
1950
if self._require_stacking:
1953
def requires_stacking(self):
1954
"""Return True if this policy requires stacking."""
1955
return self._stack_on is not None and self._require_stacking
1957
def _get_full_stack_on(self):
1958
"""Get a fully-qualified URL for the stack_on location."""
1959
if self._stack_on is None:
1961
if self._stack_on_pwd is None:
1962
return self._stack_on
1964
return urlutils.join(self._stack_on_pwd, self._stack_on)
1966
def _add_fallback(self, repository, possible_transports=None):
1967
"""Add a fallback to the supplied repository, if stacking is set."""
1968
stack_on = self._get_full_stack_on()
1969
if stack_on is None:
1972
stacked_dir = BzrDir.open(stack_on,
1973
possible_transports=possible_transports)
1974
except errors.JailBreak:
1975
# We keep the stacking details, but we are in the server code so
1976
# actually stacking is not needed.
1979
stacked_repo = stacked_dir.open_branch().repository
1980
except errors.NotBranchError:
1981
stacked_repo = stacked_dir.open_repository()
1983
repository.add_fallback_repository(stacked_repo)
1984
except errors.UnstackableRepositoryFormat:
1985
if self._require_stacking:
1988
self._require_stacking = True
1990
def acquire_repository(self, make_working_trees=None, shared=False):
1991
"""Acquire a repository for this bzrdir.
1993
Implementations may create a new repository or use a pre-exising
1995
:param make_working_trees: If creating a repository, set
1996
make_working_trees to this value (if non-None)
1997
:param shared: If creating a repository, make it shared if True
1998
:return: A repository, is_new_flag (True if the repository was
2001
raise NotImplemented(RepositoryAcquisitionPolicy.acquire_repository)
2004
class CreateRepository(RepositoryAcquisitionPolicy):
2005
"""A policy of creating a new repository"""
2007
def __init__(self, bzrdir, stack_on=None, stack_on_pwd=None,
2008
require_stacking=False):
2011
:param bzrdir: The bzrdir to create the repository on.
2012
:param stack_on: A location to stack on
2013
:param stack_on_pwd: If stack_on is relative, the location it is
2016
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2018
self._bzrdir = bzrdir
2020
def acquire_repository(self, make_working_trees=None, shared=False):
2021
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2023
Creates the desired repository in the bzrdir we already have.
2025
stack_on = self._get_full_stack_on()
2027
format = self._bzrdir._format
2028
format.require_stacking(stack_on=stack_on,
2029
possible_transports=[self._bzrdir.root_transport])
2030
if not self._require_stacking:
2031
# We have picked up automatic stacking somewhere.
2032
note('Using default stacking branch %s at %s', self._stack_on,
2034
repository = self._bzrdir.create_repository(shared=shared)
2035
self._add_fallback(repository,
2036
possible_transports=[self._bzrdir.transport])
2037
if make_working_trees is not None:
2038
repository.set_make_working_trees(make_working_trees)
2039
return repository, True
2042
class UseExistingRepository(RepositoryAcquisitionPolicy):
2043
"""A policy of reusing an existing repository"""
2045
def __init__(self, repository, stack_on=None, stack_on_pwd=None,
2046
require_stacking=False):
2049
:param repository: The repository to use.
2050
:param stack_on: A location to stack on
2051
:param stack_on_pwd: If stack_on is relative, the location it is
2054
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2056
self._repository = repository
2058
def acquire_repository(self, make_working_trees=None, shared=False):
2059
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2061
Returns an existing repository to use.
2063
self._add_fallback(self._repository,
2064
possible_transports=[self._repository.bzrdir.transport])
2065
return self._repository, False
2068
def register_metadir(registry, key,
2069
repository_format, help, native=True, deprecated=False,
2075
"""Register a metadir subformat.
2077
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
2078
by the Repository/Branch/WorkingTreeformats.
2080
:param repository_format: The fully-qualified repository format class
2082
:param branch_format: Fully-qualified branch format class name as
2084
:param tree_format: Fully-qualified tree format class name as
2087
# This should be expanded to support setting WorkingTree and Branch
2088
# formats, once BzrDirMetaFormat1 supports that.
2089
def _load(full_name):
2090
mod_name, factory_name = full_name.rsplit('.', 1)
2092
factory = pyutils.get_named_object(mod_name, factory_name)
2093
except ImportError, e:
2094
raise ImportError('failed to load %s: %s' % (full_name, e))
2095
except AttributeError:
2096
raise AttributeError('no factory %s in module %r'
2097
% (full_name, sys.modules[mod_name]))
2101
bd = BzrDirMetaFormat1()
2102
if branch_format is not None:
2103
bd.set_branch_format(_load(branch_format))
2104
if tree_format is not None:
2105
bd.workingtree_format = _load(tree_format)
2106
if repository_format is not None:
2107
bd.repository_format = _load(repository_format)
2109
registry.register(key, helper, help, native, deprecated, hidden,
2110
experimental, alias)
2112
register_metadir(controldir.format_registry, 'knit',
2237
# This is not in remote.py because it's small, and needs to be registered.
2238
# Putting it in remote.py creates a circular import problem.
2239
# we can make it a lazy object if the control formats is turned into something
2241
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2242
"""Format representing bzrdirs accessed via a smart server"""
2244
def get_format_description(self):
2245
return 'bzr remote bzrdir'
2248
def probe_transport(klass, transport):
2249
"""Return a RemoteBzrDirFormat object if it looks possible."""
2251
client = transport.get_smart_client()
2252
except (NotImplementedError, AttributeError,
2253
errors.TransportNotPossible):
2254
# no smart server, so not a branch for this format type.
2255
raise errors.NotBranchError(path=transport.base)
2257
# Send a 'hello' request in protocol version one, and decline to
2258
# open it if the server doesn't support our required version (2) so
2259
# that the VFS-based transport will do it.
2260
request = client.get_request()
2261
smart_protocol = protocol.SmartClientRequestProtocolOne(request)
2262
server_version = smart_protocol.query_version()
2263
if server_version != 2:
2264
raise errors.NotBranchError(path=transport.base)
2267
def initialize_on_transport(self, transport):
2269
# hand off the request to the smart server
2270
shared_medium = transport.get_shared_medium()
2271
except errors.NoSmartMedium:
2272
# TODO: lookup the local format from a server hint.
2273
local_dir_format = BzrDirMetaFormat1()
2274
return local_dir_format.initialize_on_transport(transport)
2275
client = _SmartClient(shared_medium)
2276
path = client.remote_path_from_transport(transport)
2277
response = _SmartClient(shared_medium).call('BzrDirFormat.initialize',
2279
assert response[0] in ('ok', ), 'unexpected response code %s' % (response,)
2280
return remote.RemoteBzrDir(transport)
2282
def _open(self, transport):
2283
return remote.RemoteBzrDir(transport)
2285
def __eq__(self, other):
2286
if not isinstance(other, RemoteBzrDirFormat):
2288
return self.get_format_description() == other.get_format_description()
2291
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
2294
class BzrDirFormatInfo(object):
2296
def __init__(self, native, deprecated, hidden):
2297
self.deprecated = deprecated
2298
self.native = native
2299
self.hidden = hidden
2302
class BzrDirFormatRegistry(registry.Registry):
2303
"""Registry of user-selectable BzrDir subformats.
2305
Differs from BzrDirFormat._control_formats in that it provides sub-formats,
2306
e.g. BzrDirMeta1 with weave repository. Also, it's more user-oriented.
2309
def register_metadir(self, key,
2310
repository_format, help, native=True, deprecated=False,
2314
"""Register a metadir subformat.
2316
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
2317
by the Repository format.
2319
:param repository_format: The fully-qualified repository format class
2321
:param branch_format: Fully-qualified branch format class name as
2323
:param tree_format: Fully-qualified tree format class name as
2326
# This should be expanded to support setting WorkingTree and Branch
2327
# formats, once BzrDirMetaFormat1 supports that.
2328
def _load(full_name):
2329
mod_name, factory_name = full_name.rsplit('.', 1)
2331
mod = __import__(mod_name, globals(), locals(),
2333
except ImportError, e:
2334
raise ImportError('failed to load %s: %s' % (full_name, e))
2336
factory = getattr(mod, factory_name)
2337
except AttributeError:
2338
raise AttributeError('no factory %s in module %r'
2343
bd = BzrDirMetaFormat1()
2344
if branch_format is not None:
2345
bd.set_branch_format(_load(branch_format))
2346
if tree_format is not None:
2347
bd.workingtree_format = _load(tree_format)
2348
if repository_format is not None:
2349
bd.repository_format = _load(repository_format)
2351
self.register(key, helper, help, native, deprecated, hidden)
2353
def register(self, key, factory, help, native=True, deprecated=False,
2355
"""Register a BzrDirFormat factory.
2357
The factory must be a callable that takes one parameter: the key.
2358
It must produce an instance of the BzrDirFormat when called.
2360
This function mainly exists to prevent the info object from being
2363
registry.Registry.register(self, key, factory, help,
2364
BzrDirFormatInfo(native, deprecated, hidden))
2366
def register_lazy(self, key, module_name, member_name, help, native=True,
2367
deprecated=False, hidden=False):
2368
registry.Registry.register_lazy(self, key, module_name, member_name,
2369
help, BzrDirFormatInfo(native, deprecated, hidden))
2371
def set_default(self, key):
2372
"""Set the 'default' key to be a clone of the supplied key.
2374
This method must be called once and only once.
2376
registry.Registry.register(self, 'default', self.get(key),
2377
self.get_help(key), info=self.get_info(key))
2379
def set_default_repository(self, key):
2380
"""Set the FormatRegistry default and Repository default.
2382
This is a transitional method while Repository.set_default_format
2385
if 'default' in self:
2386
self.remove('default')
2387
self.set_default(key)
2388
format = self.get('default')()
2389
assert isinstance(format, BzrDirMetaFormat1)
2391
def make_bzrdir(self, key):
2392
return self.get(key)()
2394
def help_topic(self, topic):
2395
output = textwrap.dedent("""\
2396
These formats can be used for creating branches, working trees, and
2400
default_realkey = None
2401
default_help = self.get_help('default')
2403
for key in self.keys():
2404
if key == 'default':
2406
help = self.get_help(key)
2407
if help == default_help:
2408
default_realkey = key
2410
help_pairs.append((key, help))
2412
def wrapped(key, help, info):
2414
help = '(native) ' + help
2415
return ':%s:\n%s\n\n' % (key,
2416
textwrap.fill(help, initial_indent=' ',
2417
subsequent_indent=' '))
2418
if default_realkey is not None:
2419
output += wrapped(default_realkey, '(default) %s' % default_help,
2420
self.get_info('default'))
2421
deprecated_pairs = []
2422
for key, help in help_pairs:
2423
info = self.get_info(key)
2426
elif info.deprecated:
2427
deprecated_pairs.append((key, help))
2429
output += wrapped(key, help, info)
2430
if len(deprecated_pairs) > 0:
2431
output += "Deprecated formats are shown below.\n\n"
2432
for key, help in deprecated_pairs:
2433
info = self.get_info(key)
2434
output += wrapped(key, help, info)
2439
format_registry = BzrDirFormatRegistry()
2440
format_registry.register('weave', BzrDirFormat6,
2441
'Pre-0.8 format. Slower than knit and does not'
2442
' support checkouts or shared repositories.',
2444
format_registry.register_metadir('knit',
2113
2445
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2114
2446
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
2115
2447
branch_format='bzrlib.branch.BzrBranchFormat5',
2448
tree_format='bzrlib.workingtree.WorkingTreeFormat3')
2449
format_registry.register_metadir('metaweave',
2450
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
2451
'Transitional format in 0.8. Slower than knit.',
2452
branch_format='bzrlib.branch.BzrBranchFormat5',
2116
2453
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
2118
2454
deprecated=True)
2119
register_metadir(controldir.format_registry, 'dirstate',
2455
format_registry.register_metadir('dirstate',
2120
2456
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2121
2457
help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
2122
2458
'above when accessed over the network.',
2124
2460
# this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
2125
2461
# directly from workingtree_4 triggers a circular import.
2126
2462
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2129
register_metadir(controldir.format_registry, 'dirstate-tags',
2464
format_registry.register_metadir('dirstate-tags',
2130
2465
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2131
2466
help='New in 0.15: Fast local operations and improved scaling for '
2132
2467
'network operations. Additionally adds support for tags.'
2133
2468
' Incompatible with bzr < 0.15.',
2134
2469
branch_format='bzrlib.branch.BzrBranchFormat6',
2135
2470
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2138
register_metadir(controldir.format_registry, 'rich-root',
2139
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
2140
help='New in 1.0. Better handling of tree roots. Incompatible with'
2142
branch_format='bzrlib.branch.BzrBranchFormat6',
2143
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2146
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
2472
format_registry.register_metadir('dirstate-with-subtree',
2147
2473
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2148
2474
help='New in 0.15: Fast local operations and improved scaling for '
2149
2475
'network operations. Additionally adds support for versioning nested '
2150
2476
'bzr branches. Incompatible with bzr < 0.15.',
2151
2477
branch_format='bzrlib.branch.BzrBranchFormat6',
2152
2478
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2156
register_metadir(controldir.format_registry, 'pack-0.92',
2157
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
2158
help='New in 0.92: Pack-based format with data compatible with '
2159
'dirstate-tags format repositories. Interoperates with '
2160
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2162
branch_format='bzrlib.branch.BzrBranchFormat6',
2163
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2165
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2166
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
2167
help='New in 0.92: Pack-based format with data compatible with '
2168
'dirstate-with-subtree format repositories. Interoperates with '
2169
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2171
branch_format='bzrlib.branch.BzrBranchFormat6',
2172
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2176
register_metadir(controldir.format_registry, 'rich-root-pack',
2177
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
2178
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
2179
'(needed for bzr-svn and bzr-git).',
2180
branch_format='bzrlib.branch.BzrBranchFormat6',
2181
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2184
register_metadir(controldir.format_registry, '1.6',
2185
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
2186
help='A format that allows a branch to indicate that there is another '
2187
'(stacked) repository that should be used to access data that is '
2188
'not present locally.',
2189
branch_format='bzrlib.branch.BzrBranchFormat7',
2190
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2193
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2194
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
2195
help='A variant of 1.6 that supports rich-root data '
2196
'(needed for bzr-svn and bzr-git).',
2197
branch_format='bzrlib.branch.BzrBranchFormat7',
2198
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2201
register_metadir(controldir.format_registry, '1.9',
2202
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2203
help='A repository format using B+tree indexes. These indexes '
2204
'are smaller in size, have smarter caching and provide faster '
2205
'performance for most operations.',
2206
branch_format='bzrlib.branch.BzrBranchFormat7',
2207
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2210
register_metadir(controldir.format_registry, '1.9-rich-root',
2211
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2212
help='A variant of 1.9 that supports rich-root data '
2213
'(needed for bzr-svn and bzr-git).',
2214
branch_format='bzrlib.branch.BzrBranchFormat7',
2215
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2218
register_metadir(controldir.format_registry, '1.14',
2219
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2220
help='A working-tree format that supports content filtering.',
2221
branch_format='bzrlib.branch.BzrBranchFormat7',
2222
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2224
register_metadir(controldir.format_registry, '1.14-rich-root',
2225
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2226
help='A variant of 1.14 that supports rich-root data '
2227
'(needed for bzr-svn and bzr-git).',
2228
branch_format='bzrlib.branch.BzrBranchFormat7',
2229
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2231
# The following un-numbered 'development' formats should always just be aliases.
2232
register_metadir(controldir.format_registry, 'development-subtree',
2233
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2aSubtree',
2234
help='Current development format, subtree variant. Can convert data to and '
2235
'from pack-0.92-subtree (and anything compatible with '
2236
'pack-0.92-subtree) format repositories. Repositories and branches in '
2237
'this format can only be read by bzr.dev. Please read '
2238
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2240
branch_format='bzrlib.branch.BzrBranchFormat7',
2241
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
2244
alias=False, # Restore to being an alias when an actual development subtree format is added
2245
# This current non-alias status is simply because we did not introduce a
2246
# chk based subtree format.
2248
register_metadir(controldir.format_registry, 'development5-subtree',
2249
'bzrlib.repofmt.knitpack_repo.RepositoryFormatPackDevelopment2Subtree',
2250
help='Development format, subtree variant. Can convert data to and '
2251
'from pack-0.92-subtree (and anything compatible with '
2252
'pack-0.92-subtree) format repositories. Repositories and branches in '
2253
'this format can only be read by bzr.dev. Please read '
2254
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
2256
branch_format='bzrlib.branch.BzrBranchFormat7',
2257
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
2263
# And the development formats above will have aliased one of the following:
2265
# Finally, the current format.
2266
register_metadir(controldir.format_registry, '2a',
2267
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2268
help='First format for bzr 2.0 series.\n'
2269
'Uses group-compress storage.\n'
2270
'Provides rich roots which are a one-way transition.\n',
2271
# 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
2272
# 'rich roots. Supported by bzr 1.16 and later.',
2273
branch_format='bzrlib.branch.BzrBranchFormat7',
2274
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
2278
# The following format should be an alias for the rich root equivalent
2279
# of the default format
2280
register_metadir(controldir.format_registry, 'default-rich-root',
2281
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
2282
branch_format='bzrlib.branch.BzrBranchFormat7',
2283
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
2288
# The current format that is made on 'bzr init'.
2289
format_name = config.GlobalConfig().get_user_option('default_format')
2290
if format_name is None:
2291
controldir.format_registry.set_default('2a')
2293
controldir.format_registry.set_default(format_name)
2295
# XXX 2010-08-20 JRV: There is still a lot of code relying on
2296
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc
2297
# get changed to ControlDir.create/ControlDir.open/etc this should be removed.
2298
format_registry = controldir.format_registry
2481
format_registry.set_default('dirstate-tags')