169
145
format.get_format_description(),
172
def clone(self, url, revision_id=None, force_new_repo=False,
173
preserve_stacking=False):
148
def clone(self, url, revision_id=None, force_new_repo=False):
174
149
"""Clone this bzrdir and its contents to url verbatim.
176
:param url: The url create the clone at. If url's last component does
177
not exist, it will be created.
178
:param revision_id: The tip revision-id to use for any branch or
179
working tree. If not None, then the clone operation may tune
151
If urls last component does not exist, it will be created.
153
if revision_id is not None, then the clone operation may tune
180
154
itself to download less data.
181
:param force_new_repo: Do not use a shared repository for the target
155
:param force_new_repo: Do not use a shared repository for the target
182
156
even if one is available.
183
:param preserve_stacking: When cloning a stacked branch, stack the
184
new branch on top of the other branch's stacked-on branch.
186
158
return self.clone_on_transport(get_transport(url),
187
159
revision_id=revision_id,
188
force_new_repo=force_new_repo,
189
preserve_stacking=preserve_stacking)
160
force_new_repo=force_new_repo)
191
162
def clone_on_transport(self, transport, revision_id=None,
192
force_new_repo=False, preserve_stacking=False, stacked_on=None,
193
create_prefix=False, use_existing_dir=True):
163
force_new_repo=False):
194
164
"""Clone this bzrdir and its contents to transport verbatim.
196
:param transport: The transport for the location to produce the clone
197
at. If the target directory does not exist, it will be created.
198
:param revision_id: The tip revision-id to use for any branch or
199
working tree. If not None, then the clone operation may tune
166
If the target directory does not exist, it will be created.
168
if revision_id is not None, then the clone operation may tune
200
169
itself to download less data.
201
:param force_new_repo: Do not use a shared repository for the target,
170
:param force_new_repo: Do not use a shared repository for the target
202
171
even if one is available.
203
:param preserve_stacking: When cloning a stacked branch, stack the
204
new branch on top of the other branch's stacked-on branch.
205
:param create_prefix: Create any missing directories leading up to
207
:param use_existing_dir: Use an existing directory if one exists.
209
# Overview: put together a broad description of what we want to end up
210
# with; then make as few api calls as possible to do it.
212
# We may want to create a repo/branch/tree, if we do so what format
213
# would we want for each:
214
require_stacking = (stacked_on is not None)
215
format = self.cloning_metadir(require_stacking)
217
# Figure out what objects we want:
173
transport.ensure_base()
174
result = self._format.initialize_on_transport(transport)
219
176
local_repo = self.find_repository()
220
177
except errors.NoRepositoryPresent:
221
178
local_repo = None
223
local_branch = self.open_branch()
224
except errors.NotBranchError:
227
# enable fallbacks when branch is not a branch reference
228
if local_branch.repository.has_same_location(local_repo):
229
local_repo = local_branch.repository
230
if preserve_stacking:
232
stacked_on = local_branch.get_stacked_on_url()
233
except (errors.UnstackableBranchFormat,
234
errors.UnstackableRepositoryFormat,
237
# Bug: We create a metadir without knowing if it can support stacking,
238
# we should look up the policy needs first, or just use it as a hint,
241
make_working_trees = local_repo.make_working_trees()
242
want_shared = local_repo.is_shared()
243
repo_format_name = format.repository_format.network_name()
245
make_working_trees = False
247
repo_format_name = None
249
result_repo, result, require_stacking, repository_policy = \
250
format.initialize_on_transport_ex(transport,
251
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
252
force_new_repo=force_new_repo, stacked_on=stacked_on,
253
stack_on_pwd=self.root_transport.base,
254
repo_format_name=repo_format_name,
255
make_working_trees=make_working_trees, shared_repo=want_shared)
258
# If the result repository is in the same place as the
259
# resulting bzr dir, it will have no content, further if the
260
# result is not stacked then we know all content should be
261
# copied, and finally if we are copying up to a specific
262
# revision_id then we can use the pending-ancestry-result which
263
# does not require traversing all of history to describe it.
264
if (result_repo.bzrdir.root_transport.base ==
265
result.root_transport.base and not require_stacking and
266
revision_id is not None):
267
fetch_spec = graph.PendingAncestryResult(
268
[revision_id], local_repo)
269
result_repo.fetch(local_repo, fetch_spec=fetch_spec)
180
# may need to copy content in
182
result_repo = local_repo.clone(
184
revision_id=revision_id)
185
result_repo.set_make_working_trees(local_repo.make_working_trees())
188
result_repo = result.find_repository()
189
# fetch content this dir needs.
271
190
result_repo.fetch(local_repo, revision_id=revision_id)
275
if result_repo is not None:
276
raise AssertionError('result_repo not None(%r)' % result_repo)
191
except errors.NoRepositoryPresent:
192
# needed to make one anyway.
193
result_repo = local_repo.clone(
195
revision_id=revision_id)
196
result_repo.set_make_working_trees(local_repo.make_working_trees())
277
197
# 1 if there is a branch present
278
198
# make sure its content is available in the target repository
280
if local_branch is not None:
281
result_branch = local_branch.clone(result, revision_id=revision_id,
282
repository_policy=repository_policy)
284
# Cheaper to check if the target is not local, than to try making
286
result.root_transport.local_abspath('.')
287
if result_repo is None or result_repo.make_working_trees():
288
self.open_workingtree().clone(result)
201
self.open_branch().clone(result, revision_id=revision_id)
202
except errors.NotBranchError:
205
self.open_workingtree().clone(result)
289
206
except (errors.NoWorkingTree, errors.NotLocalUrl):
296
213
t = get_transport(url)
216
# TODO: Should take a Transport
300
def create(cls, base, format=None, possible_transports=None):
218
def create(cls, base, format=None):
301
219
"""Create a new BzrDir at the url 'base'.
221
This will call the current default formats initialize with base
222
as the only parameter.
303
224
:param format: If supplied, the format of branch to create. If not
304
225
supplied, the default is used.
305
:param possible_transports: If supplied, a list of transports that
306
can be reused to share a remote connection.
308
227
if cls is not BzrDir:
309
228
raise AssertionError("BzrDir.create always creates the default"
310
229
" format, not one of %r" % cls)
311
t = get_transport(base, possible_transports)
230
t = get_transport(base)
313
232
if format is None:
314
233
format = BzrDirFormat.get_default_format()
315
return format.initialize_on_transport(t)
318
def find_bzrdirs(transport, evaluate=None, list_current=None):
319
"""Find bzrdirs recursively from current location.
321
This is intended primarily as a building block for more sophisticated
322
functionality, like finding trees under a directory, or finding
323
branches that use a given repository.
324
:param evaluate: An optional callable that yields recurse, value,
325
where recurse controls whether this bzrdir is recursed into
326
and value is the value to yield. By default, all bzrdirs
327
are recursed into, and the return value is the bzrdir.
328
:param list_current: if supplied, use this function to list the current
329
directory, instead of Transport.list_dir
330
:return: a generator of found bzrdirs, or whatever evaluate returns.
332
if list_current is None:
333
def list_current(transport):
334
return transport.list_dir('')
336
def evaluate(bzrdir):
339
pending = [transport]
340
while len(pending) > 0:
341
current_transport = pending.pop()
344
bzrdir = BzrDir.open_from_transport(current_transport)
345
except errors.NotBranchError:
348
recurse, value = evaluate(bzrdir)
351
subdirs = list_current(current_transport)
352
except errors.NoSuchFile:
355
for subdir in sorted(subdirs, reverse=True):
356
pending.append(current_transport.clone(subdir))
358
def list_branches(self):
359
"""Return a sequence of all branches local to this control directory.
363
return [self.open_branch()]
364
except errors.NotBranchError:
368
def find_branches(transport):
369
"""Find all branches under a transport.
371
This will find all branches below the transport, including branches
372
inside other branches. Where possible, it will use
373
Repository.find_branches.
375
To list all the branches that use a particular Repository, see
376
Repository.find_branches
378
def evaluate(bzrdir):
380
repository = bzrdir.open_repository()
381
except errors.NoRepositoryPresent:
384
return False, ([], repository)
385
return True, (bzrdir.list_branches(), None)
387
for branches, repo in BzrDir.find_bzrdirs(transport,
390
ret.extend(repo.find_branches())
391
if branches is not None:
395
def destroy_repository(self):
396
"""Destroy the repository in this BzrDir"""
397
raise NotImplementedError(self.destroy_repository)
234
return format.initialize(safe_unicode(base))
399
236
def create_branch(self):
400
237
"""Create a branch in this BzrDir.
402
The bzrdir's format will control what branch format is created.
239
The bzrdirs format will control what branch format is created.
403
240
For more control see BranchFormatXX.create(a_bzrdir).
405
242
raise NotImplementedError(self.create_branch)
407
def destroy_branch(self):
408
"""Destroy the branch in this BzrDir"""
409
raise NotImplementedError(self.destroy_branch)
412
245
def create_branch_and_repo(base, force_new_repo=False, format=None):
413
246
"""Create a new BzrDir, Branch and Repository at the url 'base'.
415
This will use the current default BzrDirFormat unless one is
416
specified, and use whatever
248
This will use the current default BzrDirFormat, and use whatever
417
249
repository format that that uses via bzrdir.create_branch and
418
250
create_repository. If a shared repository is available that is used
423
255
:param base: The URL to create the branch at.
424
256
:param force_new_repo: If True a new repository is always created.
425
:param format: If supplied, the format of branch to create. If not
426
supplied, the default is used.
428
258
bzrdir = BzrDir.create(base, format)
429
259
bzrdir._find_or_create_repository(force_new_repo)
430
260
return bzrdir.create_branch()
432
def determine_repository_policy(self, force_new_repo=False, stack_on=None,
433
stack_on_pwd=None, require_stacking=False):
434
"""Return an object representing a policy to use.
436
This controls whether a new repository is created, and the format of
437
that repository, or some existing shared repository used instead.
439
If stack_on is supplied, will not seek a containing shared repo.
441
:param force_new_repo: If True, require a new repository to be created.
442
:param stack_on: If supplied, the location to stack on. If not
443
supplied, a default_stack_on location may be used.
444
:param stack_on_pwd: If stack_on is relative, the location it is
447
def repository_policy(found_bzrdir):
450
config = found_bzrdir.get_config()
452
stack_on = config.get_default_stack_on()
453
if stack_on is not None:
454
stack_on_pwd = found_bzrdir.root_transport.base
456
# does it have a repository ?
458
repository = found_bzrdir.open_repository()
459
except errors.NoRepositoryPresent:
462
if ((found_bzrdir.root_transport.base !=
463
self.root_transport.base) and not repository.is_shared()):
464
# Don't look higher, can't use a higher shared repo.
472
return UseExistingRepository(repository, stack_on,
473
stack_on_pwd, require_stacking=require_stacking), True
475
return CreateRepository(self, stack_on, stack_on_pwd,
476
require_stacking=require_stacking), True
478
if not force_new_repo:
480
policy = self._find_containing(repository_policy)
481
if policy is not None:
485
return UseExistingRepository(self.open_repository(),
486
stack_on, stack_on_pwd,
487
require_stacking=require_stacking)
488
except errors.NoRepositoryPresent:
490
return CreateRepository(self, stack_on, stack_on_pwd,
491
require_stacking=require_stacking)
493
262
def _find_or_create_repository(self, force_new_repo):
494
263
"""Create a new repository if needed, returning the repository."""
495
policy = self.determine_repository_policy(force_new_repo)
496
return policy.acquire_repository()[0]
265
return self.create_repository()
267
return self.find_repository()
268
except errors.NoRepositoryPresent:
269
return self.create_repository()
499
272
def create_branch_convenience(base, force_new_repo=False,
500
force_new_tree=None, format=None,
501
possible_transports=None):
273
force_new_tree=None, format=None):
502
274
"""Create a new BzrDir, Branch and Repository at the url 'base'.
504
276
This is a convenience function - it will use an existing repository
505
277
if possible, can be told explicitly whether to create a working tree or
508
This will use the current default BzrDirFormat unless one is
509
specified, and use whatever
280
This will use the current default BzrDirFormat, and use whatever
510
281
repository format that that uses via bzrdir.create_branch and
511
282
create_repository. If a shared repository is available that is used
512
283
preferentially. Whatever repository is used, its tree creation policy
547
336
'base' must be a local path or a file:// url.
549
This will use the current default BzrDirFormat unless one is
550
specified, and use whatever
338
This will use the current default BzrDirFormat, and use whatever
551
339
repository format that that uses for bzrdirformat.create_workingtree,
552
340
create_branch and create_repository.
554
:param format: Override for the bzrdir format to create.
555
342
:return: The WorkingTree object.
557
t = get_transport(base)
558
if not isinstance(t, local.LocalTransport):
344
t = get_transport(safe_unicode(base))
345
if not isinstance(t, LocalTransport):
559
346
raise errors.NotLocalUrl(base)
560
bzrdir = BzrDir.create_branch_and_repo(base,
347
bzrdir = BzrDir.create_branch_and_repo(safe_unicode(base),
561
348
force_new_repo=True,
562
349
format=format).bzrdir
563
350
return bzrdir.create_workingtree()
565
def create_workingtree(self, revision_id=None, from_branch=None,
566
accelerator_tree=None, hardlink=False):
352
def create_workingtree(self, revision_id=None):
567
353
"""Create a working tree at this BzrDir.
569
:param revision_id: create it as of this revision id.
570
:param from_branch: override bzrdir branch (for lightweight checkouts)
571
:param accelerator_tree: A tree which can be used for retrieving file
572
contents more quickly than the revision tree, i.e. a workingtree.
573
The revision tree will be used for cases where accelerator_tree's
574
content is different.
355
revision_id: create it as of this revision id.
576
357
raise NotImplementedError(self.create_workingtree)
578
def backup_bzrdir(self):
579
"""Backup this bzr control directory.
581
:return: Tuple with old path name and new path name
583
def name_gen(base='backup.bzr'):
585
name = "%s.~%d~" % (base, counter)
586
while self.root_transport.has(name):
588
name = "%s.~%d~" % (base, counter)
591
backup_dir=name_gen()
592
pb = ui.ui_factory.nested_progress_bar()
594
# FIXME: bug 300001 -- the backup fails if the backup directory
595
# already exists, but it should instead either remove it or make
596
# a new backup directory.
598
# FIXME: bug 262450 -- the backup directory should have the same
599
# permissions as the .bzr directory (probably a bug in copy_tree)
600
old_path = self.root_transport.abspath('.bzr')
601
new_path = self.root_transport.abspath(backup_dir)
602
ui.ui_factory.note('making backup of %s\n to %s' % (old_path, new_path,))
603
self.root_transport.copy_tree('.bzr', backup_dir)
604
return (old_path, new_path)
608
def retire_bzrdir(self, limit=10000):
359
def retire_bzrdir(self):
609
360
"""Permanently disable the bzrdir.
611
362
This is done by renaming it to give the user some ability to recover
984
637
relpath is the portion of the path that is contained by the branch.
986
639
bzrdir, relpath = klass.open_containing(location)
987
tree, branch = bzrdir._get_tree_branch()
641
tree = bzrdir.open_workingtree()
642
except (errors.NoWorkingTree, errors.NotLocalUrl):
644
branch = bzrdir.open_branch()
988
647
return tree, branch, relpath
991
def open_containing_tree_branch_or_repository(klass, location):
992
"""Return the working tree, branch and repo contained by a location.
994
Returns (tree, branch, repository, relpath).
995
If there is no tree containing the location, tree will be None.
996
If there is no branch containing the location, branch will be None.
997
If there is no repository containing the location, repository will be
999
relpath is the portion of the path that is contained by the innermost
1002
If no tree, branch or repository is found, a NotBranchError is raised.
1004
bzrdir, relpath = klass.open_containing(location)
1006
tree, branch = bzrdir._get_tree_branch()
1007
except errors.NotBranchError:
1009
repo = bzrdir.find_repository()
1010
return None, None, repo, relpath
1011
except (errors.NoRepositoryPresent):
1012
raise errors.NotBranchError(location)
1013
return tree, branch, branch.repository, relpath
1015
649
def open_repository(self, _unsupported=False):
1016
650
"""Open the repository object at this BzrDir if one is present.
1018
This will not follow the Branch object pointer - it's strictly a direct
652
This will not follow the Branch object pointer - its strictly a direct
1019
653
open facility. Most client code should use open_branch().repository to
1020
654
get at a repository.
1022
:param _unsupported: a private parameter, not part of the api.
656
_unsupported is a private parameter, not part of the api.
1023
657
TODO: static convenience version of this?
1025
659
raise NotImplementedError(self.open_repository)
1027
661
def open_workingtree(self, _unsupported=False,
1028
recommend_upgrade=True, from_branch=None):
662
recommend_upgrade=True):
1029
663
"""Open the workingtree object at this BzrDir if one is present.
1031
665
:param recommend_upgrade: Optional keyword parameter, when True (the
1032
666
default), emit through the ui module a recommendation that the user
1033
667
upgrade the working tree when the workingtree being opened is old
1034
668
(but still fully supported).
1035
:param from_branch: override bzrdir branch (for lightweight checkouts)
1037
670
raise NotImplementedError(self.open_workingtree)
1039
672
def has_branch(self):
1040
673
"""Tell if this bzrdir contains a branch.
1042
675
Note: if you're going to open the branch, you should just go ahead
1043
and try, and not ask permission first. (This method just opens the
1044
branch and discards it, and that's somewhat expensive.)
676
and try, and not ask permission first. (This method just opens the
677
branch and discards it, and that's somewhat expensive.)
1047
680
self.open_branch()
1148
761
if revision_id is not None, then the clone operation may tune
1149
762
itself to download less data.
1150
:param accelerator_tree: A tree which can be used for retrieving file
1151
contents more quickly than the revision tree, i.e. a workingtree.
1152
The revision tree will be used for cases where accelerator_tree's
1153
content is different.
1154
:param hardlink: If true, hard-link files from accelerator_tree,
1156
:param stacked: If true, create a stacked branch referring to the
1157
location of this control directory.
1158
:param create_tree_if_local: If true, a working-tree will be created
1159
when working locally.
1161
target_transport = get_transport(url, possible_transports)
764
target_transport = get_transport(url)
1162
765
target_transport.ensure_base()
1163
cloning_format = self.cloning_metadir(stacked)
1164
# Create/update the result branch
766
cloning_format = self.cloning_metadir()
1165
767
result = cloning_format.initialize_on_transport(target_transport)
1166
# if a stacked branch wasn't requested, we don't create one
1167
# even if the origin was stacked
1168
stacked_branch_url = None
1169
if source_branch is not None:
1171
stacked_branch_url = self.root_transport.base
769
source_branch = self.open_branch()
1172
770
source_repository = source_branch.repository
1175
source_branch = self.open_branch()
1176
source_repository = source_branch.repository
1178
stacked_branch_url = self.root_transport.base
1179
except errors.NotBranchError:
1180
source_branch = None
1182
source_repository = self.open_repository()
1183
except errors.NoRepositoryPresent:
1184
source_repository = None
1185
repository_policy = result.determine_repository_policy(
1186
force_new_repo, stacked_branch_url, require_stacking=stacked)
1187
result_repo, is_new_repo = repository_policy.acquire_repository()
1188
if is_new_repo and revision_id is not None and not stacked:
1189
fetch_spec = graph.PendingAncestryResult(
1190
[revision_id], source_repository)
1193
if source_repository is not None:
1194
# Fetch while stacked to prevent unstacked fetch from
1196
if fetch_spec is None:
771
except errors.NotBranchError:
774
source_repository = self.open_repository()
775
except errors.NoRepositoryPresent:
776
source_repository = None
781
result_repo = result.find_repository()
782
except errors.NoRepositoryPresent:
784
if source_repository is None and result_repo is not None:
786
elif source_repository is None and result_repo is None:
787
# no repo available, make a new one
788
result.create_repository()
789
elif source_repository is not None and result_repo is None:
790
# have source, and want to make a new target repo
791
result_repo = source_repository.sprout(result, revision_id=revision_id)
793
# fetch needed content into target.
794
if source_repository is not None:
796
# source_repository.copy_content_into(result_repo, revision_id=revision_id)
797
# so we can override the copy method
1197
798
result_repo.fetch(source_repository, revision_id=revision_id)
1199
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
1201
if source_branch is None:
1202
# this is for sprouting a bzrdir without a branch; is that
1204
# Not especially, but it's part of the contract.
1205
result_branch = result.create_branch()
799
if source_branch is not None:
800
source_branch.sprout(result, revision_id=revision_id)
1207
result_branch = source_branch.sprout(result,
1208
revision_id=revision_id, repository_policy=repository_policy)
1209
mutter("created new branch %r" % (result_branch,))
1211
# Create/update the result working tree
1212
if (create_tree_if_local and
1213
isinstance(target_transport, local.LocalTransport) and
1214
(result_repo is None or result_repo.make_working_trees())):
1215
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
802
result.create_branch()
803
# TODO: jam 20060426 we probably need a test in here in the
804
# case that the newly sprouted branch is a remote one
805
if result_repo is None or result_repo.make_working_trees():
806
wt = result.create_workingtree()
1219
809
if wt.path2id('') is None:
1247
835
sublocation = source_branch.reference_parent(file_id, path)
1248
836
sublocation.bzrdir.sprout(target,
1249
837
basis.get_reference_revision(file_id, path),
1250
force_new_repo=force_new_repo, recurse=recurse,
838
force_new_repo=force_new_repo, recurse=recurse)
1253
840
if basis is not None:
1257
def push_branch(self, source, revision_id=None, overwrite=False,
1258
remember=False, create_prefix=False):
1259
"""Push the source branch into this BzrDir."""
1261
# If we can open a branch, use its direct repository, otherwise see
1262
# if there is a repository without a branch.
1264
br_to = self.open_branch()
1265
except errors.NotBranchError:
1266
# Didn't find a branch, can we find a repository?
1267
repository_to = self.find_repository()
1269
# Found a branch, so we must have found a repository
1270
repository_to = br_to.repository
1272
push_result = PushResult()
1273
push_result.source_branch = source
1275
# We have a repository but no branch, copy the revisions, and then
1277
repository_to.fetch(source.repository, revision_id=revision_id)
1278
br_to = source.clone(self, revision_id=revision_id)
1279
if source.get_push_location() is None or remember:
1280
source.set_push_location(br_to.base)
1281
push_result.stacked_on = None
1282
push_result.branch_push_result = None
1283
push_result.old_revno = None
1284
push_result.old_revid = _mod_revision.NULL_REVISION
1285
push_result.target_branch = br_to
1286
push_result.master_branch = None
1287
push_result.workingtree_updated = False
1289
# We have successfully opened the branch, remember if necessary:
1290
if source.get_push_location() is None or remember:
1291
source.set_push_location(br_to.base)
1293
tree_to = self.open_workingtree()
1294
except errors.NotLocalUrl:
1295
push_result.branch_push_result = source.push(br_to,
1296
overwrite, stop_revision=revision_id)
1297
push_result.workingtree_updated = False
1298
except errors.NoWorkingTree:
1299
push_result.branch_push_result = source.push(br_to,
1300
overwrite, stop_revision=revision_id)
1301
push_result.workingtree_updated = None # Not applicable
1303
tree_to.lock_write()
1305
push_result.branch_push_result = source.push(
1306
tree_to.branch, overwrite, stop_revision=revision_id)
1310
push_result.workingtree_updated = True
1311
push_result.old_revno = push_result.branch_push_result.old_revno
1312
push_result.old_revid = push_result.branch_push_result.old_revid
1313
push_result.target_branch = \
1314
push_result.branch_push_result.target_branch
1318
class BzrDirHooks(hooks.Hooks):
1319
"""Hooks for BzrDir operations."""
1322
"""Create the default hooks."""
1323
hooks.Hooks.__init__(self)
1324
self.create_hook(hooks.HookPoint('pre_open',
1325
"Invoked before attempting to open a BzrDir with the transport "
1326
"that the open will use.", (1, 14), None))
1328
# install the default hooks
1329
BzrDir.hooks = BzrDirHooks()
1332
845
class BzrDirPreSplitOut(BzrDir):
1333
846
"""A common class for the all-in-one formats."""
1873
1286
current default format. In the case of plugins we can/should provide
1874
1287
some means for them to extend the range of returnable converters.
1876
:param format: Optional format to override the default format of the
1289
:param format: Optional format to override the default format of the
1879
1292
raise NotImplementedError(self.get_converter)
1881
def initialize(self, url, possible_transports=None):
1294
def initialize(self, url):
1882
1295
"""Create a bzr control dir at this url and return an opened copy.
1884
While not deprecated, this method is very specific and its use will
1885
lead to many round trips to setup a working environment. See
1886
initialize_on_transport_ex for a [nearly] all-in-one method.
1888
1297
Subclasses should typically override initialize_on_transport
1889
1298
instead of this method.
1891
return self.initialize_on_transport(get_transport(url,
1892
possible_transports))
1300
return self.initialize_on_transport(get_transport(url))
1894
1302
def initialize_on_transport(self, transport):
1895
1303
"""Initialize a new bzrdir in the base directory of a Transport."""
1897
# can we hand off the request to the smart server rather than using
1899
client_medium = transport.get_smart_medium()
1900
except errors.NoSmartMedium:
1901
return self._initialize_on_transport_vfs(transport)
1903
# Current RPC's only know how to create bzr metadir1 instances, so
1904
# we still delegate to vfs methods if the requested format is not a
1906
if type(self) != BzrDirMetaFormat1:
1907
return self._initialize_on_transport_vfs(transport)
1908
remote_format = RemoteBzrDirFormat()
1909
self._supply_sub_formats_to(remote_format)
1910
return remote_format.initialize_on_transport(transport)
1912
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1913
create_prefix=False, force_new_repo=False, stacked_on=None,
1914
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1915
shared_repo=False, vfs_only=False):
1916
"""Create this format on transport.
1918
The directory to initialize will be created.
1920
:param force_new_repo: Do not use a shared repository for the target,
1921
even if one is available.
1922
:param create_prefix: Create any missing directories leading up to
1924
:param use_existing_dir: Use an existing directory if one exists.
1925
:param stacked_on: A url to stack any created branch on, None to follow
1926
any target stacking policy.
1927
:param stack_on_pwd: If stack_on is relative, the location it is
1929
:param repo_format_name: If non-None, a repository will be
1930
made-or-found. Should none be found, or if force_new_repo is True
1931
the repo_format_name is used to select the format of repository to
1933
:param make_working_trees: Control the setting of make_working_trees
1934
for a new shared repository when one is made. None to use whatever
1935
default the format has.
1936
:param shared_repo: Control whether made repositories are shared or
1938
:param vfs_only: If True do not attempt to use a smart server
1939
:return: repo, bzrdir, require_stacking, repository_policy. repo is
1940
None if none was created or found, bzrdir is always valid.
1941
require_stacking is the result of examining the stacked_on
1942
parameter and any stacking policy found for the target.
1945
# Try to hand off to a smart server
1947
client_medium = transport.get_smart_medium()
1948
except errors.NoSmartMedium:
1951
# TODO: lookup the local format from a server hint.
1952
remote_dir_format = RemoteBzrDirFormat()
1953
remote_dir_format._network_name = self.network_name()
1954
self._supply_sub_formats_to(remote_dir_format)
1955
return remote_dir_format.initialize_on_transport_ex(transport,
1956
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1957
force_new_repo=force_new_repo, stacked_on=stacked_on,
1958
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1959
make_working_trees=make_working_trees, shared_repo=shared_repo)
1960
# XXX: Refactor the create_prefix/no_create_prefix code into a
1961
# common helper function
1962
# The destination may not exist - if so make it according to policy.
1963
def make_directory(transport):
1964
transport.mkdir('.')
1966
def redirected(transport, e, redirection_notice):
1967
note(redirection_notice)
1968
return transport._redirected_to(e.source, e.target)
1970
transport = do_catching_redirections(make_directory, transport,
1972
except errors.FileExists:
1973
if not use_existing_dir:
1975
except errors.NoSuchFile:
1976
if not create_prefix:
1978
transport.create_prefix()
1980
require_stacking = (stacked_on is not None)
1981
# Now the target directory exists, but doesn't have a .bzr
1982
# directory. So we need to create it, along with any work to create
1983
# all of the dependent branches, etc.
1985
result = self.initialize_on_transport(transport)
1986
if repo_format_name:
1988
# use a custom format
1989
result._format.repository_format = \
1990
repository.network_format_registry.get(repo_format_name)
1991
except AttributeError:
1992
# The format didn't permit it to be set.
1994
# A repository is desired, either in-place or shared.
1995
repository_policy = result.determine_repository_policy(
1996
force_new_repo, stacked_on, stack_on_pwd,
1997
require_stacking=require_stacking)
1998
result_repo, is_new_repo = repository_policy.acquire_repository(
1999
make_working_trees, shared_repo)
2000
if not require_stacking and repository_policy._require_stacking:
2001
require_stacking = True
2002
result._format.require_stacking()
2003
result_repo.lock_write()
2006
repository_policy = None
2007
return result_repo, result, require_stacking, repository_policy
2009
def _initialize_on_transport_vfs(self, transport):
2010
"""Initialize a new bzrdir using VFS calls.
2012
:param transport: The transport to create the .bzr directory in.
2015
# Since we are creating a .bzr directory, inherit the
1304
# Since we don't have a .bzr directory, inherit the
2016
1305
# mode from the root directory
2017
1306
temp_control = lockable_files.LockableFiles(transport,
2018
1307
'', lockable_files.TransportLock)
2408
1641
def set_branch_format(self, format):
2409
1642
self._branch_format = format
2411
def require_stacking(self, stack_on=None, possible_transports=None,
2413
"""We have a request to stack, try to ensure the formats support it.
2415
:param stack_on: If supplied, it is the URL to a branch that we want to
2416
stack on. Check to see if that format supports stacking before
2419
# Stacking is desired. requested by the target, but does the place it
2420
# points at support stacking? If it doesn't then we should
2421
# not implicitly upgrade. We check this here.
2422
new_repo_format = None
2423
new_branch_format = None
2425
# a bit of state for get_target_branch so that we don't try to open it
2426
# 2 times, for both repo *and* branch
2427
target = [None, False, None] # target_branch, checked, upgrade anyway
2428
def get_target_branch():
2430
# We've checked, don't check again
2432
if stack_on is None:
2433
# No target format, that means we want to force upgrading
2434
target[:] = [None, True, True]
2437
target_dir = BzrDir.open(stack_on,
2438
possible_transports=possible_transports)
2439
except errors.NotBranchError:
2440
# Nothing there, don't change formats
2441
target[:] = [None, True, False]
2443
except errors.JailBreak:
2444
# JailBreak, JFDI and upgrade anyway
2445
target[:] = [None, True, True]
2448
target_branch = target_dir.open_branch()
2449
except errors.NotBranchError:
2450
# No branch, don't upgrade formats
2451
target[:] = [None, True, False]
2453
target[:] = [target_branch, True, False]
2456
if (not _skip_repo and
2457
not self.repository_format.supports_external_lookups):
2458
# We need to upgrade the Repository.
2459
target_branch, _, do_upgrade = get_target_branch()
2460
if target_branch is None:
2461
# We don't have a target branch, should we upgrade anyway?
2463
# stack_on is inaccessible, JFDI.
2464
# TODO: bad monkey, hard-coded formats...
2465
if self.repository_format.rich_root_data:
2466
new_repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
2468
new_repo_format = pack_repo.RepositoryFormatKnitPack5()
2470
# If the target already supports stacking, then we know the
2471
# project is already able to use stacking, so auto-upgrade
2473
new_repo_format = target_branch.repository._format
2474
if not new_repo_format.supports_external_lookups:
2475
# target doesn't, source doesn't, so don't auto upgrade
2477
new_repo_format = None
2478
if new_repo_format is not None:
2479
self.repository_format = new_repo_format
2480
note('Source repository format does not support stacking,'
2481
' using format:\n %s',
2482
new_repo_format.get_format_description())
2484
if not self.get_branch_format().supports_stacking():
2485
# We just checked the repo, now lets check if we need to
2486
# upgrade the branch format
2487
target_branch, _, do_upgrade = get_target_branch()
2488
if target_branch is None:
2490
# TODO: bad monkey, hard-coded formats...
2491
new_branch_format = branch.BzrBranchFormat7()
2493
new_branch_format = target_branch._format
2494
if not new_branch_format.supports_stacking():
2495
new_branch_format = None
2496
if new_branch_format is not None:
2497
# Does support stacking, use its format.
2498
self.set_branch_format(new_branch_format)
2499
note('Source branch format does not support stacking,'
2500
' using format:\n %s',
2501
new_branch_format.get_format_description())
2503
1644
def get_converter(self, format=None):
2504
1645
"""See BzrDirFormat.get_converter()."""
2505
1646
if format is None:
3102
2218
# TODO: conversions of Branch and Tree should be done by
3103
2219
# InterXFormat lookups
3104
2220
if (isinstance(tree, workingtree.WorkingTree3) and
3105
not isinstance(tree, workingtree_4.DirStateWorkingTree) and
2221
not isinstance(tree, workingtree_4.WorkingTree4) and
3106
2222
isinstance(self.target_format.workingtree_format,
3107
workingtree_4.DirStateWorkingTreeFormat)):
2223
workingtree_4.WorkingTreeFormat4)):
3108
2224
workingtree_4.Converter3to4().convert(tree)
3109
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
3110
not isinstance(tree, workingtree_4.WorkingTree5) and
3111
isinstance(self.target_format.workingtree_format,
3112
workingtree_4.WorkingTreeFormat5)):
3113
workingtree_4.Converter4to5().convert(tree)
3114
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
3115
not isinstance(tree, workingtree_4.WorkingTree6) and
3116
isinstance(self.target_format.workingtree_format,
3117
workingtree_4.WorkingTreeFormat6)):
3118
workingtree_4.Converter4or5to6().convert(tree)
3120
2225
return to_convert
3123
# This is not in remote.py because it's relatively small, and needs to be
3124
# registered. Putting it in remote.py creates a circular import problem.
2228
# This is not in remote.py because it's small, and needs to be registered.
2229
# Putting it in remote.py creates a circular import problem.
3125
2230
# we can make it a lazy object if the control formats is turned into something
3126
2231
# like a registry.
3127
2232
class RemoteBzrDirFormat(BzrDirMetaFormat1):
3128
2233
"""Format representing bzrdirs accessed via a smart server"""
3131
BzrDirMetaFormat1.__init__(self)
3132
# XXX: It's a bit ugly that the network name is here, because we'd
3133
# like to believe that format objects are stateless or at least
3134
# immutable, However, we do at least avoid mutating the name after
3135
# it's returned. See <https://bugs.edge.launchpad.net/bzr/+bug/504102>
3136
self._network_name = None
3139
return "%s(_network_name=%r)" % (self.__class__.__name__,
3142
2235
def get_format_description(self):
3143
if self._network_name:
3144
real_format = network_format_registry.get(self._network_name)
3145
return 'Remote: ' + real_format.get_format_description()
3146
2236
return 'bzr remote bzrdir'
3148
def get_format_string(self):
3149
raise NotImplementedError(self.get_format_string)
3151
def network_name(self):
3152
if self._network_name:
3153
return self._network_name
3155
raise AssertionError("No network name set.")
3158
2239
def probe_transport(klass, transport):
3159
2240
"""Return a RemoteBzrDirFormat object if it looks possible."""
3161
medium = transport.get_smart_medium()
2242
client = transport.get_smart_client()
3162
2243
except (NotImplementedError, AttributeError,
3163
errors.TransportNotPossible, errors.NoSmartMedium,
3164
errors.SmartProtocolError):
2244
errors.TransportNotPossible):
3165
2245
# no smart server, so not a branch for this format type.
3166
2246
raise errors.NotBranchError(path=transport.base)
3168
# Decline to open it if the server doesn't support our required
3169
# version (3) so that the VFS-based transport will do it.
3170
if medium.should_probe():
3172
server_version = medium.protocol_version()
3173
except errors.SmartProtocolError:
3174
# Apparently there's no usable smart server there, even though
3175
# the medium supports the smart protocol.
3176
raise errors.NotBranchError(path=transport.base)
3177
if server_version != '2':
3178
raise errors.NotBranchError(path=transport.base)
2248
# Send a 'hello' request in protocol version one, and decline to
2249
# open it if the server doesn't support our required version (2) so
2250
# that the VFS-based transport will do it.
2251
request = client.get_request()
2252
smart_protocol = protocol.SmartClientRequestProtocolOne(request)
2253
server_version = smart_protocol.query_version()
2254
if server_version != 2:
2255
raise errors.NotBranchError(path=transport.base)
3181
2258
def initialize_on_transport(self, transport):
3183
2260
# hand off the request to the smart server
3184
client_medium = transport.get_smart_medium()
2261
medium = transport.get_smart_medium()
3185
2262
except errors.NoSmartMedium:
3186
2263
# TODO: lookup the local format from a server hint.
3187
2264
local_dir_format = BzrDirMetaFormat1()
3188
2265
return local_dir_format.initialize_on_transport(transport)
3189
client = _SmartClient(client_medium)
2266
client = _SmartClient(medium)
3190
2267
path = client.remote_path_from_transport(transport)
3192
response = client.call('BzrDirFormat.initialize', path)
3193
except errors.ErrorFromSmartServer, err:
3194
remote._translate_error(err, path=path)
3195
if response[0] != 'ok':
3196
raise errors.SmartProtocolError('unexpected response code %s' % (response,))
3197
format = RemoteBzrDirFormat()
3198
self._supply_sub_formats_to(format)
3199
return remote.RemoteBzrDir(transport, format)
3201
def parse_NoneTrueFalse(self, arg):
3208
raise AssertionError("invalid arg %r" % arg)
3210
def _serialize_NoneTrueFalse(self, arg):
3217
def _serialize_NoneString(self, arg):
3220
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
3221
create_prefix=False, force_new_repo=False, stacked_on=None,
3222
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
3225
# hand off the request to the smart server
3226
client_medium = transport.get_smart_medium()
3227
except errors.NoSmartMedium:
3230
# Decline to open it if the server doesn't support our required
3231
# version (3) so that the VFS-based transport will do it.
3232
if client_medium.should_probe():
3234
server_version = client_medium.protocol_version()
3235
if server_version != '2':
3239
except errors.SmartProtocolError:
3240
# Apparently there's no usable smart server there, even though
3241
# the medium supports the smart protocol.
3246
client = _SmartClient(client_medium)
3247
path = client.remote_path_from_transport(transport)
3248
if client_medium._is_remote_before((1, 16)):
3251
# TODO: lookup the local format from a server hint.
3252
local_dir_format = BzrDirMetaFormat1()
3253
self._supply_sub_formats_to(local_dir_format)
3254
return local_dir_format.initialize_on_transport_ex(transport,
3255
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
3256
force_new_repo=force_new_repo, stacked_on=stacked_on,
3257
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
3258
make_working_trees=make_working_trees, shared_repo=shared_repo,
3260
return self._initialize_on_transport_ex_rpc(client, path, transport,
3261
use_existing_dir, create_prefix, force_new_repo, stacked_on,
3262
stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
3264
def _initialize_on_transport_ex_rpc(self, client, path, transport,
3265
use_existing_dir, create_prefix, force_new_repo, stacked_on,
3266
stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
3268
args.append(self._serialize_NoneTrueFalse(use_existing_dir))
3269
args.append(self._serialize_NoneTrueFalse(create_prefix))
3270
args.append(self._serialize_NoneTrueFalse(force_new_repo))
3271
args.append(self._serialize_NoneString(stacked_on))
3272
# stack_on_pwd is often/usually our transport
3275
stack_on_pwd = transport.relpath(stack_on_pwd)
3276
if not stack_on_pwd:
3278
except errors.PathNotChild:
3280
args.append(self._serialize_NoneString(stack_on_pwd))
3281
args.append(self._serialize_NoneString(repo_format_name))
3282
args.append(self._serialize_NoneTrueFalse(make_working_trees))
3283
args.append(self._serialize_NoneTrueFalse(shared_repo))
3284
request_network_name = self._network_name or \
3285
BzrDirFormat.get_default_format().network_name()
3287
response = client.call('BzrDirFormat.initialize_ex_1.16',
3288
request_network_name, path, *args)
3289
except errors.UnknownSmartMethod:
3290
client._medium._remember_remote_is_before((1,16))
3291
local_dir_format = BzrDirMetaFormat1()
3292
self._supply_sub_formats_to(local_dir_format)
3293
return local_dir_format.initialize_on_transport_ex(transport,
3294
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
3295
force_new_repo=force_new_repo, stacked_on=stacked_on,
3296
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
3297
make_working_trees=make_working_trees, shared_repo=shared_repo,
3299
except errors.ErrorFromSmartServer, err:
3300
remote._translate_error(err, path=path)
3301
repo_path = response[0]
3302
bzrdir_name = response[6]
3303
require_stacking = response[7]
3304
require_stacking = self.parse_NoneTrueFalse(require_stacking)
3305
format = RemoteBzrDirFormat()
3306
format._network_name = bzrdir_name
3307
self._supply_sub_formats_to(format)
3308
bzrdir = remote.RemoteBzrDir(transport, format, _client=client)
3310
repo_format = remote.response_tuple_to_repo_format(response[1:])
3311
if repo_path == '.':
3314
repo_bzrdir_format = RemoteBzrDirFormat()
3315
repo_bzrdir_format._network_name = response[5]
3316
repo_bzr = remote.RemoteBzrDir(transport.clone(repo_path),
3320
final_stack = response[8] or None
3321
final_stack_pwd = response[9] or None
3323
final_stack_pwd = urlutils.join(
3324
transport.base, final_stack_pwd)
3325
remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
3326
if len(response) > 10:
3327
# Updated server verb that locks remotely.
3328
repo_lock_token = response[10] or None
3329
remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
3331
remote_repo.dont_leave_lock_in_place()
3333
remote_repo.lock_write()
3334
policy = UseExistingRepository(remote_repo, final_stack,
3335
final_stack_pwd, require_stacking)
3336
policy.acquire_repository()
3340
bzrdir._format.set_branch_format(self.get_branch_format())
3341
if require_stacking:
3342
# The repo has already been created, but we need to make sure that
3343
# we'll make a stackable branch.
3344
bzrdir._format.require_stacking(_skip_repo=True)
3345
return remote_repo, bzrdir, require_stacking, policy
2268
response = _SmartClient(medium).call('BzrDirFormat.initialize', path)
2269
assert response[0] in ('ok', ), 'unexpected response code %s' % (response,)
2270
return remote.RemoteBzrDir(transport)
3347
2272
def _open(self, transport):
3348
return remote.RemoteBzrDir(transport, self)
2273
return remote.RemoteBzrDir(transport)
3350
2275
def __eq__(self, other):
3351
2276
if not isinstance(other, RemoteBzrDirFormat):
3353
2278
return self.get_format_description() == other.get_format_description()
3355
def __return_repository_format(self):
3356
# Always return a RemoteRepositoryFormat object, but if a specific bzr
3357
# repository format has been asked for, tell the RemoteRepositoryFormat
3358
# that it should use that for init() etc.
3359
result = remote.RemoteRepositoryFormat()
3360
custom_format = getattr(self, '_repository_format', None)
3362
if isinstance(custom_format, remote.RemoteRepositoryFormat):
3363
return custom_format
3365
# We will use the custom format to create repositories over the
3366
# wire; expose its details like rich_root_data for code to
3368
result._custom_format = custom_format
3371
def get_branch_format(self):
3372
result = BzrDirMetaFormat1.get_branch_format(self)
3373
if not isinstance(result, remote.RemoteBranchFormat):
3374
new_result = remote.RemoteBranchFormat()
3375
new_result._custom_format = result
3377
self.set_branch_format(new_result)
3381
repository_format = property(__return_repository_format,
3382
BzrDirMetaFormat1._set_repository_format) #.im_func)
3385
2281
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
3388
2284
class BzrDirFormatInfo(object):
3390
def __init__(self, native, deprecated, hidden, experimental):
2286
def __init__(self, native, deprecated, hidden):
3391
2287
self.deprecated = deprecated
3392
2288
self.native = native
3393
2289
self.hidden = hidden
3394
self.experimental = experimental
3397
2292
class BzrDirFormatRegistry(registry.Registry):
3398
2293
"""Registry of user-selectable BzrDir subformats.
3400
2295
Differs from BzrDirFormat._control_formats in that it provides sub-formats,
3401
2296
e.g. BzrDirMeta1 with weave repository. Also, it's more user-oriented.
3405
"""Create a BzrDirFormatRegistry."""
3406
self._aliases = set()
3407
self._registration_order = list()
3408
super(BzrDirFormatRegistry, self).__init__()
3411
"""Return a set of the format names which are aliases."""
3412
return frozenset(self._aliases)
3414
2299
def register_metadir(self, key,
3415
2300
repository_format, help, native=True, deprecated=False,
3416
2301
branch_format=None,
3417
2302
tree_format=None,
3421
2304
"""Register a metadir subformat.
3423
2306
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
3424
by the Repository/Branch/WorkingTreeformats.
2307
by the Repository format.
3426
2309
:param repository_format: The fully-qualified repository format class
3427
2310
name as a string.
3455
2338
if repository_format is not None:
3456
2339
bd.repository_format = _load(repository_format)
3458
self.register(key, helper, help, native, deprecated, hidden,
3459
experimental, alias)
2341
self.register(key, helper, help, native, deprecated, hidden)
3461
2343
def register(self, key, factory, help, native=True, deprecated=False,
3462
hidden=False, experimental=False, alias=False):
3463
2345
"""Register a BzrDirFormat factory.
3465
2347
The factory must be a callable that takes one parameter: the key.
3466
2348
It must produce an instance of the BzrDirFormat when called.
3468
2350
This function mainly exists to prevent the info object from being
3469
2351
supplied directly.
3471
registry.Registry.register(self, key, factory, help,
3472
BzrDirFormatInfo(native, deprecated, hidden, experimental))
3474
self._aliases.add(key)
3475
self._registration_order.append(key)
2353
registry.Registry.register(self, key, factory, help,
2354
BzrDirFormatInfo(native, deprecated, hidden))
3477
2356
def register_lazy(self, key, module_name, member_name, help, native=True,
3478
deprecated=False, hidden=False, experimental=False, alias=False):
3479
registry.Registry.register_lazy(self, key, module_name, member_name,
3480
help, BzrDirFormatInfo(native, deprecated, hidden, experimental))
3482
self._aliases.add(key)
3483
self._registration_order.append(key)
2357
deprecated=False, hidden=False):
2358
registry.Registry.register_lazy(self, key, module_name, member_name,
2359
help, BzrDirFormatInfo(native, deprecated, hidden))
3485
2361
def set_default(self, key):
3486
2362
"""Set the 'default' key to be a clone of the supplied key.
3488
2364
This method must be called once and only once.
3490
registry.Registry.register(self, 'default', self.get(key),
2366
registry.Registry.register(self, 'default', self.get(key),
3491
2367
self.get_help(key), info=self.get_info(key))
3492
self._aliases.add('default')
3494
2369
def set_default_repository(self, key):
3495
2370
"""Set the FormatRegistry default and Repository default.
3497
2372
This is a transitional method while Repository.set_default_format
3522
2404
def wrapped(key, help, info):
3523
2405
if info.native:
3524
2406
help = '(native) ' + help
3525
return ':%s:\n%s\n\n' % (key,
3526
textwrap.fill(help, initial_indent=' ',
3527
subsequent_indent=' ',
3528
break_long_words=False))
3529
if default_realkey is not None:
3530
output += wrapped(default_realkey, '(default) %s' % default_help,
3531
self.get_info('default'))
2407
return ' %s:\n%s\n\n' % (key,
2408
textwrap.fill(help, initial_indent=' ',
2409
subsequent_indent=' '))
2410
output += wrapped('%s/default' % default_realkey, default_help,
2411
self.get_info('default'))
3532
2412
deprecated_pairs = []
3533
experimental_pairs = []
3534
2413
for key, help in help_pairs:
3535
2414
info = self.get_info(key)
3536
2415
if info.hidden:
3538
2417
elif info.deprecated:
3539
2418
deprecated_pairs.append((key, help))
3540
elif info.experimental:
3541
experimental_pairs.append((key, help))
3543
2420
output += wrapped(key, help, info)
3544
output += "\nSee :doc:`formats-help` for more about storage formats."
3546
if len(experimental_pairs) > 0:
3547
other_output += "Experimental formats are shown below.\n\n"
3548
for key, help in experimental_pairs:
3549
info = self.get_info(key)
3550
other_output += wrapped(key, help, info)
3553
"No experimental formats are available.\n\n"
3554
2421
if len(deprecated_pairs) > 0:
3555
other_output += "\nDeprecated formats are shown below.\n\n"
2422
output += "Deprecated formats\n------------------\n\n"
3556
2423
for key, help in deprecated_pairs:
3557
2424
info = self.get_info(key)
3558
other_output += wrapped(key, help, info)
3561
"\nNo deprecated formats are available.\n\n"
3563
"\nSee :doc:`formats-help` for more about storage formats."
3565
if topic == 'other-formats':
3571
class RepositoryAcquisitionPolicy(object):
3572
"""Abstract base class for repository acquisition policies.
3574
A repository acquisition policy decides how a BzrDir acquires a repository
3575
for a branch that is being created. The most basic policy decision is
3576
whether to create a new repository or use an existing one.
3578
def __init__(self, stack_on, stack_on_pwd, require_stacking):
3581
:param stack_on: A location to stack on
3582
:param stack_on_pwd: If stack_on is relative, the location it is
3584
:param require_stacking: If True, it is a failure to not stack.
3586
self._stack_on = stack_on
3587
self._stack_on_pwd = stack_on_pwd
3588
self._require_stacking = require_stacking
3590
def configure_branch(self, branch):
3591
"""Apply any configuration data from this policy to the branch.
3593
Default implementation sets repository stacking.
3595
if self._stack_on is None:
3597
if self._stack_on_pwd is None:
3598
stack_on = self._stack_on
3601
stack_on = urlutils.rebase_url(self._stack_on,
3603
branch.bzrdir.root_transport.base)
3604
except errors.InvalidRebaseURLs:
3605
stack_on = self._get_full_stack_on()
3607
branch.set_stacked_on_url(stack_on)
3608
except (errors.UnstackableBranchFormat,
3609
errors.UnstackableRepositoryFormat):
3610
if self._require_stacking:
3613
def requires_stacking(self):
3614
"""Return True if this policy requires stacking."""
3615
return self._stack_on is not None and self._require_stacking
3617
def _get_full_stack_on(self):
3618
"""Get a fully-qualified URL for the stack_on location."""
3619
if self._stack_on is None:
3621
if self._stack_on_pwd is None:
3622
return self._stack_on
3624
return urlutils.join(self._stack_on_pwd, self._stack_on)
3626
def _add_fallback(self, repository, possible_transports=None):
3627
"""Add a fallback to the supplied repository, if stacking is set."""
3628
stack_on = self._get_full_stack_on()
3629
if stack_on is None:
3632
stacked_dir = BzrDir.open(stack_on,
3633
possible_transports=possible_transports)
3634
except errors.JailBreak:
3635
# We keep the stacking details, but we are in the server code so
3636
# actually stacking is not needed.
3639
stacked_repo = stacked_dir.open_branch().repository
3640
except errors.NotBranchError:
3641
stacked_repo = stacked_dir.open_repository()
3643
repository.add_fallback_repository(stacked_repo)
3644
except errors.UnstackableRepositoryFormat:
3645
if self._require_stacking:
3648
self._require_stacking = True
3650
def acquire_repository(self, make_working_trees=None, shared=False):
3651
"""Acquire a repository for this bzrdir.
3653
Implementations may create a new repository or use a pre-exising
3655
:param make_working_trees: If creating a repository, set
3656
make_working_trees to this value (if non-None)
3657
:param shared: If creating a repository, make it shared if True
3658
:return: A repository, is_new_flag (True if the repository was
3661
raise NotImplemented(RepositoryAcquisitionPolicy.acquire_repository)
3664
class CreateRepository(RepositoryAcquisitionPolicy):
3665
"""A policy of creating a new repository"""
3667
def __init__(self, bzrdir, stack_on=None, stack_on_pwd=None,
3668
require_stacking=False):
3671
:param bzrdir: The bzrdir to create the repository on.
3672
:param stack_on: A location to stack on
3673
:param stack_on_pwd: If stack_on is relative, the location it is
3676
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
3678
self._bzrdir = bzrdir
3680
def acquire_repository(self, make_working_trees=None, shared=False):
3681
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
3683
Creates the desired repository in the bzrdir we already have.
3685
stack_on = self._get_full_stack_on()
3687
format = self._bzrdir._format
3688
format.require_stacking(stack_on=stack_on,
3689
possible_transports=[self._bzrdir.root_transport])
3690
if not self._require_stacking:
3691
# We have picked up automatic stacking somewhere.
3692
note('Using default stacking branch %s at %s', self._stack_on,
3694
repository = self._bzrdir.create_repository(shared=shared)
3695
self._add_fallback(repository,
3696
possible_transports=[self._bzrdir.transport])
3697
if make_working_trees is not None:
3698
repository.set_make_working_trees(make_working_trees)
3699
return repository, True
3702
class UseExistingRepository(RepositoryAcquisitionPolicy):
3703
"""A policy of reusing an existing repository"""
3705
def __init__(self, repository, stack_on=None, stack_on_pwd=None,
3706
require_stacking=False):
3709
:param repository: The repository to use.
3710
:param stack_on: A location to stack on
3711
:param stack_on_pwd: If stack_on is relative, the location it is
3714
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
3716
self._repository = repository
3718
def acquire_repository(self, make_working_trees=None, shared=False):
3719
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
3721
Returns an existing repository to use.
3723
self._add_fallback(self._repository,
3724
possible_transports=[self._repository.bzrdir.transport])
3725
return self._repository, False
3728
# Please register new formats after old formats so that formats
3729
# appear in chronological order and format descriptions can build
2425
output += wrapped(key, help, info)
3731
2430
format_registry = BzrDirFormatRegistry()
3732
# The pre-0.8 formats have their repository format network name registered in
3733
# repository.py. MetaDir formats have their repository format network name
3734
# inferred from their disk format string.
3735
2431
format_registry.register('weave', BzrDirFormat6,
3736
2432
'Pre-0.8 format. Slower than knit and does not'
3737
2433
' support checkouts or shared repositories.',
3739
2434
deprecated=True)
2435
format_registry.register_metadir('knit',
2436
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2437
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
2438
branch_format='bzrlib.branch.BzrBranchFormat5',
2439
tree_format='bzrlib.workingtree.WorkingTreeFormat3')
3740
2440
format_registry.register_metadir('metaweave',
3741
2441
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3742
2442
'Transitional format in 0.8. Slower than knit.',
3743
2443
branch_format='bzrlib.branch.BzrBranchFormat5',
3744
2444
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3747
format_registry.register_metadir('knit',
3748
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3749
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
3750
branch_format='bzrlib.branch.BzrBranchFormat5',
3751
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3753
2445
deprecated=True)
3754
2446
format_registry.register_metadir('dirstate',
3755
2447
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3785
2467
'bzr branches. Incompatible with bzr < 0.15.',
3786
2468
branch_format='bzrlib.branch.BzrBranchFormat6',
3787
2469
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3791
format_registry.register_metadir('pack-0.92',
3792
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
3793
help='New in 0.92: Pack-based format with data compatible with '
3794
'dirstate-tags format repositories. Interoperates with '
3795
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3797
branch_format='bzrlib.branch.BzrBranchFormat6',
3798
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3800
format_registry.register_metadir('pack-0.92-subtree',
3801
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
3802
help='New in 0.92: Pack-based format with data compatible with '
3803
'dirstate-with-subtree format repositories. Interoperates with '
3804
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3806
branch_format='bzrlib.branch.BzrBranchFormat6',
3807
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3811
format_registry.register_metadir('rich-root-pack',
3812
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3813
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
3814
'(needed for bzr-svn and bzr-git).',
3815
branch_format='bzrlib.branch.BzrBranchFormat6',
3816
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3819
format_registry.register_metadir('1.6',
3820
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3821
help='A format that allows a branch to indicate that there is another '
3822
'(stacked) repository that should be used to access data that is '
3823
'not present locally.',
3824
branch_format='bzrlib.branch.BzrBranchFormat7',
3825
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3828
format_registry.register_metadir('1.6.1-rich-root',
3829
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3830
help='A variant of 1.6 that supports rich-root data '
3831
'(needed for bzr-svn and bzr-git).',
3832
branch_format='bzrlib.branch.BzrBranchFormat7',
3833
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3836
format_registry.register_metadir('1.9',
3837
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3838
help='A repository format using B+tree indexes. These indexes '
3839
'are smaller in size, have smarter caching and provide faster '
3840
'performance for most operations.',
3841
branch_format='bzrlib.branch.BzrBranchFormat7',
3842
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3845
format_registry.register_metadir('1.9-rich-root',
3846
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3847
help='A variant of 1.9 that supports rich-root data '
3848
'(needed for bzr-svn and bzr-git).',
3849
branch_format='bzrlib.branch.BzrBranchFormat7',
3850
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3853
format_registry.register_metadir('1.14',
3854
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3855
help='A working-tree format that supports content filtering.',
3856
branch_format='bzrlib.branch.BzrBranchFormat7',
3857
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3859
format_registry.register_metadir('1.14-rich-root',
3860
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3861
help='A variant of 1.14 that supports rich-root data '
3862
'(needed for bzr-svn and bzr-git).',
3863
branch_format='bzrlib.branch.BzrBranchFormat7',
3864
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3866
# The following un-numbered 'development' formats should always just be aliases.
3867
format_registry.register_metadir('development-rich-root',
3868
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3869
help='Current development format. Supports rich roots. Can convert data '
3870
'to and from rich-root-pack (and anything compatible with '
3871
'rich-root-pack) format repositories. Repositories and branches in '
3872
'this format can only be read by bzr.dev. Please read '
3873
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3875
branch_format='bzrlib.branch.BzrBranchFormat7',
3876
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3881
format_registry.register_metadir('development-subtree',
3882
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3883
help='Current development format, subtree variant. Can convert data to and '
3884
'from pack-0.92-subtree (and anything compatible with '
3885
'pack-0.92-subtree) format repositories. Repositories and branches in '
3886
'this format can only be read by bzr.dev. Please read '
3887
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3889
branch_format='bzrlib.branch.BzrBranchFormat7',
3890
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3893
alias=False, # Restore to being an alias when an actual development subtree format is added
3894
# This current non-alias status is simply because we did not introduce a
3895
# chk based subtree format.
3898
# And the development formats above will have aliased one of the following:
3899
format_registry.register_metadir('development6-rich-root',
3900
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3901
help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3903
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3905
branch_format='bzrlib.branch.BzrBranchFormat7',
3906
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3911
format_registry.register_metadir('development7-rich-root',
3912
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
3913
help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
3914
'rich roots. Please read '
3915
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3917
branch_format='bzrlib.branch.BzrBranchFormat7',
3918
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3923
format_registry.register_metadir('2a',
3924
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3925
help='First format for bzr 2.0 series.\n'
3926
'Uses group-compress storage.\n'
3927
'Provides rich roots which are a one-way transition.\n',
3928
# 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
3929
# 'rich roots. Supported by bzr 1.16 and later.',
3930
branch_format='bzrlib.branch.BzrBranchFormat7',
3931
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3935
# The following format should be an alias for the rich root equivalent
3936
# of the default format
3937
format_registry.register_metadir('default-rich-root',
3938
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3939
branch_format='bzrlib.branch.BzrBranchFormat7',
3940
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3945
# The current format that is made on 'bzr init'.
3946
format_registry.set_default('2a')
2472
format_registry.set_default('dirstate')