169
144
format.get_format_description(),
172
def clone(self, url, revision_id=None, force_new_repo=False,
173
preserve_stacking=False):
147
def clone(self, url, revision_id=None, force_new_repo=False):
174
148
"""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
150
If urls last component does not exist, it will be created.
152
if revision_id is not None, then the clone operation may tune
180
153
itself to download less data.
181
:param force_new_repo: Do not use a shared repository for the target
154
:param force_new_repo: Do not use a shared repository for the target
182
155
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
157
return self.clone_on_transport(get_transport(url),
187
158
revision_id=revision_id,
188
force_new_repo=force_new_repo,
189
preserve_stacking=preserve_stacking)
159
force_new_repo=force_new_repo)
191
161
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):
162
force_new_repo=False):
194
163
"""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
165
If the target directory does not exist, it will be created.
167
if revision_id is not None, then the clone operation may tune
200
168
itself to download less data.
201
:param force_new_repo: Do not use a shared repository for the target,
169
:param force_new_repo: Do not use a shared repository for the target
202
170
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:
172
transport.ensure_base()
173
result = self._format.initialize_on_transport(transport)
219
175
local_repo = self.find_repository()
220
176
except errors.NoRepositoryPresent:
221
177
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)
179
# may need to copy content in
181
result_repo = local_repo.clone(
183
revision_id=revision_id)
184
result_repo.set_make_working_trees(local_repo.make_working_trees())
187
result_repo = result.find_repository()
188
# fetch content this dir needs.
271
189
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)
190
except errors.NoRepositoryPresent:
191
# needed to make one anyway.
192
result_repo = local_repo.clone(
194
revision_id=revision_id)
195
result_repo.set_make_working_trees(local_repo.make_working_trees())
277
196
# 1 if there is a branch present
278
197
# 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)
200
self.open_branch().clone(result, revision_id=revision_id)
201
except errors.NotBranchError:
204
self.open_workingtree().clone(result)
289
205
except (errors.NoWorkingTree, errors.NotLocalUrl):
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))
359
def find_branches(transport):
360
"""Find all branches under a transport.
362
This will find all branches below the transport, including branches
363
inside other branches. Where possible, it will use
364
Repository.find_branches.
366
To list all the branches that use a particular Repository, see
367
Repository.find_branches
369
def evaluate(bzrdir):
371
repository = bzrdir.open_repository()
372
except errors.NoRepositoryPresent:
375
return False, (None, repository)
377
branch = bzrdir.open_branch()
378
except errors.NotBranchError:
379
return True, (None, None)
381
return True, (branch, None)
383
for branch, repo in BzrDir.find_bzrdirs(transport, evaluate=evaluate):
385
branches.extend(repo.find_branches())
386
if branch is not None:
387
branches.append(branch)
390
def destroy_repository(self):
391
"""Destroy the repository in this BzrDir"""
392
raise NotImplementedError(self.destroy_repository)
234
return format.initialize(base, possible_transports)
394
236
def create_branch(self):
395
237
"""Create a branch in this BzrDir.
397
The bzrdir's format will control what branch format is created.
239
The bzrdirs format will control what branch format is created.
398
240
For more control see BranchFormatXX.create(a_bzrdir).
400
242
raise NotImplementedError(self.create_branch)
402
def destroy_branch(self):
403
"""Destroy the branch in this BzrDir"""
404
raise NotImplementedError(self.destroy_branch)
407
245
def create_branch_and_repo(base, force_new_repo=False, format=None):
408
246
"""Create a new BzrDir, Branch and Repository at the url 'base'.
410
This will use the current default BzrDirFormat unless one is
411
specified, and use whatever
248
This will use the current default BzrDirFormat, and use whatever
412
249
repository format that that uses via bzrdir.create_branch and
413
250
create_repository. If a shared repository is available that is used
418
255
:param base: The URL to create the branch at.
419
256
:param force_new_repo: If True a new repository is always created.
420
:param format: If supplied, the format of branch to create. If not
421
supplied, the default is used.
423
258
bzrdir = BzrDir.create(base, format)
424
259
bzrdir._find_or_create_repository(force_new_repo)
425
260
return bzrdir.create_branch()
427
def determine_repository_policy(self, force_new_repo=False, stack_on=None,
428
stack_on_pwd=None, require_stacking=False):
429
"""Return an object representing a policy to use.
431
This controls whether a new repository is created, and the format of
432
that repository, or some existing shared repository used instead.
434
If stack_on is supplied, will not seek a containing shared repo.
436
:param force_new_repo: If True, require a new repository to be created.
437
:param stack_on: If supplied, the location to stack on. If not
438
supplied, a default_stack_on location may be used.
439
:param stack_on_pwd: If stack_on is relative, the location it is
442
def repository_policy(found_bzrdir):
445
config = found_bzrdir.get_config()
447
stack_on = config.get_default_stack_on()
448
if stack_on is not None:
449
stack_on_pwd = found_bzrdir.root_transport.base
451
# does it have a repository ?
453
repository = found_bzrdir.open_repository()
454
except errors.NoRepositoryPresent:
457
if ((found_bzrdir.root_transport.base !=
458
self.root_transport.base) and not repository.is_shared()):
459
# Don't look higher, can't use a higher shared repo.
467
return UseExistingRepository(repository, stack_on,
468
stack_on_pwd, require_stacking=require_stacking), True
470
return CreateRepository(self, stack_on, stack_on_pwd,
471
require_stacking=require_stacking), True
473
if not force_new_repo:
475
policy = self._find_containing(repository_policy)
476
if policy is not None:
480
return UseExistingRepository(self.open_repository(),
481
stack_on, stack_on_pwd,
482
require_stacking=require_stacking)
483
except errors.NoRepositoryPresent:
485
return CreateRepository(self, stack_on, stack_on_pwd,
486
require_stacking=require_stacking)
488
262
def _find_or_create_repository(self, force_new_repo):
489
263
"""Create a new repository if needed, returning the repository."""
490
policy = self.determine_repository_policy(force_new_repo)
491
return policy.acquire_repository()[0]
265
return self.create_repository()
267
return self.find_repository()
268
except errors.NoRepositoryPresent:
269
return self.create_repository()
494
272
def create_branch_convenience(base, force_new_repo=False,
495
273
force_new_tree=None, format=None,
316
def create_repository(base, shared=False, format=None):
317
"""Create a new BzrDir and Repository at the url 'base'.
319
If no format is supplied, this will default to the current default
320
BzrDirFormat by default, and use whatever repository format that that
321
uses for bzrdirformat.create_repository.
323
:param shared: Create a shared repository rather than a standalone
325
The Repository object is returned.
327
This must be overridden as an instance method in child classes, where
328
it should take no parameters and construct whatever repository format
329
that child class desires.
331
bzrdir = BzrDir.create(base, format)
332
return bzrdir.create_repository(shared)
539
335
def create_standalone_workingtree(base, format=None):
540
336
"""Create a new BzrDir, WorkingTree, Branch and Repository at 'base'.
542
338
'base' must be a local path or a file:// url.
544
This will use the current default BzrDirFormat unless one is
545
specified, and use whatever
340
This will use the current default BzrDirFormat, and use whatever
546
341
repository format that that uses for bzrdirformat.create_workingtree,
547
342
create_branch and create_repository.
549
:param format: Override for the bzrdir format to create.
550
344
:return: The WorkingTree object.
552
346
t = get_transport(base)
553
if not isinstance(t, local.LocalTransport):
347
if not isinstance(t, LocalTransport):
554
348
raise errors.NotLocalUrl(base)
555
349
bzrdir = BzrDir.create_branch_and_repo(base,
556
350
force_new_repo=True,
557
351
format=format).bzrdir
558
352
return bzrdir.create_workingtree()
560
def create_workingtree(self, revision_id=None, from_branch=None,
561
accelerator_tree=None, hardlink=False):
354
def create_workingtree(self, revision_id=None):
562
355
"""Create a working tree at this BzrDir.
564
:param revision_id: create it as of this revision id.
565
:param from_branch: override bzrdir branch (for lightweight checkouts)
566
:param accelerator_tree: A tree which can be used for retrieving file
567
contents more quickly than the revision tree, i.e. a workingtree.
568
The revision tree will be used for cases where accelerator_tree's
569
content is different.
357
revision_id: create it as of this revision id.
571
359
raise NotImplementedError(self.create_workingtree)
573
def backup_bzrdir(self):
574
"""Backup this bzr control directory.
576
:return: Tuple with old path name and new path name
578
pb = ui.ui_factory.nested_progress_bar()
580
# FIXME: bug 300001 -- the backup fails if the backup directory
581
# already exists, but it should instead either remove it or make
582
# a new backup directory.
584
# FIXME: bug 262450 -- the backup directory should have the same
585
# permissions as the .bzr directory (probably a bug in copy_tree)
586
old_path = self.root_transport.abspath('.bzr')
587
new_path = self.root_transport.abspath('backup.bzr')
588
ui.ui_factory.note('making backup of %s\n to %s' % (old_path, new_path,))
589
self.root_transport.copy_tree('.bzr', 'backup.bzr')
590
return (old_path, new_path)
594
def retire_bzrdir(self, limit=10000):
361
def retire_bzrdir(self):
595
362
"""Permanently disable the bzrdir.
597
364
This is done by renaming it to give the user some ability to recover
970
640
relpath is the portion of the path that is contained by the branch.
972
642
bzrdir, relpath = klass.open_containing(location)
973
tree, branch = bzrdir._get_tree_branch()
644
tree = bzrdir.open_workingtree()
645
except (errors.NoWorkingTree, errors.NotLocalUrl):
647
branch = bzrdir.open_branch()
974
650
return tree, branch, relpath
977
def open_containing_tree_branch_or_repository(klass, location):
978
"""Return the working tree, branch and repo contained by a location.
980
Returns (tree, branch, repository, relpath).
981
If there is no tree containing the location, tree will be None.
982
If there is no branch containing the location, branch will be None.
983
If there is no repository containing the location, repository will be
985
relpath is the portion of the path that is contained by the innermost
988
If no tree, branch or repository is found, a NotBranchError is raised.
990
bzrdir, relpath = klass.open_containing(location)
992
tree, branch = bzrdir._get_tree_branch()
993
except errors.NotBranchError:
995
repo = bzrdir.find_repository()
996
return None, None, repo, relpath
997
except (errors.NoRepositoryPresent):
998
raise errors.NotBranchError(location)
999
return tree, branch, branch.repository, relpath
1001
652
def open_repository(self, _unsupported=False):
1002
653
"""Open the repository object at this BzrDir if one is present.
1004
This will not follow the Branch object pointer - it's strictly a direct
655
This will not follow the Branch object pointer - its strictly a direct
1005
656
open facility. Most client code should use open_branch().repository to
1006
657
get at a repository.
1008
:param _unsupported: a private parameter, not part of the api.
659
_unsupported is a private parameter, not part of the api.
1009
660
TODO: static convenience version of this?
1011
662
raise NotImplementedError(self.open_repository)
1013
664
def open_workingtree(self, _unsupported=False,
1014
recommend_upgrade=True, from_branch=None):
665
recommend_upgrade=True):
1015
666
"""Open the workingtree object at this BzrDir if one is present.
1017
668
:param recommend_upgrade: Optional keyword parameter, when True (the
1018
669
default), emit through the ui module a recommendation that the user
1019
670
upgrade the working tree when the workingtree being opened is old
1020
671
(but still fully supported).
1021
:param from_branch: override bzrdir branch (for lightweight checkouts)
1023
673
raise NotImplementedError(self.open_workingtree)
1025
675
def has_branch(self):
1026
676
"""Tell if this bzrdir contains a branch.
1028
678
Note: if you're going to open the branch, you should just go ahead
1029
and try, and not ask permission first. (This method just opens the
1030
branch and discards it, and that's somewhat expensive.)
679
and try, and not ask permission first. (This method just opens the
680
branch and discards it, and that's somewhat expensive.)
1033
683
self.open_branch()
1134
764
if revision_id is not None, then the clone operation may tune
1135
765
itself to download less data.
1136
:param accelerator_tree: A tree which can be used for retrieving file
1137
contents more quickly than the revision tree, i.e. a workingtree.
1138
The revision tree will be used for cases where accelerator_tree's
1139
content is different.
1140
:param hardlink: If true, hard-link files from accelerator_tree,
1142
:param stacked: If true, create a stacked branch referring to the
1143
location of this control directory.
1144
:param create_tree_if_local: If true, a working-tree will be created
1145
when working locally.
1147
target_transport = get_transport(url, possible_transports)
767
target_transport = get_transport(url)
1148
768
target_transport.ensure_base()
1149
cloning_format = self.cloning_metadir(stacked)
1150
# Create/update the result branch
769
cloning_format = self.cloning_metadir()
1151
770
result = cloning_format.initialize_on_transport(target_transport)
1152
# if a stacked branch wasn't requested, we don't create one
1153
# even if the origin was stacked
1154
stacked_branch_url = None
1155
if source_branch is not None:
1157
stacked_branch_url = self.root_transport.base
772
source_branch = self.open_branch()
1158
773
source_repository = source_branch.repository
1161
source_branch = self.open_branch()
1162
source_repository = source_branch.repository
1164
stacked_branch_url = self.root_transport.base
1165
except errors.NotBranchError:
1166
source_branch = None
1168
source_repository = self.open_repository()
1169
except errors.NoRepositoryPresent:
1170
source_repository = None
1171
repository_policy = result.determine_repository_policy(
1172
force_new_repo, stacked_branch_url, require_stacking=stacked)
1173
result_repo, is_new_repo = repository_policy.acquire_repository()
1174
if is_new_repo and revision_id is not None and not stacked:
1175
fetch_spec = graph.PendingAncestryResult(
1176
[revision_id], source_repository)
1179
if source_repository is not None:
1180
# Fetch while stacked to prevent unstacked fetch from
1182
if fetch_spec is None:
774
except errors.NotBranchError:
777
source_repository = self.open_repository()
778
except errors.NoRepositoryPresent:
779
source_repository = None
784
result_repo = result.find_repository()
785
except errors.NoRepositoryPresent:
787
if source_repository is None and result_repo is not None:
789
elif source_repository is None and result_repo is None:
790
# no repo available, make a new one
791
result.create_repository()
792
elif source_repository is not None and result_repo is None:
793
# have source, and want to make a new target repo
794
result_repo = source_repository.sprout(result, revision_id=revision_id)
796
# fetch needed content into target.
797
if source_repository is not None:
799
# source_repository.copy_content_into(result_repo, revision_id=revision_id)
800
# so we can override the copy method
1183
801
result_repo.fetch(source_repository, revision_id=revision_id)
1185
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
1187
if source_branch is None:
1188
# this is for sprouting a bzrdir without a branch; is that
1190
# Not especially, but it's part of the contract.
1191
result_branch = result.create_branch()
802
if source_branch is not None:
803
source_branch.sprout(result, revision_id=revision_id)
1193
result_branch = source_branch.sprout(result,
1194
revision_id=revision_id, repository_policy=repository_policy)
1195
mutter("created new branch %r" % (result_branch,))
1197
# Create/update the result working tree
1198
if (create_tree_if_local and
1199
isinstance(target_transport, local.LocalTransport) and
1200
(result_repo is None or result_repo.make_working_trees())):
1201
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
805
result.create_branch()
806
# TODO: jam 20060426 we probably need a test in here in the
807
# case that the newly sprouted branch is a remote one
808
if result_repo is None or result_repo.make_working_trees():
809
wt = result.create_workingtree()
1205
812
if wt.path2id('') is None:
1233
838
sublocation = source_branch.reference_parent(file_id, path)
1234
839
sublocation.bzrdir.sprout(target,
1235
840
basis.get_reference_revision(file_id, path),
1236
force_new_repo=force_new_repo, recurse=recurse,
841
force_new_repo=force_new_repo, recurse=recurse)
1239
843
if basis is not None:
1243
def push_branch(self, source, revision_id=None, overwrite=False,
1244
remember=False, create_prefix=False):
1245
"""Push the source branch into this BzrDir."""
1247
# If we can open a branch, use its direct repository, otherwise see
1248
# if there is a repository without a branch.
1250
br_to = self.open_branch()
1251
except errors.NotBranchError:
1252
# Didn't find a branch, can we find a repository?
1253
repository_to = self.find_repository()
1255
# Found a branch, so we must have found a repository
1256
repository_to = br_to.repository
1258
push_result = PushResult()
1259
push_result.source_branch = source
1261
# We have a repository but no branch, copy the revisions, and then
1263
repository_to.fetch(source.repository, revision_id=revision_id)
1264
br_to = source.clone(self, revision_id=revision_id)
1265
if source.get_push_location() is None or remember:
1266
source.set_push_location(br_to.base)
1267
push_result.stacked_on = None
1268
push_result.branch_push_result = None
1269
push_result.old_revno = None
1270
push_result.old_revid = _mod_revision.NULL_REVISION
1271
push_result.target_branch = br_to
1272
push_result.master_branch = None
1273
push_result.workingtree_updated = False
1275
# We have successfully opened the branch, remember if necessary:
1276
if source.get_push_location() is None or remember:
1277
source.set_push_location(br_to.base)
1279
tree_to = self.open_workingtree()
1280
except errors.NotLocalUrl:
1281
push_result.branch_push_result = source.push(br_to,
1282
overwrite, stop_revision=revision_id)
1283
push_result.workingtree_updated = False
1284
except errors.NoWorkingTree:
1285
push_result.branch_push_result = source.push(br_to,
1286
overwrite, stop_revision=revision_id)
1287
push_result.workingtree_updated = None # Not applicable
1289
tree_to.lock_write()
1291
push_result.branch_push_result = source.push(
1292
tree_to.branch, overwrite, stop_revision=revision_id)
1296
push_result.workingtree_updated = True
1297
push_result.old_revno = push_result.branch_push_result.old_revno
1298
push_result.old_revid = push_result.branch_push_result.old_revid
1299
push_result.target_branch = \
1300
push_result.branch_push_result.target_branch
1304
class BzrDirHooks(hooks.Hooks):
1305
"""Hooks for BzrDir operations."""
1308
"""Create the default hooks."""
1309
hooks.Hooks.__init__(self)
1310
self.create_hook(hooks.HookPoint('pre_open',
1311
"Invoked before attempting to open a BzrDir with the transport "
1312
"that the open will use.", (1, 14), None))
1314
# install the default hooks
1315
BzrDir.hooks = BzrDirHooks()
1318
848
class BzrDirPreSplitOut(BzrDir):
1319
849
"""A common class for the all-in-one formats."""
1880
1306
def initialize_on_transport(self, transport):
1881
1307
"""Initialize a new bzrdir in the base directory of a Transport."""
1883
# can we hand off the request to the smart server rather than using
1885
client_medium = transport.get_smart_medium()
1886
except errors.NoSmartMedium:
1887
return self._initialize_on_transport_vfs(transport)
1889
# Current RPC's only know how to create bzr metadir1 instances, so
1890
# we still delegate to vfs methods if the requested format is not a
1892
if type(self) != BzrDirMetaFormat1:
1893
return self._initialize_on_transport_vfs(transport)
1894
remote_format = RemoteBzrDirFormat()
1895
self._supply_sub_formats_to(remote_format)
1896
return remote_format.initialize_on_transport(transport)
1898
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1899
create_prefix=False, force_new_repo=False, stacked_on=None,
1900
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1901
shared_repo=False, vfs_only=False):
1902
"""Create this format on transport.
1904
The directory to initialize will be created.
1906
:param force_new_repo: Do not use a shared repository for the target,
1907
even if one is available.
1908
:param create_prefix: Create any missing directories leading up to
1910
:param use_existing_dir: Use an existing directory if one exists.
1911
:param stacked_on: A url to stack any created branch on, None to follow
1912
any target stacking policy.
1913
:param stack_on_pwd: If stack_on is relative, the location it is
1915
:param repo_format_name: If non-None, a repository will be
1916
made-or-found. Should none be found, or if force_new_repo is True
1917
the repo_format_name is used to select the format of repository to
1919
:param make_working_trees: Control the setting of make_working_trees
1920
for a new shared repository when one is made. None to use whatever
1921
default the format has.
1922
:param shared_repo: Control whether made repositories are shared or
1924
:param vfs_only: If True do not attempt to use a smart server
1925
:return: repo, bzrdir, require_stacking, repository_policy. repo is
1926
None if none was created or found, bzrdir is always valid.
1927
require_stacking is the result of examining the stacked_on
1928
parameter and any stacking policy found for the target.
1931
# Try to hand off to a smart server
1933
client_medium = transport.get_smart_medium()
1934
except errors.NoSmartMedium:
1937
# TODO: lookup the local format from a server hint.
1938
remote_dir_format = RemoteBzrDirFormat()
1939
remote_dir_format._network_name = self.network_name()
1940
self._supply_sub_formats_to(remote_dir_format)
1941
return remote_dir_format.initialize_on_transport_ex(transport,
1942
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1943
force_new_repo=force_new_repo, stacked_on=stacked_on,
1944
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1945
make_working_trees=make_working_trees, shared_repo=shared_repo)
1946
# XXX: Refactor the create_prefix/no_create_prefix code into a
1947
# common helper function
1948
# The destination may not exist - if so make it according to policy.
1949
def make_directory(transport):
1950
transport.mkdir('.')
1952
def redirected(transport, e, redirection_notice):
1953
note(redirection_notice)
1954
return transport._redirected_to(e.source, e.target)
1956
transport = do_catching_redirections(make_directory, transport,
1958
except errors.FileExists:
1959
if not use_existing_dir:
1961
except errors.NoSuchFile:
1962
if not create_prefix:
1964
transport.create_prefix()
1966
require_stacking = (stacked_on is not None)
1967
# Now the target directory exists, but doesn't have a .bzr
1968
# directory. So we need to create it, along with any work to create
1969
# all of the dependent branches, etc.
1971
result = self.initialize_on_transport(transport)
1972
if repo_format_name:
1974
# use a custom format
1975
result._format.repository_format = \
1976
repository.network_format_registry.get(repo_format_name)
1977
except AttributeError:
1978
# The format didn't permit it to be set.
1980
# A repository is desired, either in-place or shared.
1981
repository_policy = result.determine_repository_policy(
1982
force_new_repo, stacked_on, stack_on_pwd,
1983
require_stacking=require_stacking)
1984
result_repo, is_new_repo = repository_policy.acquire_repository(
1985
make_working_trees, shared_repo)
1986
if not require_stacking and repository_policy._require_stacking:
1987
require_stacking = True
1988
result._format.require_stacking()
1989
result_repo.lock_write()
1992
repository_policy = None
1993
return result_repo, result, require_stacking, repository_policy
1995
def _initialize_on_transport_vfs(self, transport):
1996
"""Initialize a new bzrdir using VFS calls.
1998
:param transport: The transport to create the .bzr directory in.
2001
# Since we are creating a .bzr directory, inherit the
1308
# Since we don't have a .bzr directory, inherit the
2002
1309
# mode from the root directory
2003
1310
temp_control = lockable_files.LockableFiles(transport,
2004
1311
'', lockable_files.TransportLock)
2394
1645
def set_branch_format(self, format):
2395
1646
self._branch_format = format
2397
def require_stacking(self, stack_on=None, possible_transports=None,
2399
"""We have a request to stack, try to ensure the formats support it.
2401
:param stack_on: If supplied, it is the URL to a branch that we want to
2402
stack on. Check to see if that format supports stacking before
2405
# Stacking is desired. requested by the target, but does the place it
2406
# points at support stacking? If it doesn't then we should
2407
# not implicitly upgrade. We check this here.
2408
new_repo_format = None
2409
new_branch_format = None
2411
# a bit of state for get_target_branch so that we don't try to open it
2412
# 2 times, for both repo *and* branch
2413
target = [None, False, None] # target_branch, checked, upgrade anyway
2414
def get_target_branch():
2416
# We've checked, don't check again
2418
if stack_on is None:
2419
# No target format, that means we want to force upgrading
2420
target[:] = [None, True, True]
2423
target_dir = BzrDir.open(stack_on,
2424
possible_transports=possible_transports)
2425
except errors.NotBranchError:
2426
# Nothing there, don't change formats
2427
target[:] = [None, True, False]
2429
except errors.JailBreak:
2430
# JailBreak, JFDI and upgrade anyway
2431
target[:] = [None, True, True]
2434
target_branch = target_dir.open_branch()
2435
except errors.NotBranchError:
2436
# No branch, don't upgrade formats
2437
target[:] = [None, True, False]
2439
target[:] = [target_branch, True, False]
2442
if (not _skip_repo and
2443
not self.repository_format.supports_external_lookups):
2444
# We need to upgrade the Repository.
2445
target_branch, _, do_upgrade = get_target_branch()
2446
if target_branch is None:
2447
# We don't have a target branch, should we upgrade anyway?
2449
# stack_on is inaccessible, JFDI.
2450
# TODO: bad monkey, hard-coded formats...
2451
if self.repository_format.rich_root_data:
2452
new_repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
2454
new_repo_format = pack_repo.RepositoryFormatKnitPack5()
2456
# If the target already supports stacking, then we know the
2457
# project is already able to use stacking, so auto-upgrade
2459
new_repo_format = target_branch.repository._format
2460
if not new_repo_format.supports_external_lookups:
2461
# target doesn't, source doesn't, so don't auto upgrade
2463
new_repo_format = None
2464
if new_repo_format is not None:
2465
self.repository_format = new_repo_format
2466
note('Source repository format does not support stacking,'
2467
' using format:\n %s',
2468
new_repo_format.get_format_description())
2470
if not self.get_branch_format().supports_stacking():
2471
# We just checked the repo, now lets check if we need to
2472
# upgrade the branch format
2473
target_branch, _, do_upgrade = get_target_branch()
2474
if target_branch is None:
2476
# TODO: bad monkey, hard-coded formats...
2477
new_branch_format = branch.BzrBranchFormat7()
2479
new_branch_format = target_branch._format
2480
if not new_branch_format.supports_stacking():
2481
new_branch_format = None
2482
if new_branch_format is not None:
2483
# Does support stacking, use its format.
2484
self.set_branch_format(new_branch_format)
2485
note('Source branch format does not support stacking,'
2486
' using format:\n %s',
2487
new_branch_format.get_format_description())
2489
1648
def get_converter(self, format=None):
2490
1649
"""See BzrDirFormat.get_converter()."""
2491
1650
if format is None:
3092
2222
# TODO: conversions of Branch and Tree should be done by
3093
2223
# InterXFormat lookups
3094
2224
if (isinstance(tree, workingtree.WorkingTree3) and
3095
not isinstance(tree, workingtree_4.DirStateWorkingTree) and
2225
not isinstance(tree, workingtree_4.WorkingTree4) and
3096
2226
isinstance(self.target_format.workingtree_format,
3097
workingtree_4.DirStateWorkingTreeFormat)):
2227
workingtree_4.WorkingTreeFormat4)):
3098
2228
workingtree_4.Converter3to4().convert(tree)
3099
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
3100
not isinstance(tree, workingtree_4.WorkingTree5) and
3101
isinstance(self.target_format.workingtree_format,
3102
workingtree_4.WorkingTreeFormat5)):
3103
workingtree_4.Converter4to5().convert(tree)
3104
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
3105
not isinstance(tree, workingtree_4.WorkingTree6) and
3106
isinstance(self.target_format.workingtree_format,
3107
workingtree_4.WorkingTreeFormat6)):
3108
workingtree_4.Converter4or5to6().convert(tree)
3110
2229
return to_convert
3113
# This is not in remote.py because it's relatively small, and needs to be
3114
# registered. Putting it in remote.py creates a circular import problem.
2232
# This is not in remote.py because it's small, and needs to be registered.
2233
# Putting it in remote.py creates a circular import problem.
3115
2234
# we can make it a lazy object if the control formats is turned into something
3116
2235
# like a registry.
3117
2236
class RemoteBzrDirFormat(BzrDirMetaFormat1):
3118
2237
"""Format representing bzrdirs accessed via a smart server"""
3121
BzrDirMetaFormat1.__init__(self)
3122
# XXX: It's a bit ugly that the network name is here, because we'd
3123
# like to believe that format objects are stateless or at least
3124
# immutable, However, we do at least avoid mutating the name after
3125
# it's returned. See <https://bugs.edge.launchpad.net/bzr/+bug/504102>
3126
self._network_name = None
3129
return "%s(_network_name=%r)" % (self.__class__.__name__,
3132
2239
def get_format_description(self):
3133
if self._network_name:
3134
real_format = network_format_registry.get(self._network_name)
3135
return 'Remote: ' + real_format.get_format_description()
3136
2240
return 'bzr remote bzrdir'
3138
def get_format_string(self):
3139
raise NotImplementedError(self.get_format_string)
3141
def network_name(self):
3142
if self._network_name:
3143
return self._network_name
3145
raise AssertionError("No network name set.")
3148
2243
def probe_transport(klass, transport):
3149
2244
"""Return a RemoteBzrDirFormat object if it looks possible."""
3151
medium = transport.get_smart_medium()
2246
client = transport.get_smart_client()
3152
2247
except (NotImplementedError, AttributeError,
3153
errors.TransportNotPossible, errors.NoSmartMedium,
3154
errors.SmartProtocolError):
2248
errors.TransportNotPossible):
3155
2249
# no smart server, so not a branch for this format type.
3156
2250
raise errors.NotBranchError(path=transport.base)
3158
# Decline to open it if the server doesn't support our required
3159
# version (3) so that the VFS-based transport will do it.
3160
if medium.should_probe():
3162
server_version = medium.protocol_version()
3163
except errors.SmartProtocolError:
3164
# Apparently there's no usable smart server there, even though
3165
# the medium supports the smart protocol.
3166
raise errors.NotBranchError(path=transport.base)
3167
if server_version != '2':
3168
raise errors.NotBranchError(path=transport.base)
2252
# Send a 'hello' request in protocol version one, and decline to
2253
# open it if the server doesn't support our required version (2) so
2254
# that the VFS-based transport will do it.
2255
request = client.get_request()
2256
smart_protocol = protocol.SmartClientRequestProtocolOne(request)
2257
server_version = smart_protocol.query_version()
2258
if server_version != 2:
2259
raise errors.NotBranchError(path=transport.base)
3171
2262
def initialize_on_transport(self, transport):
3173
2264
# hand off the request to the smart server
3174
client_medium = transport.get_smart_medium()
2265
medium = transport.get_smart_medium()
3175
2266
except errors.NoSmartMedium:
3176
2267
# TODO: lookup the local format from a server hint.
3177
2268
local_dir_format = BzrDirMetaFormat1()
3178
2269
return local_dir_format.initialize_on_transport(transport)
3179
client = _SmartClient(client_medium)
2270
client = _SmartClient(medium)
3180
2271
path = client.remote_path_from_transport(transport)
3182
response = client.call('BzrDirFormat.initialize', path)
3183
except errors.ErrorFromSmartServer, err:
3184
remote._translate_error(err, path=path)
3185
if response[0] != 'ok':
3186
raise errors.SmartProtocolError('unexpected response code %s' % (response,))
3187
format = RemoteBzrDirFormat()
3188
self._supply_sub_formats_to(format)
3189
return remote.RemoteBzrDir(transport, format)
3191
def parse_NoneTrueFalse(self, arg):
3198
raise AssertionError("invalid arg %r" % arg)
3200
def _serialize_NoneTrueFalse(self, arg):
3207
def _serialize_NoneString(self, arg):
3210
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
3211
create_prefix=False, force_new_repo=False, stacked_on=None,
3212
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
3215
# hand off the request to the smart server
3216
client_medium = transport.get_smart_medium()
3217
except errors.NoSmartMedium:
3220
# Decline to open it if the server doesn't support our required
3221
# version (3) so that the VFS-based transport will do it.
3222
if client_medium.should_probe():
3224
server_version = client_medium.protocol_version()
3225
if server_version != '2':
3229
except errors.SmartProtocolError:
3230
# Apparently there's no usable smart server there, even though
3231
# the medium supports the smart protocol.
3236
client = _SmartClient(client_medium)
3237
path = client.remote_path_from_transport(transport)
3238
if client_medium._is_remote_before((1, 16)):
3241
# TODO: lookup the local format from a server hint.
3242
local_dir_format = BzrDirMetaFormat1()
3243
self._supply_sub_formats_to(local_dir_format)
3244
return local_dir_format.initialize_on_transport_ex(transport,
3245
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
3246
force_new_repo=force_new_repo, stacked_on=stacked_on,
3247
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
3248
make_working_trees=make_working_trees, shared_repo=shared_repo,
3250
return self._initialize_on_transport_ex_rpc(client, path, transport,
3251
use_existing_dir, create_prefix, force_new_repo, stacked_on,
3252
stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
3254
def _initialize_on_transport_ex_rpc(self, client, path, transport,
3255
use_existing_dir, create_prefix, force_new_repo, stacked_on,
3256
stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
3258
args.append(self._serialize_NoneTrueFalse(use_existing_dir))
3259
args.append(self._serialize_NoneTrueFalse(create_prefix))
3260
args.append(self._serialize_NoneTrueFalse(force_new_repo))
3261
args.append(self._serialize_NoneString(stacked_on))
3262
# stack_on_pwd is often/usually our transport
3265
stack_on_pwd = transport.relpath(stack_on_pwd)
3266
if not stack_on_pwd:
3268
except errors.PathNotChild:
3270
args.append(self._serialize_NoneString(stack_on_pwd))
3271
args.append(self._serialize_NoneString(repo_format_name))
3272
args.append(self._serialize_NoneTrueFalse(make_working_trees))
3273
args.append(self._serialize_NoneTrueFalse(shared_repo))
3274
request_network_name = self._network_name or \
3275
BzrDirFormat.get_default_format().network_name()
3277
response = client.call('BzrDirFormat.initialize_ex_1.16',
3278
request_network_name, path, *args)
3279
except errors.UnknownSmartMethod:
3280
client._medium._remember_remote_is_before((1,16))
3281
local_dir_format = BzrDirMetaFormat1()
3282
self._supply_sub_formats_to(local_dir_format)
3283
return local_dir_format.initialize_on_transport_ex(transport,
3284
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
3285
force_new_repo=force_new_repo, stacked_on=stacked_on,
3286
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
3287
make_working_trees=make_working_trees, shared_repo=shared_repo,
3289
except errors.ErrorFromSmartServer, err:
3290
remote._translate_error(err, path=path)
3291
repo_path = response[0]
3292
bzrdir_name = response[6]
3293
require_stacking = response[7]
3294
require_stacking = self.parse_NoneTrueFalse(require_stacking)
3295
format = RemoteBzrDirFormat()
3296
format._network_name = bzrdir_name
3297
self._supply_sub_formats_to(format)
3298
bzrdir = remote.RemoteBzrDir(transport, format, _client=client)
3300
repo_format = remote.response_tuple_to_repo_format(response[1:])
3301
if repo_path == '.':
3304
repo_bzrdir_format = RemoteBzrDirFormat()
3305
repo_bzrdir_format._network_name = response[5]
3306
repo_bzr = remote.RemoteBzrDir(transport.clone(repo_path),
3310
final_stack = response[8] or None
3311
final_stack_pwd = response[9] or None
3313
final_stack_pwd = urlutils.join(
3314
transport.base, final_stack_pwd)
3315
remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
3316
if len(response) > 10:
3317
# Updated server verb that locks remotely.
3318
repo_lock_token = response[10] or None
3319
remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
3321
remote_repo.dont_leave_lock_in_place()
3323
remote_repo.lock_write()
3324
policy = UseExistingRepository(remote_repo, final_stack,
3325
final_stack_pwd, require_stacking)
3326
policy.acquire_repository()
3330
bzrdir._format.set_branch_format(self.get_branch_format())
3331
if require_stacking:
3332
# The repo has already been created, but we need to make sure that
3333
# we'll make a stackable branch.
3334
bzrdir._format.require_stacking(_skip_repo=True)
3335
return remote_repo, bzrdir, require_stacking, policy
2272
response = _SmartClient(medium).call('BzrDirFormat.initialize', path)
2273
assert response[0] in ('ok', ), 'unexpected response code %s' % (response,)
2274
return remote.RemoteBzrDir(transport)
3337
2276
def _open(self, transport):
3338
return remote.RemoteBzrDir(transport, self)
2277
return remote.RemoteBzrDir(transport)
3340
2279
def __eq__(self, other):
3341
2280
if not isinstance(other, RemoteBzrDirFormat):
3343
2282
return self.get_format_description() == other.get_format_description()
3345
def __return_repository_format(self):
3346
# Always return a RemoteRepositoryFormat object, but if a specific bzr
3347
# repository format has been asked for, tell the RemoteRepositoryFormat
3348
# that it should use that for init() etc.
3349
result = remote.RemoteRepositoryFormat()
3350
custom_format = getattr(self, '_repository_format', None)
3352
if isinstance(custom_format, remote.RemoteRepositoryFormat):
3353
return custom_format
3355
# We will use the custom format to create repositories over the
3356
# wire; expose its details like rich_root_data for code to
3358
result._custom_format = custom_format
3361
def get_branch_format(self):
3362
result = BzrDirMetaFormat1.get_branch_format(self)
3363
if not isinstance(result, remote.RemoteBranchFormat):
3364
new_result = remote.RemoteBranchFormat()
3365
new_result._custom_format = result
3367
self.set_branch_format(new_result)
3371
repository_format = property(__return_repository_format,
3372
BzrDirMetaFormat1._set_repository_format) #.im_func)
3375
2285
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
3378
2288
class BzrDirFormatInfo(object):
3380
def __init__(self, native, deprecated, hidden, experimental):
2290
def __init__(self, native, deprecated, hidden):
3381
2291
self.deprecated = deprecated
3382
2292
self.native = native
3383
2293
self.hidden = hidden
3384
self.experimental = experimental
3387
2296
class BzrDirFormatRegistry(registry.Registry):
3388
2297
"""Registry of user-selectable BzrDir subformats.
3390
2299
Differs from BzrDirFormat._control_formats in that it provides sub-formats,
3391
2300
e.g. BzrDirMeta1 with weave repository. Also, it's more user-oriented.
3395
"""Create a BzrDirFormatRegistry."""
3396
self._aliases = set()
3397
self._registration_order = list()
3398
super(BzrDirFormatRegistry, self).__init__()
3401
"""Return a set of the format names which are aliases."""
3402
return frozenset(self._aliases)
3404
2303
def register_metadir(self, key,
3405
2304
repository_format, help, native=True, deprecated=False,
3406
2305
branch_format=None,
3407
2306
tree_format=None,
3411
2308
"""Register a metadir subformat.
3413
2310
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
3414
by the Repository/Branch/WorkingTreeformats.
2311
by the Repository format.
3416
2313
:param repository_format: The fully-qualified repository format class
3417
2314
name as a string.
3445
2342
if repository_format is not None:
3446
2343
bd.repository_format = _load(repository_format)
3448
self.register(key, helper, help, native, deprecated, hidden,
3449
experimental, alias)
2345
self.register(key, helper, help, native, deprecated, hidden)
3451
2347
def register(self, key, factory, help, native=True, deprecated=False,
3452
hidden=False, experimental=False, alias=False):
3453
2349
"""Register a BzrDirFormat factory.
3455
2351
The factory must be a callable that takes one parameter: the key.
3456
2352
It must produce an instance of the BzrDirFormat when called.
3458
2354
This function mainly exists to prevent the info object from being
3459
2355
supplied directly.
3461
registry.Registry.register(self, key, factory, help,
3462
BzrDirFormatInfo(native, deprecated, hidden, experimental))
3464
self._aliases.add(key)
3465
self._registration_order.append(key)
2357
registry.Registry.register(self, key, factory, help,
2358
BzrDirFormatInfo(native, deprecated, hidden))
3467
2360
def register_lazy(self, key, module_name, member_name, help, native=True,
3468
deprecated=False, hidden=False, experimental=False, alias=False):
3469
registry.Registry.register_lazy(self, key, module_name, member_name,
3470
help, BzrDirFormatInfo(native, deprecated, hidden, experimental))
3472
self._aliases.add(key)
3473
self._registration_order.append(key)
2361
deprecated=False, hidden=False):
2362
registry.Registry.register_lazy(self, key, module_name, member_name,
2363
help, BzrDirFormatInfo(native, deprecated, hidden))
3475
2365
def set_default(self, key):
3476
2366
"""Set the 'default' key to be a clone of the supplied key.
3478
2368
This method must be called once and only once.
3480
registry.Registry.register(self, 'default', self.get(key),
2370
registry.Registry.register(self, 'default', self.get(key),
3481
2371
self.get_help(key), info=self.get_info(key))
3482
self._aliases.add('default')
3484
2373
def set_default_repository(self, key):
3485
2374
"""Set the FormatRegistry default and Repository default.
3487
2376
This is a transitional method while Repository.set_default_format
3512
2408
def wrapped(key, help, info):
3513
2409
if info.native:
3514
2410
help = '(native) ' + help
3515
return ':%s:\n%s\n\n' % (key,
3516
textwrap.fill(help, initial_indent=' ',
3517
subsequent_indent=' ',
3518
break_long_words=False))
3519
if default_realkey is not None:
3520
output += wrapped(default_realkey, '(default) %s' % default_help,
3521
self.get_info('default'))
2411
return ' %s:\n%s\n\n' % (key,
2412
textwrap.fill(help, initial_indent=' ',
2413
subsequent_indent=' '))
2414
output += wrapped('%s/default' % default_realkey, default_help,
2415
self.get_info('default'))
3522
2416
deprecated_pairs = []
3523
experimental_pairs = []
3524
2417
for key, help in help_pairs:
3525
2418
info = self.get_info(key)
3526
2419
if info.hidden:
3528
2421
elif info.deprecated:
3529
2422
deprecated_pairs.append((key, help))
3530
elif info.experimental:
3531
experimental_pairs.append((key, help))
3533
2424
output += wrapped(key, help, info)
3534
output += "\nSee :doc:`formats-help` for more about storage formats."
3536
if len(experimental_pairs) > 0:
3537
other_output += "Experimental formats are shown below.\n\n"
3538
for key, help in experimental_pairs:
3539
info = self.get_info(key)
3540
other_output += wrapped(key, help, info)
3543
"No experimental formats are available.\n\n"
3544
2425
if len(deprecated_pairs) > 0:
3545
other_output += "\nDeprecated formats are shown below.\n\n"
2426
output += "Deprecated formats\n------------------\n\n"
3546
2427
for key, help in deprecated_pairs:
3547
2428
info = self.get_info(key)
3548
other_output += wrapped(key, help, info)
3551
"\nNo deprecated formats are available.\n\n"
3553
"\nSee :doc:`formats-help` for more about storage formats."
3555
if topic == 'other-formats':
3561
class RepositoryAcquisitionPolicy(object):
3562
"""Abstract base class for repository acquisition policies.
3564
A repository acquisition policy decides how a BzrDir acquires a repository
3565
for a branch that is being created. The most basic policy decision is
3566
whether to create a new repository or use an existing one.
3568
def __init__(self, stack_on, stack_on_pwd, require_stacking):
3571
:param stack_on: A location to stack on
3572
:param stack_on_pwd: If stack_on is relative, the location it is
3574
:param require_stacking: If True, it is a failure to not stack.
3576
self._stack_on = stack_on
3577
self._stack_on_pwd = stack_on_pwd
3578
self._require_stacking = require_stacking
3580
def configure_branch(self, branch):
3581
"""Apply any configuration data from this policy to the branch.
3583
Default implementation sets repository stacking.
3585
if self._stack_on is None:
3587
if self._stack_on_pwd is None:
3588
stack_on = self._stack_on
3591
stack_on = urlutils.rebase_url(self._stack_on,
3593
branch.bzrdir.root_transport.base)
3594
except errors.InvalidRebaseURLs:
3595
stack_on = self._get_full_stack_on()
3597
branch.set_stacked_on_url(stack_on)
3598
except (errors.UnstackableBranchFormat,
3599
errors.UnstackableRepositoryFormat):
3600
if self._require_stacking:
3603
def requires_stacking(self):
3604
"""Return True if this policy requires stacking."""
3605
return self._stack_on is not None and self._require_stacking
3607
def _get_full_stack_on(self):
3608
"""Get a fully-qualified URL for the stack_on location."""
3609
if self._stack_on is None:
3611
if self._stack_on_pwd is None:
3612
return self._stack_on
3614
return urlutils.join(self._stack_on_pwd, self._stack_on)
3616
def _add_fallback(self, repository, possible_transports=None):
3617
"""Add a fallback to the supplied repository, if stacking is set."""
3618
stack_on = self._get_full_stack_on()
3619
if stack_on is None:
3622
stacked_dir = BzrDir.open(stack_on,
3623
possible_transports=possible_transports)
3624
except errors.JailBreak:
3625
# We keep the stacking details, but we are in the server code so
3626
# actually stacking is not needed.
3629
stacked_repo = stacked_dir.open_branch().repository
3630
except errors.NotBranchError:
3631
stacked_repo = stacked_dir.open_repository()
3633
repository.add_fallback_repository(stacked_repo)
3634
except errors.UnstackableRepositoryFormat:
3635
if self._require_stacking:
3638
self._require_stacking = True
3640
def acquire_repository(self, make_working_trees=None, shared=False):
3641
"""Acquire a repository for this bzrdir.
3643
Implementations may create a new repository or use a pre-exising
3645
:param make_working_trees: If creating a repository, set
3646
make_working_trees to this value (if non-None)
3647
:param shared: If creating a repository, make it shared if True
3648
:return: A repository, is_new_flag (True if the repository was
3651
raise NotImplemented(RepositoryAcquisitionPolicy.acquire_repository)
3654
class CreateRepository(RepositoryAcquisitionPolicy):
3655
"""A policy of creating a new repository"""
3657
def __init__(self, bzrdir, stack_on=None, stack_on_pwd=None,
3658
require_stacking=False):
3661
:param bzrdir: The bzrdir to create the repository on.
3662
:param stack_on: A location to stack on
3663
:param stack_on_pwd: If stack_on is relative, the location it is
3666
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
3668
self._bzrdir = bzrdir
3670
def acquire_repository(self, make_working_trees=None, shared=False):
3671
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
3673
Creates the desired repository in the bzrdir we already have.
3675
stack_on = self._get_full_stack_on()
3677
format = self._bzrdir._format
3678
format.require_stacking(stack_on=stack_on,
3679
possible_transports=[self._bzrdir.root_transport])
3680
if not self._require_stacking:
3681
# We have picked up automatic stacking somewhere.
3682
note('Using default stacking branch %s at %s', self._stack_on,
3684
repository = self._bzrdir.create_repository(shared=shared)
3685
self._add_fallback(repository,
3686
possible_transports=[self._bzrdir.transport])
3687
if make_working_trees is not None:
3688
repository.set_make_working_trees(make_working_trees)
3689
return repository, True
3692
class UseExistingRepository(RepositoryAcquisitionPolicy):
3693
"""A policy of reusing an existing repository"""
3695
def __init__(self, repository, stack_on=None, stack_on_pwd=None,
3696
require_stacking=False):
3699
:param repository: The repository to use.
3700
:param stack_on: A location to stack on
3701
:param stack_on_pwd: If stack_on is relative, the location it is
3704
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
3706
self._repository = repository
3708
def acquire_repository(self, make_working_trees=None, shared=False):
3709
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
3711
Returns an existing repository to use.
3713
self._add_fallback(self._repository,
3714
possible_transports=[self._repository.bzrdir.transport])
3715
return self._repository, False
3718
# Please register new formats after old formats so that formats
3719
# appear in chronological order and format descriptions can build
2429
output += wrapped(key, help, info)
3721
2434
format_registry = BzrDirFormatRegistry()
3722
# The pre-0.8 formats have their repository format network name registered in
3723
# repository.py. MetaDir formats have their repository format network name
3724
# inferred from their disk format string.
3725
2435
format_registry.register('weave', BzrDirFormat6,
3726
2436
'Pre-0.8 format. Slower than knit and does not'
3727
2437
' support checkouts or shared repositories.',
3729
2438
deprecated=True)
2439
format_registry.register_metadir('knit',
2440
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2441
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
2442
branch_format='bzrlib.branch.BzrBranchFormat5',
2443
tree_format='bzrlib.workingtree.WorkingTreeFormat3')
3730
2444
format_registry.register_metadir('metaweave',
3731
2445
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3732
2446
'Transitional format in 0.8. Slower than knit.',
3733
2447
branch_format='bzrlib.branch.BzrBranchFormat5',
3734
2448
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3737
format_registry.register_metadir('knit',
3738
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3739
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
3740
branch_format='bzrlib.branch.BzrBranchFormat5',
3741
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3743
2449
deprecated=True)
3744
2450
format_registry.register_metadir('dirstate',
3745
2451
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3775
2471
'bzr branches. Incompatible with bzr < 0.15.',
3776
2472
branch_format='bzrlib.branch.BzrBranchFormat6',
3777
2473
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3781
format_registry.register_metadir('pack-0.92',
3782
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
3783
help='New in 0.92: Pack-based format with data compatible with '
3784
'dirstate-tags format repositories. Interoperates with '
3785
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3787
branch_format='bzrlib.branch.BzrBranchFormat6',
3788
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3790
format_registry.register_metadir('pack-0.92-subtree',
3791
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
3792
help='New in 0.92: Pack-based format with data compatible with '
3793
'dirstate-with-subtree format repositories. Interoperates with '
3794
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3796
branch_format='bzrlib.branch.BzrBranchFormat6',
3797
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3801
format_registry.register_metadir('rich-root-pack',
3802
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3803
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
3804
'(needed for bzr-svn and bzr-git).',
3805
branch_format='bzrlib.branch.BzrBranchFormat6',
3806
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3809
format_registry.register_metadir('1.6',
3810
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3811
help='A format that allows a branch to indicate that there is another '
3812
'(stacked) repository that should be used to access data that is '
3813
'not present locally.',
3814
branch_format='bzrlib.branch.BzrBranchFormat7',
3815
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3818
format_registry.register_metadir('1.6.1-rich-root',
3819
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3820
help='A variant of 1.6 that supports rich-root data '
3821
'(needed for bzr-svn and bzr-git).',
3822
branch_format='bzrlib.branch.BzrBranchFormat7',
3823
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3826
format_registry.register_metadir('1.9',
3827
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3828
help='A repository format using B+tree indexes. These indexes '
3829
'are smaller in size, have smarter caching and provide faster '
3830
'performance for most operations.',
3831
branch_format='bzrlib.branch.BzrBranchFormat7',
3832
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3835
format_registry.register_metadir('1.9-rich-root',
3836
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3837
help='A variant of 1.9 that supports rich-root data '
3838
'(needed for bzr-svn and bzr-git).',
3839
branch_format='bzrlib.branch.BzrBranchFormat7',
3840
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3843
format_registry.register_metadir('1.14',
3844
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3845
help='A working-tree format that supports content filtering.',
3846
branch_format='bzrlib.branch.BzrBranchFormat7',
3847
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3849
format_registry.register_metadir('1.14-rich-root',
3850
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3851
help='A variant of 1.14 that supports rich-root data '
3852
'(needed for bzr-svn and bzr-git).',
3853
branch_format='bzrlib.branch.BzrBranchFormat7',
3854
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3856
# The following un-numbered 'development' formats should always just be aliases.
3857
format_registry.register_metadir('development-rich-root',
3858
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3859
help='Current development format. Supports rich roots. Can convert data '
3860
'to and from rich-root-pack (and anything compatible with '
3861
'rich-root-pack) format repositories. Repositories and branches in '
3862
'this format can only be read by bzr.dev. Please read '
3863
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3865
branch_format='bzrlib.branch.BzrBranchFormat7',
3866
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3871
format_registry.register_metadir('development-subtree',
3872
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3873
help='Current development format, subtree variant. Can convert data to and '
3874
'from pack-0.92-subtree (and anything compatible with '
3875
'pack-0.92-subtree) format repositories. Repositories and branches in '
3876
'this format can only be read by bzr.dev. Please read '
3877
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3879
branch_format='bzrlib.branch.BzrBranchFormat7',
3880
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3883
alias=False, # Restore to being an alias when an actual development subtree format is added
3884
# This current non-alias status is simply because we did not introduce a
3885
# chk based subtree format.
3888
# And the development formats above will have aliased one of the following:
3889
format_registry.register_metadir('development6-rich-root',
3890
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3891
help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3893
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3895
branch_format='bzrlib.branch.BzrBranchFormat7',
3896
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3901
format_registry.register_metadir('development7-rich-root',
3902
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
3903
help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
3904
'rich roots. Please read '
3905
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3907
branch_format='bzrlib.branch.BzrBranchFormat7',
3908
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3913
format_registry.register_metadir('2a',
3914
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3915
help='First format for bzr 2.0 series.\n'
3916
'Uses group-compress storage.\n'
3917
'Provides rich roots which are a one-way transition.\n',
3918
# 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
3919
# 'rich roots. Supported by bzr 1.16 and later.',
3920
branch_format='bzrlib.branch.BzrBranchFormat7',
3921
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3925
# The following format should be an alias for the rich root equivalent
3926
# of the default format
3927
format_registry.register_metadir('default-rich-root',
3928
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3929
branch_format='bzrlib.branch.BzrBranchFormat7',
3930
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3935
# The current format that is made on 'bzr init'.
3936
format_registry.set_default('2a')
2476
format_registry.set_default('dirstate')