128
123
# No repo, no problem.
132
def _check_supported(format, allow_unsupported,
133
recommend_upgrade=True,
135
"""Give an error or warning on old formats.
137
:param format: may be any kind of format - workingtree, branch,
140
:param allow_unsupported: If true, allow opening
141
formats that are strongly deprecated, and which may
142
have limited functionality.
144
:param recommend_upgrade: If true (default), warn
145
the user through the ui object that they may wish
146
to upgrade the object.
148
# TODO: perhaps move this into a base Format class; it's not BzrDir
149
# specific. mbp 20070323
150
if not allow_unsupported and not format.is_supported():
151
# see open_downlevel to open legacy branches.
152
raise errors.UnsupportedFormatError(format=format)
153
if recommend_upgrade \
154
and getattr(format, 'upgrade_recommended', False):
155
ui.ui_factory.recommend_upgrade(
156
format.get_format_description(),
159
126
def clone_on_transport(self, transport, revision_id=None,
160
127
force_new_repo=False, preserve_stacking=False, stacked_on=None,
161
128
create_prefix=False, use_existing_dir=True, no_tree=False):
421
388
policy = self.determine_repository_policy(force_new_repo)
422
389
return policy.acquire_repository()[0]
391
def _find_source_repo(self, add_cleanup, source_branch):
392
"""Find the source branch and repo for a sprout operation.
394
This is helper intended for use by _sprout.
396
:returns: (source_branch, source_repository). Either or both may be
397
None. If not None, they will be read-locked (and their unlock(s)
398
scheduled via the add_cleanup param).
400
if source_branch is not None:
401
add_cleanup(source_branch.lock_read().unlock)
402
return source_branch, source_branch.repository
404
source_branch = self.open_branch()
405
source_repository = source_branch.repository
406
except errors.NotBranchError:
409
source_repository = self.open_repository()
410
except errors.NoRepositoryPresent:
411
source_repository = None
413
add_cleanup(source_repository.lock_read().unlock)
415
add_cleanup(source_branch.lock_read().unlock)
416
return source_branch, source_repository
418
def sprout(self, url, revision_id=None, force_new_repo=False,
419
recurse='down', possible_transports=None,
420
accelerator_tree=None, hardlink=False, stacked=False,
421
source_branch=None, create_tree_if_local=True):
422
"""Create a copy of this controldir prepared for use as a new line of
425
If url's last component does not exist, it will be created.
427
Attributes related to the identity of the source branch like
428
branch nickname will be cleaned, a working tree is created
429
whether one existed before or not; and a local branch is always
432
if revision_id is not None, then the clone operation may tune
433
itself to download less data.
434
:param accelerator_tree: A tree which can be used for retrieving file
435
contents more quickly than the revision tree, i.e. a workingtree.
436
The revision tree will be used for cases where accelerator_tree's
437
content is different.
438
:param hardlink: If true, hard-link files from accelerator_tree,
440
:param stacked: If true, create a stacked branch referring to the
441
location of this control directory.
442
:param create_tree_if_local: If true, a working-tree will be created
443
when working locally.
445
operation = cleanup.OperationWithCleanups(self._sprout)
446
return operation.run(url, revision_id=revision_id,
447
force_new_repo=force_new_repo, recurse=recurse,
448
possible_transports=possible_transports,
449
accelerator_tree=accelerator_tree, hardlink=hardlink,
450
stacked=stacked, source_branch=source_branch,
451
create_tree_if_local=create_tree_if_local)
453
def _sprout(self, op, url, revision_id=None, force_new_repo=False,
454
recurse='down', possible_transports=None,
455
accelerator_tree=None, hardlink=False, stacked=False,
456
source_branch=None, create_tree_if_local=True):
457
add_cleanup = op.add_cleanup
458
fetch_spec_factory = fetch.FetchSpecFactory()
459
if revision_id is not None:
460
fetch_spec_factory.add_revision_ids([revision_id])
461
fetch_spec_factory.source_branch_stop_revision_id = revision_id
462
target_transport = _mod_transport.get_transport(url,
464
target_transport.ensure_base()
465
cloning_format = self.cloning_metadir(stacked)
466
# Create/update the result branch
467
result = cloning_format.initialize_on_transport(target_transport)
468
source_branch, source_repository = self._find_source_repo(
469
add_cleanup, source_branch)
470
fetch_spec_factory.source_branch = source_branch
471
# if a stacked branch wasn't requested, we don't create one
472
# even if the origin was stacked
473
if stacked and source_branch is not None:
474
stacked_branch_url = self.root_transport.base
476
stacked_branch_url = None
477
repository_policy = result.determine_repository_policy(
478
force_new_repo, stacked_branch_url, require_stacking=stacked)
479
result_repo, is_new_repo = repository_policy.acquire_repository()
480
add_cleanup(result_repo.lock_write().unlock)
481
fetch_spec_factory.source_repo = source_repository
482
fetch_spec_factory.target_repo = result_repo
483
if stacked or (len(result_repo._fallback_repositories) != 0):
484
target_repo_kind = fetch.TargetRepoKinds.STACKED
486
target_repo_kind = fetch.TargetRepoKinds.EMPTY
488
target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
489
fetch_spec_factory.target_repo_kind = target_repo_kind
490
if source_repository is not None:
491
fetch_spec = fetch_spec_factory.make_fetch_spec()
492
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
494
if source_branch is None:
495
# this is for sprouting a controldir without a branch; is that
497
# Not especially, but it's part of the contract.
498
result_branch = result.create_branch()
500
result_branch = source_branch.sprout(result,
501
revision_id=revision_id, repository_policy=repository_policy,
502
repository=result_repo)
503
mutter("created new branch %r" % (result_branch,))
505
# Create/update the result working tree
506
if (create_tree_if_local and
507
isinstance(target_transport, local.LocalTransport) and
508
(result_repo is None or result_repo.make_working_trees())):
509
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
510
hardlink=hardlink, from_branch=result_branch)
513
if wt.path2id('') is None:
515
wt.set_root_id(self.open_workingtree.get_root_id())
516
except errors.NoWorkingTree:
522
if recurse == 'down':
525
basis = wt.basis_tree()
526
elif result_branch is not None:
527
basis = result_branch.basis_tree()
528
elif source_branch is not None:
529
basis = source_branch.basis_tree()
530
if basis is not None:
531
add_cleanup(basis.lock_read().unlock)
532
subtrees = basis.iter_references()
535
for path, file_id in subtrees:
536
target = urlutils.join(url, urlutils.escape(path))
537
sublocation = source_branch.reference_parent(file_id, path)
538
sublocation.bzrdir.sprout(target,
539
basis.get_reference_revision(file_id, path),
540
force_new_repo=force_new_repo, recurse=recurse,
425
547
def create_branch_convenience(base, force_new_repo=False,
426
548
force_new_tree=None, format=None,
2029
2144
'network operations. Additionally adds support for versioning nested '
2030
2145
'bzr branches. Incompatible with bzr < 0.15.',
2031
2146
branch_format='bzrlib.branch.BzrBranchFormat6',
2032
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2147
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2033
2148
experimental=True,
2036
2151
register_metadir(controldir.format_registry, 'pack-0.92',
2037
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
2152
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
2038
2153
help='New in 0.92: Pack-based format with data compatible with '
2039
2154
'dirstate-tags format repositories. Interoperates with '
2040
2155
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2042
2157
branch_format='bzrlib.branch.BzrBranchFormat6',
2043
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2158
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2045
2160
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2046
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
2161
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
2047
2162
help='New in 0.92: Pack-based format with data compatible with '
2048
2163
'dirstate-with-subtree format repositories. Interoperates with '
2049
2164
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2051
2166
branch_format='bzrlib.branch.BzrBranchFormat6',
2052
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2167
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2054
2169
experimental=True,
2056
2171
register_metadir(controldir.format_registry, 'rich-root-pack',
2057
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
2172
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
2058
2173
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
2059
2174
'(needed for bzr-svn and bzr-git).',
2060
2175
branch_format='bzrlib.branch.BzrBranchFormat6',
2061
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2176
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2064
2179
register_metadir(controldir.format_registry, '1.6',
2065
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
2180
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
2066
2181
help='A format that allows a branch to indicate that there is another '
2067
2182
'(stacked) repository that should be used to access data that is '
2068
2183
'not present locally.',
2069
2184
branch_format='bzrlib.branch.BzrBranchFormat7',
2070
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2185
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2073
2188
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2074
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
2189
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
2075
2190
help='A variant of 1.6 that supports rich-root data '
2076
2191
'(needed for bzr-svn and bzr-git).',
2077
2192
branch_format='bzrlib.branch.BzrBranchFormat7',
2078
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2193
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2081
2196
register_metadir(controldir.format_registry, '1.9',
2082
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
2197
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2083
2198
help='A repository format using B+tree indexes. These indexes '
2084
2199
'are smaller in size, have smarter caching and provide faster '
2085
2200
'performance for most operations.',
2086
2201
branch_format='bzrlib.branch.BzrBranchFormat7',
2087
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2202
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2090
2205
register_metadir(controldir.format_registry, '1.9-rich-root',
2091
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
2206
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2092
2207
help='A variant of 1.9 that supports rich-root data '
2093
2208
'(needed for bzr-svn and bzr-git).',
2094
2209
branch_format='bzrlib.branch.BzrBranchFormat7',
2095
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2210
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
2098
2213
register_metadir(controldir.format_registry, '1.14',
2099
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
2214
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
2100
2215
help='A working-tree format that supports content filtering.',
2101
2216
branch_format='bzrlib.branch.BzrBranchFormat7',
2102
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2217
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2104
2219
register_metadir(controldir.format_registry, '1.14-rich-root',
2105
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
2220
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
2106
2221
help='A variant of 1.14 that supports rich-root data '
2107
2222
'(needed for bzr-svn and bzr-git).',
2108
2223
branch_format='bzrlib.branch.BzrBranchFormat7',
2109
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2224
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
2111
2226
# The following un-numbered 'development' formats should always just be aliases.
2112
2227
register_metadir(controldir.format_registry, 'development-subtree',