131
83
thing_to_unlock.break_lock()
133
def check_conversion_target(self, target_format):
134
"""Check that a bzrdir as a whole can be converted to a new format."""
135
# The only current restriction is that the repository content can be
136
# fetched compatibly with the target.
137
target_repo_format = target_format.repository_format
139
self.open_repository()._format.check_conversion_target(
141
except errors.NoRepositoryPresent:
142
# No repo, no problem.
85
def can_convert_format(self):
86
"""Return true if this bzrdir is one whose format we can convert from."""
146
def _check_supported(format, allow_unsupported,
147
recommend_upgrade=True,
149
"""Give an error or warning on old formats.
151
:param format: may be any kind of format - workingtree, branch,
154
:param allow_unsupported: If true, allow opening
155
formats that are strongly deprecated, and which may
156
have limited functionality.
158
:param recommend_upgrade: If true (default), warn
159
the user through the ui object that they may wish
160
to upgrade the object.
90
def _check_supported(format, allow_unsupported):
91
"""Check whether format is a supported format.
93
If allow_unsupported is True, this is a no-op.
162
# TODO: perhaps move this into a base Format class; it's not BzrDir
163
# specific. mbp 20070323
164
95
if not allow_unsupported and not format.is_supported():
165
96
# see open_downlevel to open legacy branches.
166
97
raise errors.UnsupportedFormatError(format=format)
167
if recommend_upgrade \
168
and getattr(format, 'upgrade_recommended', False):
169
ui.ui_factory.recommend_upgrade(
170
format.get_format_description(),
173
def clone_on_transport(self, transport, revision_id=None,
174
force_new_repo=False, preserve_stacking=False, stacked_on=None,
175
create_prefix=False, use_existing_dir=True, no_tree=False):
176
"""Clone this bzrdir and its contents to transport verbatim.
178
:param transport: The transport for the location to produce the clone
179
at. If the target directory does not exist, it will be created.
180
:param revision_id: The tip revision-id to use for any branch or
181
working tree. If not None, then the clone operation may tune
99
def clone(self, url, revision_id=None, basis=None, force_new_repo=False):
100
"""Clone this bzrdir and its contents to url verbatim.
102
If urls last component does not exist, it will be created.
104
if revision_id is not None, then the clone operation may tune
182
105
itself to download less data.
183
:param force_new_repo: Do not use a shared repository for the target,
106
:param force_new_repo: Do not use a shared repository for the target
184
107
even if one is available.
185
:param preserve_stacking: When cloning a stacked branch, stack the
186
new branch on top of the other branch's stacked-on branch.
187
:param create_prefix: Create any missing directories leading up to
189
:param use_existing_dir: Use an existing directory if one exists.
191
# Overview: put together a broad description of what we want to end up
192
# with; then make as few api calls as possible to do it.
194
# We may want to create a repo/branch/tree, if we do so what format
195
# would we want for each:
196
require_stacking = (stacked_on is not None)
197
format = self.cloning_metadir(require_stacking)
199
# Figure out what objects we want:
110
basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
111
result = self._format.initialize(url)
201
113
local_repo = self.find_repository()
202
114
except errors.NoRepositoryPresent:
203
115
local_repo = None
205
local_branch = self.open_branch()
206
except errors.NotBranchError:
209
# enable fallbacks when branch is not a branch reference
210
if local_branch.repository.has_same_location(local_repo):
211
local_repo = local_branch.repository
212
if preserve_stacking:
214
stacked_on = local_branch.get_stacked_on_url()
215
except (errors.UnstackableBranchFormat,
216
errors.UnstackableRepositoryFormat,
219
# Bug: We create a metadir without knowing if it can support stacking,
220
# we should look up the policy needs first, or just use it as a hint,
223
make_working_trees = local_repo.make_working_trees() and not no_tree
224
want_shared = local_repo.is_shared()
225
repo_format_name = format.repository_format.network_name()
227
make_working_trees = False
229
repo_format_name = None
231
result_repo, result, require_stacking, repository_policy = \
232
format.initialize_on_transport_ex(transport,
233
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
234
force_new_repo=force_new_repo, stacked_on=stacked_on,
235
stack_on_pwd=self.root_transport.base,
236
repo_format_name=repo_format_name,
237
make_working_trees=make_working_trees, shared_repo=want_shared)
240
# If the result repository is in the same place as the
241
# resulting bzr dir, it will have no content, further if the
242
# result is not stacked then we know all content should be
243
# copied, and finally if we are copying up to a specific
244
# revision_id then we can use the pending-ancestry-result which
245
# does not require traversing all of history to describe it.
246
if (result_repo.user_url == result.user_url
247
and not require_stacking and
248
revision_id is not None):
249
fetch_spec = graph.PendingAncestryResult(
250
[revision_id], local_repo)
251
result_repo.fetch(local_repo, fetch_spec=fetch_spec)
117
# may need to copy content in
119
result_repo = local_repo.clone(
121
revision_id=revision_id,
123
result_repo.set_make_working_trees(local_repo.make_working_trees())
126
result_repo = result.find_repository()
127
# fetch content this dir needs.
129
# XXX FIXME RBC 20060214 need tests for this when the basis
131
result_repo.fetch(basis_repo, revision_id=revision_id)
253
132
result_repo.fetch(local_repo, revision_id=revision_id)
257
if result_repo is not None:
258
raise AssertionError('result_repo not None(%r)' % result_repo)
133
except errors.NoRepositoryPresent:
134
# needed to make one anyway.
135
result_repo = local_repo.clone(
137
revision_id=revision_id,
139
result_repo.set_make_working_trees(local_repo.make_working_trees())
259
140
# 1 if there is a branch present
260
141
# make sure its content is available in the target repository
262
if local_branch is not None:
263
result_branch = local_branch.clone(result, revision_id=revision_id,
264
repository_policy=repository_policy)
266
# Cheaper to check if the target is not local, than to try making
268
result.root_transport.local_abspath('.')
269
if result_repo is None or result_repo.make_working_trees():
270
self.open_workingtree().clone(result)
144
self.open_branch().clone(result, revision_id=revision_id)
145
except errors.NotBranchError:
148
self.open_workingtree().clone(result, basis=basis_tree)
271
149
except (errors.NoWorkingTree, errors.NotLocalUrl):
153
def _get_basis_components(self, basis):
154
"""Retrieve the basis components that are available at basis."""
156
return None, None, None
158
basis_tree = basis.open_workingtree()
159
basis_branch = basis_tree.branch
160
basis_repo = basis_branch.repository
161
except (errors.NoWorkingTree, errors.NotLocalUrl):
164
basis_branch = basis.open_branch()
165
basis_repo = basis_branch.repository
166
except errors.NotBranchError:
169
basis_repo = basis.open_repository()
170
except errors.NoRepositoryPresent:
172
return basis_repo, basis_branch, basis_tree
275
174
# TODO: This should be given a Transport, and should chdir up; otherwise
276
175
# this will open a new connection.
277
176
def _make_tail(self, url):
278
t = get_transport(url)
282
def find_bzrdirs(transport, evaluate=None, list_current=None):
283
"""Find bzrdirs recursively from current location.
285
This is intended primarily as a building block for more sophisticated
286
functionality, like finding trees under a directory, or finding
287
branches that use a given repository.
288
:param evaluate: An optional callable that yields recurse, value,
289
where recurse controls whether this bzrdir is recursed into
290
and value is the value to yield. By default, all bzrdirs
291
are recursed into, and the return value is the bzrdir.
292
:param list_current: if supplied, use this function to list the current
293
directory, instead of Transport.list_dir
294
:return: a generator of found bzrdirs, or whatever evaluate returns.
296
if list_current is None:
297
def list_current(transport):
298
return transport.list_dir('')
300
def evaluate(bzrdir):
303
pending = [transport]
304
while len(pending) > 0:
305
current_transport = pending.pop()
308
bzrdir = BzrDir.open_from_transport(current_transport)
309
except (errors.NotBranchError, errors.PermissionDenied):
312
recurse, value = evaluate(bzrdir)
315
subdirs = list_current(current_transport)
316
except (errors.NoSuchFile, errors.PermissionDenied):
319
for subdir in sorted(subdirs, reverse=True):
320
pending.append(current_transport.clone(subdir))
323
def find_branches(transport):
324
"""Find all branches under a transport.
326
This will find all branches below the transport, including branches
327
inside other branches. Where possible, it will use
328
Repository.find_branches.
330
To list all the branches that use a particular Repository, see
331
Repository.find_branches
333
def evaluate(bzrdir):
335
repository = bzrdir.open_repository()
336
except errors.NoRepositoryPresent:
339
return False, ([], repository)
340
return True, (bzrdir.list_branches(), None)
342
for branches, repo in BzrDir.find_bzrdirs(transport,
345
ret.extend(repo.find_branches())
346
if branches is not None:
351
def create_branch_and_repo(base, force_new_repo=False, format=None):
177
head, tail = urlutils.split(url)
178
if tail and tail != '.':
179
t = bzrlib.transport.get_transport(head)
182
except errors.FileExists:
185
# TODO: Should take a Transport
187
def create(cls, base):
188
"""Create a new BzrDir at the url 'base'.
190
This will call the current default formats initialize with base
191
as the only parameter.
193
If you need a specific format, consider creating an instance
194
of that and calling initialize().
196
if cls is not BzrDir:
197
raise AssertionError("BzrDir.create always creates the default format, "
198
"not one of %r" % cls)
199
head, tail = urlutils.split(base)
200
if tail and tail != '.':
201
t = bzrlib.transport.get_transport(head)
204
except errors.FileExists:
206
return BzrDirFormat.get_default_format().initialize(safe_unicode(base))
208
def create_branch(self):
209
"""Create a branch in this BzrDir.
211
The bzrdirs format will control what branch format is created.
212
For more control see BranchFormatXX.create(a_bzrdir).
214
raise NotImplementedError(self.create_branch)
217
def create_branch_and_repo(base, force_new_repo=False):
352
218
"""Create a new BzrDir, Branch and Repository at the url 'base'.
354
This will use the current default BzrDirFormat unless one is
355
specified, and use whatever
220
This will use the current default BzrDirFormat, and use whatever
356
221
repository format that that uses via bzrdir.create_branch and
357
222
create_repository. If a shared repository is available that is used
454
258
The created Branch object is returned.
455
259
If a working tree cannot be made due to base not being a file:// url,
456
no error is raised unless force_new_tree is True, in which case no
260
no error is raised unless force_new_tree is True, in which case no
457
261
data is created on disk and NotLocalUrl is raised.
459
263
:param base: The URL to create the branch at.
460
264
:param force_new_repo: If True a new repository is always created.
461
:param force_new_tree: If True or False force creation of a tree or
265
:param force_new_tree: If True or False force creation of a tree or
462
266
prevent such creation respectively.
463
:param format: Override for the bzrdir format to create.
464
:param possible_transports: An optional reusable transports list.
267
:param format: Override for the for the bzrdir format to create
466
269
if force_new_tree:
467
270
# check for non local urls
468
t = get_transport(base, possible_transports)
469
if not isinstance(t, local.LocalTransport):
271
t = get_transport(safe_unicode(base))
272
if not isinstance(t, LocalTransport):
470
273
raise errors.NotLocalUrl(base)
471
bzrdir = BzrDir.create(base, format, possible_transports)
275
bzrdir = BzrDir.create(base)
277
bzrdir = format.initialize(base)
472
278
repo = bzrdir._find_or_create_repository(force_new_repo)
473
279
result = bzrdir.create_branch()
474
if force_new_tree or (repo.make_working_trees() and
280
if force_new_tree or (repo.make_working_trees() and
475
281
force_new_tree is None):
477
283
bzrdir.create_workingtree()
478
284
except errors.NotLocalUrl:
483
def create_standalone_workingtree(base, format=None):
289
def create_repository(base, shared=False):
290
"""Create a new BzrDir and Repository at the url 'base'.
292
This will use the current default BzrDirFormat, and use whatever
293
repository format that that uses for bzrdirformat.create_repository.
295
;param shared: Create a shared repository rather than a standalone
297
The Repository object is returned.
299
This must be overridden as an instance method in child classes, where
300
it should take no parameters and construct whatever repository format
301
that child class desires.
303
bzrdir = BzrDir.create(base)
304
return bzrdir.create_repository(shared)
307
def create_standalone_workingtree(base):
484
308
"""Create a new BzrDir, WorkingTree, Branch and Repository at 'base'.
486
310
'base' must be a local path or a file:// url.
488
This will use the current default BzrDirFormat unless one is
489
specified, and use whatever
312
This will use the current default BzrDirFormat, and use whatever
490
313
repository format that that uses for bzrdirformat.create_workingtree,
491
314
create_branch and create_repository.
493
:param format: Override for the bzrdir format to create.
494
:return: The WorkingTree object.
316
The WorkingTree object is returned.
496
t = get_transport(base)
497
if not isinstance(t, local.LocalTransport):
318
t = get_transport(safe_unicode(base))
319
if not isinstance(t, LocalTransport):
498
320
raise errors.NotLocalUrl(base)
499
bzrdir = BzrDir.create_branch_and_repo(base,
501
format=format).bzrdir
321
bzrdir = BzrDir.create_branch_and_repo(safe_unicode(base),
322
force_new_repo=True).bzrdir
502
323
return bzrdir.create_workingtree()
504
@deprecated_method(deprecated_in((2, 3, 0)))
505
def generate_backup_name(self, base):
506
return self._available_backup_name(base)
508
def _available_backup_name(self, base):
509
"""Find a non-existing backup file name based on base.
511
See bzrlib.osutils.available_backup_name about race conditions.
513
return osutils.available_backup_name(base, self.root_transport.has)
515
def backup_bzrdir(self):
516
"""Backup this bzr control directory.
518
:return: Tuple with old path name and new path name
521
pb = ui.ui_factory.nested_progress_bar()
325
def create_workingtree(self, revision_id=None):
326
"""Create a working tree at this BzrDir.
328
revision_id: create it as of this revision id.
330
raise NotImplementedError(self.create_workingtree)
332
def find_repository(self):
333
"""Find the repository that should be used for a_bzrdir.
335
This does not require a branch as we use it to find the repo for
336
new branches as well as to hook existing branches up to their
523
old_path = self.root_transport.abspath('.bzr')
524
backup_dir = self._available_backup_name('backup.bzr')
525
new_path = self.root_transport.abspath(backup_dir)
526
ui.ui_factory.note('making backup of %s\n to %s'
527
% (old_path, new_path,))
528
self.root_transport.copy_tree('.bzr', backup_dir)
529
return (old_path, new_path)
533
def retire_bzrdir(self, limit=10000):
534
"""Permanently disable the bzrdir.
536
This is done by renaming it to give the user some ability to recover
537
if there was a problem.
539
This will have horrible consequences if anyone has anything locked or
541
:param limit: number of times to retry
546
to_path = '.bzr.retired.%d' % i
547
self.root_transport.rename('.bzr', to_path)
548
note("renamed %s to %s"
549
% (self.root_transport.abspath('.bzr'), to_path))
551
except (errors.TransportError, IOError, errors.PathError):
558
def _find_containing(self, evaluate):
559
"""Find something in a containing control directory.
561
This method will scan containing control dirs, until it finds what
562
it is looking for, decides that it will never find it, or runs out
563
of containing control directories to check.
565
It is used to implement find_repository and
566
determine_repository_policy.
568
:param evaluate: A function returning (value, stop). If stop is True,
569
the value will be returned.
573
result, stop = evaluate(found_bzrdir)
576
next_transport = found_bzrdir.root_transport.clone('..')
577
if (found_bzrdir.user_url == next_transport.base):
578
# top of the file system
340
return self.open_repository()
341
except errors.NoRepositoryPresent:
343
next_transport = self.root_transport.clone('..')
580
345
# find the next containing bzrdir
582
347
found_bzrdir = BzrDir.open_containing_from_transport(
583
348
next_transport)[0]
584
349
except errors.NotBranchError:
587
def find_repository(self):
588
"""Find the repository that should be used.
590
This does not require a branch as we use it to find the repo for
591
new branches as well as to hook existing branches up to their
594
def usable_repository(found_bzrdir):
351
raise errors.NoRepositoryPresent(self)
595
352
# does it have a repository ?
597
354
repository = found_bzrdir.open_repository()
598
355
except errors.NoRepositoryPresent:
600
if found_bzrdir.user_url == self.user_url:
601
return repository, True
602
elif repository.is_shared():
603
return repository, True
607
found_repo = self._find_containing(usable_repository)
608
if found_repo is None:
609
raise errors.NoRepositoryPresent(self)
612
def _find_creation_modes(self):
613
"""Determine the appropriate modes for files and directories.
615
They're always set to be consistent with the base directory,
616
assuming that this transport allows setting modes.
618
# TODO: Do we need or want an option (maybe a config setting) to turn
619
# this off or override it for particular locations? -- mbp 20080512
620
if self._mode_check_done:
622
self._mode_check_done = True
624
st = self.transport.stat('.')
625
except errors.TransportNotPossible:
626
self._dir_mode = None
627
self._file_mode = None
629
# Check the directory mode, but also make sure the created
630
# directories and files are read-write for this user. This is
631
# mostly a workaround for filesystems which lie about being able to
632
# write to a directory (cygwin & win32)
633
if (st.st_mode & 07777 == 00000):
634
# FTP allows stat but does not return dir/file modes
635
self._dir_mode = None
636
self._file_mode = None
638
self._dir_mode = (st.st_mode & 07777) | 00700
639
# Remove the sticky and execute bits for files
640
self._file_mode = self._dir_mode & ~07111
642
def _get_file_mode(self):
643
"""Return Unix mode for newly created files, or None.
645
if not self._mode_check_done:
646
self._find_creation_modes()
647
return self._file_mode
649
def _get_dir_mode(self):
650
"""Return Unix mode for newly created directories, or None.
652
if not self._mode_check_done:
653
self._find_creation_modes()
654
return self._dir_mode
656
def get_config(self):
657
"""Get configuration for this BzrDir."""
658
return config.BzrDirConfig(self)
660
def _get_config(self):
661
"""By default, no configuration is available."""
356
next_transport = found_bzrdir.root_transport.clone('..')
357
if (found_bzrdir.root_transport.base == next_transport.base):
358
# top of the file system
362
if ((found_bzrdir.root_transport.base ==
363
self.root_transport.base) or repository.is_shared()):
366
raise errors.NoRepositoryPresent(self)
367
raise errors.NoRepositoryPresent(self)
369
def get_branch_transport(self, branch_format):
370
"""Get the transport for use by branch format in this BzrDir.
372
Note that bzr dirs that do not support format strings will raise
373
IncompatibleFormat if the branch format they are given has
374
a format string, and vice versa.
376
If branch_format is None, the transport is returned with no
377
checking. if it is not None, then the returned transport is
378
guaranteed to point to an existing directory ready for use.
380
raise NotImplementedError(self.get_branch_transport)
382
def get_repository_transport(self, repository_format):
383
"""Get the transport for use by repository format in this BzrDir.
385
Note that bzr dirs that do not support format strings will raise
386
IncompatibleFormat if the repository format they are given has
387
a format string, and vice versa.
389
If repository_format is None, the transport is returned with no
390
checking. if it is not None, then the returned transport is
391
guaranteed to point to an existing directory ready for use.
393
raise NotImplementedError(self.get_repository_transport)
395
def get_workingtree_transport(self, tree_format):
396
"""Get the transport for use by workingtree format in this BzrDir.
398
Note that bzr dirs that do not support format strings will raise
399
IncompatibleFormat if the workingtree format they are given has
400
a format string, and vice versa.
402
If workingtree_format is None, the transport is returned with no
403
checking. if it is not None, then the returned transport is
404
guaranteed to point to an existing directory ready for use.
406
raise NotImplementedError(self.get_workingtree_transport)
664
408
def __init__(self, _transport, _format):
665
409
"""Initialize a Bzr control dir object.
667
411
Only really common logic should reside here, concrete classes should be
668
412
made with varying behaviours.
671
415
:param _transport: the transport this dir is based at.
673
417
self._format = _format
674
# these are also under the more standard names of
675
# control_transport and user_transport
676
418
self.transport = _transport.clone('.bzr')
677
419
self.root_transport = _transport
678
self._mode_check_done = False
681
def user_transport(self):
682
return self.root_transport
685
def control_transport(self):
686
return self.transport
688
421
def is_control_filename(self, filename):
689
422
"""True if filename is the name of a path which is reserved for bzrdir's.
691
424
:param filename: A filename within the root transport of this bzrdir.
693
426
This is true IF and ONLY IF the filename is part of the namespace reserved
694
427
for bzr control dirs. Currently this is the '.bzr' directory in the root
695
of the root_transport.
428
of the root_transport. it is expected that plugins will need to extend
429
this in the future - for instance to make bzr talk with svn working
697
# this might be better on the BzrDirFormat class because it refers to
698
# all the possible bzrdir disk formats.
699
# This method is tested via the workingtree is_control_filename tests-
700
# it was extracted from WorkingTree.is_control_filename. If the method's
701
# contract is extended beyond the current trivial implementation, please
432
# this might be better on the BzrDirFormat class because it refers to
433
# all the possible bzrdir disk formats.
434
# This method is tested via the workingtree is_control_filename tests-
435
# it was extracted from WorkingTree.is_control_filename. If the methods
436
# contract is extended beyond the current trivial implementation please
702
437
# add new tests for it to the appropriate place.
703
438
return filename == '.bzr' or filename.startswith('.bzr/')
440
def needs_format_conversion(self, format=None):
441
"""Return true if this bzrdir needs convert_format run on it.
443
For instance, if the repository format is out of date but the
444
branch and working tree are not, this should return True.
446
:param format: Optional parameter indicating a specific desired
447
format we plan to arrive at.
449
raise NotImplementedError(self.needs_format_conversion)
706
452
def open_unsupported(base):
707
453
"""Open a branch which is not supported."""
708
454
return BzrDir.open(base, _unsupported=True)
711
def open(base, _unsupported=False, possible_transports=None):
712
"""Open an existing bzrdir, rooted at 'base' (url).
714
:param _unsupported: a private parameter to the BzrDir class.
716
t = get_transport(base, possible_transports=possible_transports)
717
return BzrDir.open_from_transport(t, _unsupported=_unsupported)
720
def open_from_transport(transport, _unsupported=False,
721
_server_formats=True):
722
"""Open a bzrdir within a particular directory.
724
:param transport: Transport containing the bzrdir.
725
:param _unsupported: private.
727
for hook in BzrDir.hooks['pre_open']:
729
# Keep initial base since 'transport' may be modified while following
731
base = transport.base
732
def find_format(transport):
733
return transport, controldir.ControlDirFormat.find_format(
734
transport, _server_formats=_server_formats)
736
def redirected(transport, e, redirection_notice):
737
redirected_transport = transport._redirected_to(e.source, e.target)
738
if redirected_transport is None:
739
raise errors.NotBranchError(base)
740
note('%s is%s redirected to %s',
741
transport.base, e.permanently, redirected_transport.base)
742
return redirected_transport
745
transport, format = do_catching_redirections(find_format,
748
except errors.TooManyRedirections:
749
raise errors.NotBranchError(base)
457
def open(base, _unsupported=False):
458
"""Open an existing bzrdir, rooted at 'base' (url)
460
_unsupported is a private parameter to the BzrDir class.
462
t = get_transport(base)
463
mutter("trying to open %r with transport %r", base, t)
464
format = BzrDirFormat.find_format(t)
751
465
BzrDir._check_supported(format, _unsupported)
752
return format.open(transport, _found=True)
466
return format.open(t, _found=True)
468
def open_branch(self, unsupported=False):
469
"""Open the branch object at this BzrDir if one is present.
471
If unsupported is True, then no longer supported branch formats can
474
TODO: static convenience version of this?
476
raise NotImplementedError(self.open_branch)
755
def open_containing(url, possible_transports=None):
479
def open_containing(url):
756
480
"""Open an existing branch which contains url.
758
482
:param url: url to search from.
759
483
See open_containing_from_transport for more detail.
761
transport = get_transport(url, possible_transports)
762
return BzrDir.open_containing_from_transport(transport)
485
return BzrDir.open_containing_from_transport(get_transport(url))
765
488
def open_containing_from_transport(a_transport):
766
"""Open an existing branch which contains a_transport.base.
489
"""Open an existing branch which contains a_transport.base
768
491
This probes for a branch at a_transport, and searches upwards from there.
770
493
Basically we keep looking up until we find the control directory or
771
494
run into the root. If there isn't one, raises NotBranchError.
772
If there is one and it is either an unrecognised format or an unsupported
495
If there is one and it is either an unrecognised format or an unsupported
773
496
format, UnknownFormatError or UnsupportedFormatError are raised.
774
497
If there is one, it is returned, along with the unused portion of url.
776
:return: The BzrDir that contains the path, and a Unicode path
499
:return: The BzrDir that contains the path, and a Unicode path
777
500
for the rest of the URL.
779
502
# this gets the normalised url back. I.e. '.' -> the full path.
780
503
url = a_transport.base
783
result = BzrDir.open_from_transport(a_transport)
784
return result, urlutils.unescape(a_transport.relpath(url))
506
format = BzrDirFormat.find_format(a_transport)
507
BzrDir._check_supported(format, False)
508
return format.open(a_transport), urlutils.unescape(a_transport.relpath(url))
785
509
except errors.NotBranchError, e:
510
## mutter('not a branch in: %r %s', a_transport.base, e)
788
new_t = a_transport.clone('..')
789
except errors.InvalidURLJoin:
790
# reached the root, whatever that may be
791
raise errors.NotBranchError(path=url)
512
new_t = a_transport.clone('..')
792
513
if new_t.base == a_transport.base:
793
514
# reached the root, whatever that may be
794
515
raise errors.NotBranchError(path=url)
795
516
a_transport = new_t
798
def open_tree_or_branch(klass, location):
799
"""Return the branch and working tree at a location.
801
If there is no tree at the location, tree will be None.
802
If there is no branch at the location, an exception will be
804
:return: (tree, branch)
806
bzrdir = klass.open(location)
807
return bzrdir._get_tree_branch()
810
def open_containing_tree_or_branch(klass, location):
811
"""Return the branch and working tree contained by a location.
813
Returns (tree, branch, relpath).
814
If there is no tree at containing the location, tree will be None.
815
If there is no branch containing the location, an exception will be
817
relpath is the portion of the path that is contained by the branch.
819
bzrdir, relpath = klass.open_containing(location)
820
tree, branch = bzrdir._get_tree_branch()
821
return tree, branch, relpath
824
def open_containing_tree_branch_or_repository(klass, location):
825
"""Return the working tree, branch and repo contained by a location.
827
Returns (tree, branch, repository, relpath).
828
If there is no tree containing the location, tree will be None.
829
If there is no branch containing the location, branch will be None.
830
If there is no repository containing the location, repository will be
832
relpath is the portion of the path that is contained by the innermost
835
If no tree, branch or repository is found, a NotBranchError is raised.
837
bzrdir, relpath = klass.open_containing(location)
839
tree, branch = bzrdir._get_tree_branch()
840
except errors.NotBranchError:
842
repo = bzrdir.find_repository()
843
return None, None, repo, relpath
844
except (errors.NoRepositoryPresent):
845
raise errors.NotBranchError(location)
846
return tree, branch, branch.repository, relpath
848
def _cloning_metadir(self):
849
"""Produce a metadir suitable for cloning with.
851
:returns: (destination_bzrdir_format, source_repository)
853
result_format = self._format.__class__()
856
branch = self.open_branch(ignore_fallbacks=True)
857
source_repository = branch.repository
858
result_format._branch_format = branch._format
859
except errors.NotBranchError:
518
def open_repository(self, _unsupported=False):
519
"""Open the repository object at this BzrDir if one is present.
521
This will not follow the Branch object pointer - its strictly a direct
522
open facility. Most client code should use open_branch().repository to
525
_unsupported is a private parameter, not part of the api.
526
TODO: static convenience version of this?
528
raise NotImplementedError(self.open_repository)
530
def open_workingtree(self, _unsupported=False):
531
"""Open the workingtree object at this BzrDir if one is present.
533
TODO: static convenience version of this?
535
raise NotImplementedError(self.open_workingtree)
537
def has_branch(self):
538
"""Tell if this bzrdir contains a branch.
540
Note: if you're going to open the branch, you should just go ahead
541
and try, and not ask permission first. (This method just opens the
542
branch and discards it, and that's somewhat expensive.)
547
except errors.NotBranchError:
550
def has_workingtree(self):
551
"""Tell if this bzrdir contains a working tree.
553
This will still raise an exception if the bzrdir has a workingtree that
554
is remote & inaccessible.
556
Note: if you're going to open the working tree, you should just go ahead
557
and try, and not ask permission first. (This method just opens the
558
workingtree and discards it, and that's somewhat expensive.)
561
self.open_workingtree()
563
except errors.NoWorkingTree:
566
def sprout(self, url, revision_id=None, basis=None, force_new_repo=False):
567
"""Create a copy of this bzrdir prepared for use as a new line of
570
If urls last component does not exist, it will be created.
572
Attributes related to the identity of the source branch like
573
branch nickname will be cleaned, a working tree is created
574
whether one existed before or not; and a local branch is always
577
if revision_id is not None, then the clone operation may tune
578
itself to download less data.
581
result = self._format.initialize(url)
582
basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
584
source_branch = self.open_branch()
585
source_repository = source_branch.repository
586
except errors.NotBranchError:
861
589
source_repository = self.open_repository()
862
except errors.NoRepositoryPresent:
863
source_repository = None
865
# XXX TODO: This isinstance is here because we have not implemented
866
# the fix recommended in bug # 103195 - to delegate this choice the
868
repo_format = source_repository._format
869
if isinstance(repo_format, remote.RemoteRepositoryFormat):
870
source_repository._ensure_real()
871
repo_format = source_repository._real_repository._format
872
result_format.repository_format = repo_format
874
# TODO: Couldn't we just probe for the format in these cases,
875
# rather than opening the whole tree? It would be a little
876
# faster. mbp 20070401
877
tree = self.open_workingtree(recommend_upgrade=False)
878
except (errors.NoWorkingTree, errors.NotLocalUrl):
879
result_format.workingtree_format = None
881
result_format.workingtree_format = tree._format.__class__()
882
return result_format, source_repository
884
def cloning_metadir(self, require_stacking=False):
885
"""Produce a metadir suitable for cloning or sprouting with.
887
These operations may produce workingtrees (yes, even though they're
888
"cloning" something that doesn't have a tree), so a viable workingtree
889
format must be selected.
891
:require_stacking: If True, non-stackable formats will be upgraded
892
to similar stackable formats.
893
:returns: a BzrDirFormat with all component formats either set
894
appropriately or set to None if that component should not be
897
format, repository = self._cloning_metadir()
898
if format._workingtree_format is None:
900
if repository is None:
901
# No repository either
903
# We have a repository, so set a working tree? (Why? This seems to
904
# contradict the stated return value in the docstring).
905
tree_format = repository._format._matchingbzrdir.workingtree_format
906
format.workingtree_format = tree_format.__class__()
908
format.require_stacking()
912
def create(cls, base, format=None, possible_transports=None):
913
"""Create a new BzrDir at the url 'base'.
915
:param format: If supplied, the format of branch to create. If not
916
supplied, the default is used.
917
:param possible_transports: If supplied, a list of transports that
918
can be reused to share a remote connection.
920
if cls is not BzrDir:
921
raise AssertionError("BzrDir.create always creates the"
922
"default format, not one of %r" % cls)
923
t = get_transport(base, possible_transports)
926
format = controldir.ControlDirFormat.get_default_format()
927
return format.initialize_on_transport(t)
931
class BzrDirHooks(hooks.Hooks):
932
"""Hooks for BzrDir operations."""
935
"""Create the default hooks."""
936
hooks.Hooks.__init__(self)
937
self.create_hook(hooks.HookPoint('pre_open',
938
"Invoked before attempting to open a BzrDir with the transport "
939
"that the open will use.", (1, 14), None))
940
self.create_hook(hooks.HookPoint('post_repo_init',
941
"Invoked after a repository has been initialized. "
942
"post_repo_init is called with a "
943
"bzrlib.bzrdir.RepoInitHookParams.",
946
# install the default hooks
947
BzrDir.hooks = BzrDirHooks()
950
class RepoInitHookParams(object):
951
"""Object holding parameters passed to *_repo_init hooks.
953
There are 4 fields that hooks may wish to access:
955
:ivar repository: Repository created
956
:ivar format: Repository format
957
:ivar bzrdir: The bzrdir for the repository
958
:ivar shared: The repository is shared
961
def __init__(self, repository, format, a_bzrdir, shared):
962
"""Create a group of RepoInitHook parameters.
964
:param repository: Repository created
965
:param format: Repository format
966
:param bzrdir: The bzrdir for the repository
967
:param shared: The repository is shared
969
self.repository = repository
971
self.bzrdir = a_bzrdir
974
def __eq__(self, other):
975
return self.__dict__ == other.__dict__
979
return "<%s for %s>" % (self.__class__.__name__,
982
return "<%s for %s>" % (self.__class__.__name__,
590
except errors.NoRepositoryPresent:
591
# copy the entire basis one if there is one
592
# but there is no repository.
593
source_repository = basis_repo
598
result_repo = result.find_repository()
599
except errors.NoRepositoryPresent:
601
if source_repository is None and result_repo is not None:
603
elif source_repository is None and result_repo is None:
604
# no repo available, make a new one
605
result.create_repository()
606
elif source_repository is not None and result_repo is None:
607
# have source, and want to make a new target repo
608
# we don't clone the repo because that preserves attributes
609
# like is_shared(), and we have not yet implemented a
610
# repository sprout().
611
result_repo = result.create_repository()
612
if result_repo is not None:
613
# fetch needed content into target.
615
# XXX FIXME RBC 20060214 need tests for this when the basis
617
result_repo.fetch(basis_repo, revision_id=revision_id)
618
result_repo.fetch(source_repository, revision_id=revision_id)
619
if source_branch is not None:
620
source_branch.sprout(result, revision_id=revision_id)
622
result.create_branch()
623
# TODO: jam 20060426 we probably need a test in here in the
624
# case that the newly sprouted branch is a remote one
625
if result_repo is None or result_repo.make_working_trees():
626
result.create_workingtree()
986
630
class BzrDirPreSplitOut(BzrDir):
1433
912
self._check_supported(format, unsupported)
1434
913
return format.open(self, _found=True)
1436
def open_workingtree(self, unsupported=False,
1437
recommend_upgrade=True):
915
def open_workingtree(self, unsupported=False):
1438
916
"""See BzrDir.open_workingtree."""
1439
917
from bzrlib.workingtree import WorkingTreeFormat
1440
918
format = WorkingTreeFormat.find_format(self)
1441
self._check_supported(format, unsupported,
1443
basedir=self.root_transport.base)
919
self._check_supported(format, unsupported)
1444
920
return format.open(self, _found=True)
1446
def _get_config(self):
1447
return config.TransportConfig(self.transport, 'control.conf')
1450
class BzrProber(controldir.Prober):
1451
"""Prober for formats that use a .bzr/ control directory."""
1454
"""The known .bzr formats."""
1457
def register_bzrdir_format(klass, format):
1458
klass._formats[format.get_format_string()] = format
1461
def unregister_bzrdir_format(klass, format):
1462
del klass._formats[format.get_format_string()]
1465
def probe_transport(klass, transport):
1466
"""Return the .bzrdir style format present in a directory."""
1468
format_string = transport.get_bytes(".bzr/branch-format")
1469
except errors.NoSuchFile:
1470
raise errors.NotBranchError(path=transport.base)
1472
return klass._formats[format_string]
1474
raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
1477
controldir.ControlDirFormat.register_prober(BzrProber)
1480
class RemoteBzrProber(controldir.Prober):
1481
"""Prober for remote servers that provide a Bazaar smart server."""
1484
def probe_transport(klass, transport):
1485
"""Return a RemoteBzrDirFormat object if it looks possible."""
1487
medium = transport.get_smart_medium()
1488
except (NotImplementedError, AttributeError,
1489
errors.TransportNotPossible, errors.NoSmartMedium,
1490
errors.SmartProtocolError):
1491
# no smart server, so not a branch for this format type.
1492
raise errors.NotBranchError(path=transport.base)
1494
# Decline to open it if the server doesn't support our required
1495
# version (3) so that the VFS-based transport will do it.
1496
if medium.should_probe():
1498
server_version = medium.protocol_version()
1499
except errors.SmartProtocolError:
1500
# Apparently there's no usable smart server there, even though
1501
# the medium supports the smart protocol.
1502
raise errors.NotBranchError(path=transport.base)
1503
if server_version != '2':
1504
raise errors.NotBranchError(path=transport.base)
1505
return RemoteBzrDirFormat()
1508
class BzrDirFormat(controldir.ControlDirFormat):
1509
"""ControlDirFormat base class for .bzr/ directories.
1511
Formats are placed in a dict by their format string for reference
923
class BzrDirFormat(object):
924
"""An encapsulation of the initialization and open routines for a format.
926
Formats provide three things:
927
* An initialization routine,
931
Formats are placed in an dict by their format string for reference
1512
932
during bzrdir opening. These should be subclasses of BzrDirFormat
1513
933
for consistency.
1515
935
Once a format is deprecated, just deprecate the initialize and open
1516
methods on the format class. Do not deprecate the object, as the
936
methods on the format class. Do not deprecate the object, as the
1517
937
object will be created every system load.
940
_default_format = None
941
"""The default format used for new .bzr dirs."""
944
"""The known formats."""
946
_control_formats = []
947
"""The registered control formats - .bzr, ....
949
This is a list of BzrDirFormat objects.
1520
952
_lock_file_name = 'branch-lock'
1522
954
# _lock_class must be set in subclasses to the lock type, typ.
1523
955
# TransportLock or LockDir
958
def find_format(klass, transport):
959
"""Return the format present at transport."""
960
for format in klass._control_formats:
962
return format.probe_transport(transport)
963
except errors.NotBranchError:
964
# this format does not find a control dir here.
966
raise errors.NotBranchError(path=transport.base)
969
def probe_transport(klass, transport):
970
"""Return the .bzrdir style transport present at URL."""
972
format_string = transport.get(".bzr/branch-format").read()
973
except errors.NoSuchFile:
974
raise errors.NotBranchError(path=transport.base)
977
return klass._formats[format_string]
979
raise errors.UnknownFormatError(format=format_string)
982
def get_default_format(klass):
983
"""Return the current default format."""
984
return klass._default_format
1525
986
def get_format_string(self):
1526
987
"""Return the ASCII format string that identifies this format."""
1527
988
raise NotImplementedError(self.get_format_string)
990
def get_format_description(self):
991
"""Return the short description for this format."""
992
raise NotImplementedError(self.get_format_description)
994
def get_converter(self, format=None):
995
"""Return the converter to use to convert bzrdirs needing converts.
997
This returns a bzrlib.bzrdir.Converter object.
999
This should return the best upgrader to step this format towards the
1000
current default format. In the case of plugins we can/should provide
1001
some means for them to extend the range of returnable converters.
1003
:param format: Optional format to override the default format of the
1006
raise NotImplementedError(self.get_converter)
1008
def initialize(self, url):
1009
"""Create a bzr control dir at this url and return an opened copy.
1011
Subclasses should typically override initialize_on_transport
1012
instead of this method.
1014
return self.initialize_on_transport(get_transport(url))
1529
1016
def initialize_on_transport(self, transport):
1530
1017
"""Initialize a new bzrdir in the base directory of a Transport."""
1532
# can we hand off the request to the smart server rather than using
1534
client_medium = transport.get_smart_medium()
1535
except errors.NoSmartMedium:
1536
return self._initialize_on_transport_vfs(transport)
1538
# Current RPC's only know how to create bzr metadir1 instances, so
1539
# we still delegate to vfs methods if the requested format is not a
1541
if type(self) != BzrDirMetaFormat1:
1542
return self._initialize_on_transport_vfs(transport)
1543
remote_format = RemoteBzrDirFormat()
1544
self._supply_sub_formats_to(remote_format)
1545
return remote_format.initialize_on_transport(transport)
1547
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1548
create_prefix=False, force_new_repo=False, stacked_on=None,
1549
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1550
shared_repo=False, vfs_only=False):
1551
"""Create this format on transport.
1553
The directory to initialize will be created.
1555
:param force_new_repo: Do not use a shared repository for the target,
1556
even if one is available.
1557
:param create_prefix: Create any missing directories leading up to
1559
:param use_existing_dir: Use an existing directory if one exists.
1560
:param stacked_on: A url to stack any created branch on, None to follow
1561
any target stacking policy.
1562
:param stack_on_pwd: If stack_on is relative, the location it is
1564
:param repo_format_name: If non-None, a repository will be
1565
made-or-found. Should none be found, or if force_new_repo is True
1566
the repo_format_name is used to select the format of repository to
1568
:param make_working_trees: Control the setting of make_working_trees
1569
for a new shared repository when one is made. None to use whatever
1570
default the format has.
1571
:param shared_repo: Control whether made repositories are shared or
1573
:param vfs_only: If True do not attempt to use a smart server
1574
:return: repo, bzrdir, require_stacking, repository_policy. repo is
1575
None if none was created or found, bzrdir is always valid.
1576
require_stacking is the result of examining the stacked_on
1577
parameter and any stacking policy found for the target.
1580
# Try to hand off to a smart server
1582
client_medium = transport.get_smart_medium()
1583
except errors.NoSmartMedium:
1586
# TODO: lookup the local format from a server hint.
1587
remote_dir_format = RemoteBzrDirFormat()
1588
remote_dir_format._network_name = self.network_name()
1589
self._supply_sub_formats_to(remote_dir_format)
1590
return remote_dir_format.initialize_on_transport_ex(transport,
1591
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1592
force_new_repo=force_new_repo, stacked_on=stacked_on,
1593
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1594
make_working_trees=make_working_trees, shared_repo=shared_repo)
1595
# XXX: Refactor the create_prefix/no_create_prefix code into a
1596
# common helper function
1597
# The destination may not exist - if so make it according to policy.
1598
def make_directory(transport):
1599
transport.mkdir('.')
1601
def redirected(transport, e, redirection_notice):
1602
note(redirection_notice)
1603
return transport._redirected_to(e.source, e.target)
1605
transport = do_catching_redirections(make_directory, transport,
1607
except errors.FileExists:
1608
if not use_existing_dir:
1610
except errors.NoSuchFile:
1611
if not create_prefix:
1613
transport.create_prefix()
1615
require_stacking = (stacked_on is not None)
1616
# Now the target directory exists, but doesn't have a .bzr
1617
# directory. So we need to create it, along with any work to create
1618
# all of the dependent branches, etc.
1620
result = self.initialize_on_transport(transport)
1621
if repo_format_name:
1623
# use a custom format
1624
result._format.repository_format = \
1625
repository.network_format_registry.get(repo_format_name)
1626
except AttributeError:
1627
# The format didn't permit it to be set.
1629
# A repository is desired, either in-place or shared.
1630
repository_policy = result.determine_repository_policy(
1631
force_new_repo, stacked_on, stack_on_pwd,
1632
require_stacking=require_stacking)
1633
result_repo, is_new_repo = repository_policy.acquire_repository(
1634
make_working_trees, shared_repo)
1635
if not require_stacking and repository_policy._require_stacking:
1636
require_stacking = True
1637
result._format.require_stacking()
1638
result_repo.lock_write()
1641
repository_policy = None
1642
return result_repo, result, require_stacking, repository_policy
1644
def _initialize_on_transport_vfs(self, transport):
1645
"""Initialize a new bzrdir using VFS calls.
1647
:param transport: The transport to create the .bzr directory in.
1650
# Since we are creating a .bzr directory, inherit the
1018
# Since we don't have a .bzr directory, inherit the
1651
1019
# mode from the root directory
1652
temp_control = lockable_files.LockableFiles(transport,
1653
'', lockable_files.TransportLock)
1020
temp_control = LockableFiles(transport, '', TransportLock)
1654
1021
temp_control._transport.mkdir('.bzr',
1655
1022
# FIXME: RBC 20060121 don't peek under
1657
1024
mode=temp_control._dir_mode)
1658
if sys.platform == 'win32' and isinstance(transport, local.LocalTransport):
1659
win32utils.set_file_attr_hidden(transport._abspath('.bzr'))
1660
1025
file_mode = temp_control._file_mode
1661
1026
del temp_control
1662
bzrdir_transport = transport.clone('.bzr')
1663
utf8_files = [('README',
1664
"This is a Bazaar control directory.\n"
1665
"Do not change any files in this directory.\n"
1666
"See http://bazaar-vcs.org/ for more information about Bazaar.\n"),
1027
mutter('created control directory in ' + transport.base)
1028
control = transport.clone('.bzr')
1029
utf8_files = [('README',
1030
"This is a Bazaar-NG control directory.\n"
1031
"Do not change any files in this directory.\n"),
1667
1032
('branch-format', self.get_format_string()),
1669
1034
# NB: no need to escape relative paths that are url safe.
1670
control_files = lockable_files.LockableFiles(bzrdir_transport,
1671
self._lock_file_name, self._lock_class)
1035
control_files = LockableFiles(control, self._lock_file_name,
1672
1037
control_files.create_lock()
1673
1038
control_files.lock_write()
1675
for (filename, content) in utf8_files:
1676
bzrdir_transport.put_bytes(filename, content,
1040
for file, content in utf8_files:
1041
control_files.put_utf8(file, content)
1679
1043
control_files.unlock()
1680
1044
return self.open(transport, _found=True)
1046
def is_supported(self):
1047
"""Is this format supported?
1049
Supported formats must be initializable and openable.
1050
Unsupported formats may not support initialization or committing or
1051
some other features depending on the reason for not being supported.
1056
def known_formats(klass):
1057
"""Return all the known formats.
1059
Concrete formats should override _known_formats.
1061
# There is double indirection here to make sure that control
1062
# formats used by more than one dir format will only be probed
1063
# once. This can otherwise be quite expensive for remote connections.
1065
for format in klass._control_formats:
1066
result.update(format._known_formats())
1070
def _known_formats(klass):
1071
"""Return the known format instances for this control format."""
1072
return set(klass._formats.values())
1682
1074
def open(self, transport, _found=False):
1683
1075
"""Return an instance of this format for the dir transport points at.
1685
1077
_found is a private parameter, do not use it.
1688
found_format = controldir.ControlDirFormat.find_format(transport)
1689
if not isinstance(found_format, self.__class__):
1690
raise AssertionError("%s was asked to open %s, but it seems to need "
1692
% (self, transport, found_format))
1693
# Allow subclasses - use the found format.
1694
self._supply_sub_formats_to(found_format)
1695
return found_format._open(transport)
1080
assert isinstance(BzrDirFormat.find_format(transport),
1696
1082
return self._open(transport)
1698
1084
def _open(self, transport):
2621
1810
if not isinstance(repo._format, self.target_format.repository_format.__class__):
2622
1811
from bzrlib.repository import CopyConverter
2623
ui.ui_factory.note('starting repository conversion')
1812
self.pb.note('starting repository conversion')
2624
1813
converter = CopyConverter(self.target_format.repository_format)
2625
1814
converter.convert(repo, pb)
2626
for branch in self.bzrdir.list_branches():
2627
# TODO: conversions of Branch and Tree should be done by
2628
# InterXFormat lookups/some sort of registry.
2629
# Avoid circular imports
2630
from bzrlib import branch as _mod_branch
2631
old = branch._format.__class__
2632
new = self.target_format.get_branch_format().__class__
2634
if (old == _mod_branch.BzrBranchFormat5 and
2635
new in (_mod_branch.BzrBranchFormat6,
2636
_mod_branch.BzrBranchFormat7,
2637
_mod_branch.BzrBranchFormat8)):
2638
branch_converter = _mod_branch.Converter5to6()
2639
elif (old == _mod_branch.BzrBranchFormat6 and
2640
new in (_mod_branch.BzrBranchFormat7,
2641
_mod_branch.BzrBranchFormat8)):
2642
branch_converter = _mod_branch.Converter6to7()
2643
elif (old == _mod_branch.BzrBranchFormat7 and
2644
new is _mod_branch.BzrBranchFormat8):
2645
branch_converter = _mod_branch.Converter7to8()
2647
raise errors.BadConversionTarget("No converter", new,
2649
branch_converter.convert(branch)
2650
branch = self.bzrdir.open_branch()
2651
old = branch._format.__class__
2653
tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
2654
except (errors.NoWorkingTree, errors.NotLocalUrl):
2657
# TODO: conversions of Branch and Tree should be done by
2658
# InterXFormat lookups
2659
if (isinstance(tree, workingtree.WorkingTree3) and
2660
not isinstance(tree, workingtree_4.DirStateWorkingTree) and
2661
isinstance(self.target_format.workingtree_format,
2662
workingtree_4.DirStateWorkingTreeFormat)):
2663
workingtree_4.Converter3to4().convert(tree)
2664
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
2665
not isinstance(tree, workingtree_4.WorkingTree5) and
2666
isinstance(self.target_format.workingtree_format,
2667
workingtree_4.WorkingTreeFormat5)):
2668
workingtree_4.Converter4to5().convert(tree)
2669
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
2670
not isinstance(tree, workingtree_4.WorkingTree6) and
2671
isinstance(self.target_format.workingtree_format,
2672
workingtree_4.WorkingTreeFormat6)):
2673
workingtree_4.Converter4or5to6().convert(tree)
2675
1815
return to_convert
2678
# This is not in remote.py because it's relatively small, and needs to be
2679
# registered. Putting it in remote.py creates a circular import problem.
2680
# we can make it a lazy object if the control formats is turned into something
2682
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2683
"""Format representing bzrdirs accessed via a smart server"""
2685
supports_workingtrees = False
2688
BzrDirMetaFormat1.__init__(self)
2689
# XXX: It's a bit ugly that the network name is here, because we'd
2690
# like to believe that format objects are stateless or at least
2691
# immutable, However, we do at least avoid mutating the name after
2692
# it's returned. See <https://bugs.launchpad.net/bzr/+bug/504102>
2693
self._network_name = None
2696
return "%s(_network_name=%r)" % (self.__class__.__name__,
2699
def get_format_description(self):
2700
if self._network_name:
2701
real_format = controldir.network_format_registry.get(self._network_name)
2702
return 'Remote: ' + real_format.get_format_description()
2703
return 'bzr remote bzrdir'
2705
def get_format_string(self):
2706
raise NotImplementedError(self.get_format_string)
2708
def network_name(self):
2709
if self._network_name:
2710
return self._network_name
2712
raise AssertionError("No network name set.")
2714
def initialize_on_transport(self, transport):
2716
# hand off the request to the smart server
2717
client_medium = transport.get_smart_medium()
2718
except errors.NoSmartMedium:
2719
# TODO: lookup the local format from a server hint.
2720
local_dir_format = BzrDirMetaFormat1()
2721
return local_dir_format.initialize_on_transport(transport)
2722
client = _SmartClient(client_medium)
2723
path = client.remote_path_from_transport(transport)
2725
response = client.call('BzrDirFormat.initialize', path)
2726
except errors.ErrorFromSmartServer, err:
2727
remote._translate_error(err, path=path)
2728
if response[0] != 'ok':
2729
raise errors.SmartProtocolError('unexpected response code %s' % (response,))
2730
format = RemoteBzrDirFormat()
2731
self._supply_sub_formats_to(format)
2732
return remote.RemoteBzrDir(transport, format)
2734
def parse_NoneTrueFalse(self, arg):
2741
raise AssertionError("invalid arg %r" % arg)
2743
def _serialize_NoneTrueFalse(self, arg):
2750
def _serialize_NoneString(self, arg):
2753
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
2754
create_prefix=False, force_new_repo=False, stacked_on=None,
2755
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
2758
# hand off the request to the smart server
2759
client_medium = transport.get_smart_medium()
2760
except errors.NoSmartMedium:
2763
# Decline to open it if the server doesn't support our required
2764
# version (3) so that the VFS-based transport will do it.
2765
if client_medium.should_probe():
2767
server_version = client_medium.protocol_version()
2768
if server_version != '2':
2772
except errors.SmartProtocolError:
2773
# Apparently there's no usable smart server there, even though
2774
# the medium supports the smart protocol.
2779
client = _SmartClient(client_medium)
2780
path = client.remote_path_from_transport(transport)
2781
if client_medium._is_remote_before((1, 16)):
2784
# TODO: lookup the local format from a server hint.
2785
local_dir_format = BzrDirMetaFormat1()
2786
self._supply_sub_formats_to(local_dir_format)
2787
return local_dir_format.initialize_on_transport_ex(transport,
2788
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2789
force_new_repo=force_new_repo, stacked_on=stacked_on,
2790
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2791
make_working_trees=make_working_trees, shared_repo=shared_repo,
2793
return self._initialize_on_transport_ex_rpc(client, path, transport,
2794
use_existing_dir, create_prefix, force_new_repo, stacked_on,
2795
stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
2797
def _initialize_on_transport_ex_rpc(self, client, path, transport,
2798
use_existing_dir, create_prefix, force_new_repo, stacked_on,
2799
stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
2801
args.append(self._serialize_NoneTrueFalse(use_existing_dir))
2802
args.append(self._serialize_NoneTrueFalse(create_prefix))
2803
args.append(self._serialize_NoneTrueFalse(force_new_repo))
2804
args.append(self._serialize_NoneString(stacked_on))
2805
# stack_on_pwd is often/usually our transport
2808
stack_on_pwd = transport.relpath(stack_on_pwd)
2809
if not stack_on_pwd:
2811
except errors.PathNotChild:
2813
args.append(self._serialize_NoneString(stack_on_pwd))
2814
args.append(self._serialize_NoneString(repo_format_name))
2815
args.append(self._serialize_NoneTrueFalse(make_working_trees))
2816
args.append(self._serialize_NoneTrueFalse(shared_repo))
2817
request_network_name = self._network_name or \
2818
BzrDirFormat.get_default_format().network_name()
2820
response = client.call('BzrDirFormat.initialize_ex_1.16',
2821
request_network_name, path, *args)
2822
except errors.UnknownSmartMethod:
2823
client._medium._remember_remote_is_before((1,16))
2824
local_dir_format = BzrDirMetaFormat1()
2825
self._supply_sub_formats_to(local_dir_format)
2826
return local_dir_format.initialize_on_transport_ex(transport,
2827
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2828
force_new_repo=force_new_repo, stacked_on=stacked_on,
2829
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2830
make_working_trees=make_working_trees, shared_repo=shared_repo,
2832
except errors.ErrorFromSmartServer, err:
2833
remote._translate_error(err, path=path)
2834
repo_path = response[0]
2835
bzrdir_name = response[6]
2836
require_stacking = response[7]
2837
require_stacking = self.parse_NoneTrueFalse(require_stacking)
2838
format = RemoteBzrDirFormat()
2839
format._network_name = bzrdir_name
2840
self._supply_sub_formats_to(format)
2841
bzrdir = remote.RemoteBzrDir(transport, format, _client=client)
2843
repo_format = remote.response_tuple_to_repo_format(response[1:])
2844
if repo_path == '.':
2847
repo_bzrdir_format = RemoteBzrDirFormat()
2848
repo_bzrdir_format._network_name = response[5]
2849
repo_bzr = remote.RemoteBzrDir(transport.clone(repo_path),
2853
final_stack = response[8] or None
2854
final_stack_pwd = response[9] or None
2856
final_stack_pwd = urlutils.join(
2857
transport.base, final_stack_pwd)
2858
remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
2859
if len(response) > 10:
2860
# Updated server verb that locks remotely.
2861
repo_lock_token = response[10] or None
2862
remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
2864
remote_repo.dont_leave_lock_in_place()
2866
remote_repo.lock_write()
2867
policy = UseExistingRepository(remote_repo, final_stack,
2868
final_stack_pwd, require_stacking)
2869
policy.acquire_repository()
2873
bzrdir._format.set_branch_format(self.get_branch_format())
2874
if require_stacking:
2875
# The repo has already been created, but we need to make sure that
2876
# we'll make a stackable branch.
2877
bzrdir._format.require_stacking(_skip_repo=True)
2878
return remote_repo, bzrdir, require_stacking, policy
2880
def _open(self, transport):
2881
return remote.RemoteBzrDir(transport, self)
2883
def __eq__(self, other):
2884
if not isinstance(other, RemoteBzrDirFormat):
2886
return self.get_format_description() == other.get_format_description()
2888
def __return_repository_format(self):
2889
# Always return a RemoteRepositoryFormat object, but if a specific bzr
2890
# repository format has been asked for, tell the RemoteRepositoryFormat
2891
# that it should use that for init() etc.
2892
result = remote.RemoteRepositoryFormat()
2893
custom_format = getattr(self, '_repository_format', None)
2895
if isinstance(custom_format, remote.RemoteRepositoryFormat):
2896
return custom_format
2898
# We will use the custom format to create repositories over the
2899
# wire; expose its details like rich_root_data for code to
2901
result._custom_format = custom_format
2904
def get_branch_format(self):
2905
result = BzrDirMetaFormat1.get_branch_format(self)
2906
if not isinstance(result, remote.RemoteBranchFormat):
2907
new_result = remote.RemoteBranchFormat()
2908
new_result._custom_format = result
2910
self.set_branch_format(new_result)
2914
repository_format = property(__return_repository_format,
2915
BzrDirMetaFormat1._set_repository_format) #.im_func)
2918
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
2921
class RepositoryAcquisitionPolicy(object):
2922
"""Abstract base class for repository acquisition policies.
2924
A repository acquisition policy decides how a BzrDir acquires a repository
2925
for a branch that is being created. The most basic policy decision is
2926
whether to create a new repository or use an existing one.
2928
def __init__(self, stack_on, stack_on_pwd, require_stacking):
2931
:param stack_on: A location to stack on
2932
:param stack_on_pwd: If stack_on is relative, the location it is
2934
:param require_stacking: If True, it is a failure to not stack.
2936
self._stack_on = stack_on
2937
self._stack_on_pwd = stack_on_pwd
2938
self._require_stacking = require_stacking
2940
def configure_branch(self, branch):
2941
"""Apply any configuration data from this policy to the branch.
2943
Default implementation sets repository stacking.
2945
if self._stack_on is None:
2947
if self._stack_on_pwd is None:
2948
stack_on = self._stack_on
2951
stack_on = urlutils.rebase_url(self._stack_on,
2954
except errors.InvalidRebaseURLs:
2955
stack_on = self._get_full_stack_on()
2957
branch.set_stacked_on_url(stack_on)
2958
except (errors.UnstackableBranchFormat,
2959
errors.UnstackableRepositoryFormat):
2960
if self._require_stacking:
2963
def requires_stacking(self):
2964
"""Return True if this policy requires stacking."""
2965
return self._stack_on is not None and self._require_stacking
2967
def _get_full_stack_on(self):
2968
"""Get a fully-qualified URL for the stack_on location."""
2969
if self._stack_on is None:
2971
if self._stack_on_pwd is None:
2972
return self._stack_on
2974
return urlutils.join(self._stack_on_pwd, self._stack_on)
2976
def _add_fallback(self, repository, possible_transports=None):
2977
"""Add a fallback to the supplied repository, if stacking is set."""
2978
stack_on = self._get_full_stack_on()
2979
if stack_on is None:
2982
stacked_dir = BzrDir.open(stack_on,
2983
possible_transports=possible_transports)
2984
except errors.JailBreak:
2985
# We keep the stacking details, but we are in the server code so
2986
# actually stacking is not needed.
2989
stacked_repo = stacked_dir.open_branch().repository
2990
except errors.NotBranchError:
2991
stacked_repo = stacked_dir.open_repository()
2993
repository.add_fallback_repository(stacked_repo)
2994
except errors.UnstackableRepositoryFormat:
2995
if self._require_stacking:
2998
self._require_stacking = True
3000
def acquire_repository(self, make_working_trees=None, shared=False):
3001
"""Acquire a repository for this bzrdir.
3003
Implementations may create a new repository or use a pre-exising
3005
:param make_working_trees: If creating a repository, set
3006
make_working_trees to this value (if non-None)
3007
:param shared: If creating a repository, make it shared if True
3008
:return: A repository, is_new_flag (True if the repository was
3011
raise NotImplemented(RepositoryAcquisitionPolicy.acquire_repository)
3014
class CreateRepository(RepositoryAcquisitionPolicy):
3015
"""A policy of creating a new repository"""
3017
def __init__(self, bzrdir, stack_on=None, stack_on_pwd=None,
3018
require_stacking=False):
3021
:param bzrdir: The bzrdir to create the repository on.
3022
:param stack_on: A location to stack on
3023
:param stack_on_pwd: If stack_on is relative, the location it is
3026
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
3028
self._bzrdir = bzrdir
3030
def acquire_repository(self, make_working_trees=None, shared=False):
3031
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
3033
Creates the desired repository in the bzrdir we already have.
3035
stack_on = self._get_full_stack_on()
3037
format = self._bzrdir._format
3038
format.require_stacking(stack_on=stack_on,
3039
possible_transports=[self._bzrdir.root_transport])
3040
if not self._require_stacking:
3041
# We have picked up automatic stacking somewhere.
3042
note('Using default stacking branch %s at %s', self._stack_on,
3044
repository = self._bzrdir.create_repository(shared=shared)
3045
self._add_fallback(repository,
3046
possible_transports=[self._bzrdir.transport])
3047
if make_working_trees is not None:
3048
repository.set_make_working_trees(make_working_trees)
3049
return repository, True
3052
class UseExistingRepository(RepositoryAcquisitionPolicy):
3053
"""A policy of reusing an existing repository"""
3055
def __init__(self, repository, stack_on=None, stack_on_pwd=None,
3056
require_stacking=False):
3059
:param repository: The repository to use.
3060
:param stack_on: A location to stack on
3061
:param stack_on_pwd: If stack_on is relative, the location it is
3064
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
3066
self._repository = repository
3068
def acquire_repository(self, make_working_trees=None, shared=False):
3069
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
3071
Returns an existing repository to use.
3073
self._add_fallback(self._repository,
3074
possible_transports=[self._repository.bzrdir.transport])
3075
return self._repository, False
3078
def register_metadir(registry, key,
3079
repository_format, help, native=True, deprecated=False,
3085
"""Register a metadir subformat.
3087
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
3088
by the Repository/Branch/WorkingTreeformats.
3090
:param repository_format: The fully-qualified repository format class
3092
:param branch_format: Fully-qualified branch format class name as
3094
:param tree_format: Fully-qualified tree format class name as
3097
# This should be expanded to support setting WorkingTree and Branch
3098
# formats, once BzrDirMetaFormat1 supports that.
3099
def _load(full_name):
3100
mod_name, factory_name = full_name.rsplit('.', 1)
3102
factory = pyutils.get_named_object(mod_name, factory_name)
3103
except ImportError, e:
3104
raise ImportError('failed to load %s: %s' % (full_name, e))
3105
except AttributeError:
3106
raise AttributeError('no factory %s in module %r'
3107
% (full_name, sys.modules[mod_name]))
3111
bd = BzrDirMetaFormat1()
3112
if branch_format is not None:
3113
bd.set_branch_format(_load(branch_format))
3114
if tree_format is not None:
3115
bd.workingtree_format = _load(tree_format)
3116
if repository_format is not None:
3117
bd.repository_format = _load(repository_format)
3119
registry.register(key, helper, help, native, deprecated, hidden,
3120
experimental, alias)
3122
# The pre-0.8 formats have their repository format network name registered in
3123
# repository.py. MetaDir formats have their repository format network name
3124
# inferred from their disk format string.
3125
controldir.format_registry.register('weave', BzrDirFormat6,
3126
'Pre-0.8 format. Slower than knit and does not'
3127
' support checkouts or shared repositories.',
3130
register_metadir(controldir.format_registry, 'metaweave',
3131
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3132
'Transitional format in 0.8. Slower than knit.',
3133
branch_format='bzrlib.branch.BzrBranchFormat5',
3134
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3137
register_metadir(controldir.format_registry, 'knit',
3138
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3139
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
3140
branch_format='bzrlib.branch.BzrBranchFormat5',
3141
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3144
register_metadir(controldir.format_registry, 'dirstate',
3145
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3146
help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
3147
'above when accessed over the network.',
3148
branch_format='bzrlib.branch.BzrBranchFormat5',
3149
# this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
3150
# directly from workingtree_4 triggers a circular import.
3151
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3154
register_metadir(controldir.format_registry, 'dirstate-tags',
3155
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3156
help='New in 0.15: Fast local operations and improved scaling for '
3157
'network operations. Additionally adds support for tags.'
3158
' Incompatible with bzr < 0.15.',
3159
branch_format='bzrlib.branch.BzrBranchFormat6',
3160
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3163
register_metadir(controldir.format_registry, 'rich-root',
3164
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
3165
help='New in 1.0. Better handling of tree roots. Incompatible with'
3167
branch_format='bzrlib.branch.BzrBranchFormat6',
3168
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3171
register_metadir(controldir.format_registry, 'dirstate-with-subtree',
3172
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
3173
help='New in 0.15: Fast local operations and improved scaling for '
3174
'network operations. Additionally adds support for versioning nested '
3175
'bzr branches. Incompatible with bzr < 0.15.',
3176
branch_format='bzrlib.branch.BzrBranchFormat6',
3177
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3181
register_metadir(controldir.format_registry, 'pack-0.92',
3182
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
3183
help='New in 0.92: Pack-based format with data compatible with '
3184
'dirstate-tags format repositories. Interoperates with '
3185
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3187
branch_format='bzrlib.branch.BzrBranchFormat6',
3188
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3190
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
3191
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
3192
help='New in 0.92: Pack-based format with data compatible with '
3193
'dirstate-with-subtree format repositories. Interoperates with '
3194
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3196
branch_format='bzrlib.branch.BzrBranchFormat6',
3197
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3201
register_metadir(controldir.format_registry, 'rich-root-pack',
3202
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3203
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
3204
'(needed for bzr-svn and bzr-git).',
3205
branch_format='bzrlib.branch.BzrBranchFormat6',
3206
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3209
register_metadir(controldir.format_registry, '1.6',
3210
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3211
help='A format that allows a branch to indicate that there is another '
3212
'(stacked) repository that should be used to access data that is '
3213
'not present locally.',
3214
branch_format='bzrlib.branch.BzrBranchFormat7',
3215
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3218
register_metadir(controldir.format_registry, '1.6.1-rich-root',
3219
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3220
help='A variant of 1.6 that supports rich-root data '
3221
'(needed for bzr-svn and bzr-git).',
3222
branch_format='bzrlib.branch.BzrBranchFormat7',
3223
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3226
register_metadir(controldir.format_registry, '1.9',
3227
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3228
help='A repository format using B+tree indexes. These indexes '
3229
'are smaller in size, have smarter caching and provide faster '
3230
'performance for most operations.',
3231
branch_format='bzrlib.branch.BzrBranchFormat7',
3232
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3235
register_metadir(controldir.format_registry, '1.9-rich-root',
3236
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3237
help='A variant of 1.9 that supports rich-root data '
3238
'(needed for bzr-svn and bzr-git).',
3239
branch_format='bzrlib.branch.BzrBranchFormat7',
3240
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3243
register_metadir(controldir.format_registry, '1.14',
3244
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3245
help='A working-tree format that supports content filtering.',
3246
branch_format='bzrlib.branch.BzrBranchFormat7',
3247
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3249
register_metadir(controldir.format_registry, '1.14-rich-root',
3250
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3251
help='A variant of 1.14 that supports rich-root data '
3252
'(needed for bzr-svn and bzr-git).',
3253
branch_format='bzrlib.branch.BzrBranchFormat7',
3254
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3256
# The following un-numbered 'development' formats should always just be aliases.
3257
register_metadir(controldir.format_registry, 'development-rich-root',
3258
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3259
help='Current development format. Supports rich roots. Can convert data '
3260
'to and from rich-root-pack (and anything compatible with '
3261
'rich-root-pack) format repositories. Repositories and branches in '
3262
'this format can only be read by bzr.dev. Please read '
3263
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3265
branch_format='bzrlib.branch.BzrBranchFormat7',
3266
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3271
register_metadir(controldir.format_registry, 'development5-subtree',
3272
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3273
help='Development format, subtree variant. Can convert data to and '
3274
'from pack-0.92-subtree (and anything compatible with '
3275
'pack-0.92-subtree) format repositories. Repositories and branches in '
3276
'this format can only be read by bzr.dev. Please read '
3277
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3279
branch_format='bzrlib.branch.BzrBranchFormat7',
3280
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3287
register_metadir(controldir.format_registry, 'development-subtree',
3288
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2aSubtree',
3289
help='Current development format, subtree variant. Can convert data to and '
3290
'from pack-0.92-subtree (and anything compatible with '
3291
'pack-0.92-subtree) format repositories. Repositories and branches in '
3292
'this format can only be read by bzr.dev. Please read '
3293
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3295
branch_format='bzrlib.branch.BzrBranchFormat7',
3296
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3299
alias=False, # Restore to being an alias when an actual development subtree format is added
3300
# This current non-alias status is simply because we did not introduce a
3301
# chk based subtree format.
3304
# And the development formats above will have aliased one of the following:
3305
register_metadir(controldir.format_registry, 'development6-rich-root',
3306
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3307
help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3309
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3311
branch_format='bzrlib.branch.BzrBranchFormat7',
3312
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3317
register_metadir(controldir.format_registry, 'development7-rich-root',
3318
'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
3319
help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
3320
'rich roots. Please read '
3321
'http://doc.bazaar.canonical.com/latest/developers/development-repo.html '
3323
branch_format='bzrlib.branch.BzrBranchFormat7',
3324
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3329
register_metadir(controldir.format_registry, '2a',
3330
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3331
help='First format for bzr 2.0 series.\n'
3332
'Uses group-compress storage.\n'
3333
'Provides rich roots which are a one-way transition.\n',
3334
# 'storage in packs, 255-way hashed CHK inventory, bencode revision, group compress, '
3335
# 'rich roots. Supported by bzr 1.16 and later.',
3336
branch_format='bzrlib.branch.BzrBranchFormat7',
3337
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3341
# The following format should be an alias for the rich root equivalent
3342
# of the default format
3343
register_metadir(controldir.format_registry, 'default-rich-root',
3344
'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3345
branch_format='bzrlib.branch.BzrBranchFormat7',
3346
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3351
# The current format that is made on 'bzr init'.
3352
format_name = config.GlobalConfig().get_user_option('default_format')
3353
if format_name is None:
3354
controldir.format_registry.set_default('2a')
3356
controldir.format_registry.set_default(format_name)
3358
# XXX 2010-08-20 JRV: There is still a lot of code relying on
3359
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc
3360
# get changed to ControlDir.create/ControlDir.open/etc this should be removed.
3361
format_registry = controldir.format_registry