84
129
"""Return true if this bzrdir is one whose format we can convert from."""
132
def check_conversion_target(self, target_format):
133
"""Check that a bzrdir as a whole can be converted to a new format."""
134
# The only current restriction is that the repository content can be
135
# fetched compatibly with the target.
136
target_repo_format = target_format.repository_format
138
self.open_repository()._format.check_conversion_target(
140
except errors.NoRepositoryPresent:
141
# No repo, no problem.
88
def _check_supported(format, allow_unsupported):
89
"""Check whether format is a supported format.
91
If allow_unsupported is True, this is a no-op.
145
def _check_supported(format, allow_unsupported,
146
recommend_upgrade=True,
148
"""Give an error or warning on old formats.
150
:param format: may be any kind of format - workingtree, branch,
153
:param allow_unsupported: If true, allow opening
154
formats that are strongly deprecated, and which may
155
have limited functionality.
157
:param recommend_upgrade: If true (default), warn
158
the user through the ui object that they may wish
159
to upgrade the object.
161
# TODO: perhaps move this into a base Format class; it's not BzrDir
162
# specific. mbp 20070323
93
163
if not allow_unsupported and not format.is_supported():
94
164
# see open_downlevel to open legacy branches.
95
raise errors.UnsupportedFormatError(
96
'sorry, format %s not supported' % format,
97
['use a different bzr version',
98
'or remove the .bzr directory'
99
' and "bzr init" again'])
165
raise errors.UnsupportedFormatError(format=format)
166
if recommend_upgrade \
167
and getattr(format, 'upgrade_recommended', False):
168
ui.ui_factory.recommend_upgrade(
169
format.get_format_description(),
101
def clone(self, url, revision_id=None, basis=None, force_new_repo=False):
172
def clone(self, url, revision_id=None, force_new_repo=False,
173
preserve_stacking=False):
102
174
"""Clone this bzrdir and its contents to url verbatim.
104
If urls last component does not exist, it will be created.
106
if revision_id is not None, then the clone operation may tune
107
itself to download less data.
108
:param force_new_repo: Do not use a shared repository for the target
109
even if one is available.
112
basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
113
result = self._format.initialize(url)
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
180
itself to download less data.
181
:param force_new_repo: Do not use a shared repository for the target
182
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
return self.clone_on_transport(get_transport(url),
187
revision_id=revision_id,
188
force_new_repo=force_new_repo,
189
preserve_stacking=preserve_stacking)
191
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):
194
"""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
200
itself to download less data.
201
:param force_new_repo: Do not use a shared repository for the target,
202
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:
115
219
local_repo = self.find_repository()
116
220
except errors.NoRepositoryPresent:
117
221
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,
119
# may need to copy content in
121
result_repo = local_repo.clone(
123
revision_id=revision_id,
125
result_repo.set_make_working_trees(local_repo.make_working_trees())
128
result_repo = result.find_repository()
129
# fetch content this dir needs.
131
# XXX FIXME RBC 20060214 need tests for this when the basis
133
result_repo.fetch(basis_repo, revision_id=revision_id)
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)
134
271
result_repo.fetch(local_repo, revision_id=revision_id)
135
except errors.NoRepositoryPresent:
136
# needed to make one anyway.
137
result_repo = local_repo.clone(
139
revision_id=revision_id,
141
result_repo.set_make_working_trees(local_repo.make_working_trees())
275
if result_repo is not None:
276
raise AssertionError('result_repo not None(%r)' % result_repo)
142
277
# 1 if there is a branch present
143
278
# make sure its content is available in the target repository
146
self.open_branch().clone(result, revision_id=revision_id)
147
except errors.NotBranchError:
150
self.open_workingtree().clone(result, basis=basis_tree)
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)
151
289
except (errors.NoWorkingTree, errors.NotLocalUrl):
155
def _get_basis_components(self, basis):
156
"""Retrieve the basis components that are available at basis."""
158
return None, None, None
160
basis_tree = basis.open_workingtree()
161
basis_branch = basis_tree.branch
162
basis_repo = basis_branch.repository
163
except (errors.NoWorkingTree, errors.NotLocalUrl):
166
basis_branch = basis.open_branch()
167
basis_repo = basis_branch.repository
168
except errors.NotBranchError:
171
basis_repo = basis.open_repository()
172
except errors.NoRepositoryPresent:
174
return basis_repo, basis_branch, basis_tree
293
# TODO: This should be given a Transport, and should chdir up; otherwise
294
# this will open a new connection.
176
295
def _make_tail(self, url):
177
segments = url.split('/')
178
if segments and segments[-1] not in ('', '.'):
179
parent = '/'.join(segments[:-1])
180
t = bzrlib.transport.get_transport(parent)
182
t.mkdir(segments[-1])
183
except errors.FileExists:
296
t = get_transport(url)
187
def create(cls, base):
300
def create(cls, base, format=None, possible_transports=None):
188
301
"""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().
303
:param format: If supplied, the format of branch to create. If not
304
supplied, the default is used.
305
:param possible_transports: If supplied, a list of transports that
306
can be reused to share a remote connection.
196
308
if cls is not BzrDir:
197
raise AssertionError("BzrDir.create always creates the default format, "
198
"not one of %r" % cls)
199
segments = base.split('/')
200
if segments and segments[-1] not in ('', '.'):
201
parent = '/'.join(segments[:-1])
202
t = bzrlib.transport.get_transport(parent)
204
t.mkdir(segments[-1])
205
except errors.FileExists:
207
return BzrDirFormat.get_default_format().initialize(safe_unicode(base))
309
raise AssertionError("BzrDir.create always creates the default"
310
" format, not one of %r" % cls)
311
t = get_transport(base, possible_transports)
314
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)
209
394
def create_branch(self):
210
395
"""Create a branch in this BzrDir.
212
The bzrdirs format will control what branch format is created.
397
The bzrdir's format will control what branch format is created.
213
398
For more control see BranchFormatXX.create(a_bzrdir).
215
400
raise NotImplementedError(self.create_branch)
402
def destroy_branch(self):
403
"""Destroy the branch in this BzrDir"""
404
raise NotImplementedError(self.destroy_branch)
218
def create_branch_and_repo(base, force_new_repo=False):
407
def create_branch_and_repo(base, force_new_repo=False, format=None):
219
408
"""Create a new BzrDir, Branch and Repository at the url 'base'.
221
This will use the current default BzrDirFormat, and use whatever
410
This will use the current default BzrDirFormat unless one is
411
specified, and use whatever
222
412
repository format that that uses via bzrdir.create_branch and
223
413
create_repository. If a shared repository is available that is used
259
510
The created Branch object is returned.
260
511
If a working tree cannot be made due to base not being a file:// url,
261
no error is raised unless force_new_tree is True, in which case no
512
no error is raised unless force_new_tree is True, in which case no
262
513
data is created on disk and NotLocalUrl is raised.
264
515
:param base: The URL to create the branch at.
265
516
:param force_new_repo: If True a new repository is always created.
266
:param force_new_tree: If True or False force creation of a tree or
517
:param force_new_tree: If True or False force creation of a tree or
267
518
prevent such creation respectively.
268
:param format: Override for the for the bzrdir format to create
519
:param format: Override for the bzrdir format to create.
520
:param possible_transports: An optional reusable transports list.
270
522
if force_new_tree:
271
523
# check for non local urls
272
t = get_transport(safe_unicode(base))
273
if not isinstance(t, LocalTransport):
524
t = get_transport(base, possible_transports)
525
if not isinstance(t, local.LocalTransport):
274
526
raise errors.NotLocalUrl(base)
276
bzrdir = BzrDir.create(base)
278
bzrdir = format.initialize(base)
527
bzrdir = BzrDir.create(base, format, possible_transports)
279
528
repo = bzrdir._find_or_create_repository(force_new_repo)
280
529
result = bzrdir.create_branch()
281
if force_new_tree or (repo.make_working_trees() and
530
if force_new_tree or (repo.make_working_trees() and
282
531
force_new_tree is None):
284
533
bzrdir.create_workingtree()
285
534
except errors.NotLocalUrl:
290
def create_repository(base, shared=False):
291
"""Create a new BzrDir and Repository at the url 'base'.
293
This will use the current default BzrDirFormat, and use whatever
294
repository format that that uses for bzrdirformat.create_repository.
296
;param shared: Create a shared repository rather than a standalone
298
The Repository object is returned.
300
This must be overridden as an instance method in child classes, where
301
it should take no parameters and construct whatever repository format
302
that child class desires.
304
bzrdir = BzrDir.create(base)
305
return bzrdir.create_repository()
308
def create_standalone_workingtree(base):
539
def create_standalone_workingtree(base, format=None):
309
540
"""Create a new BzrDir, WorkingTree, Branch and Repository at 'base'.
311
542
'base' must be a local path or a file:// url.
313
This will use the current default BzrDirFormat, and use whatever
544
This will use the current default BzrDirFormat unless one is
545
specified, and use whatever
314
546
repository format that that uses for bzrdirformat.create_workingtree,
315
547
create_branch and create_repository.
317
The WorkingTree object is returned.
549
:param format: Override for the bzrdir format to create.
550
:return: The WorkingTree object.
319
t = get_transport(safe_unicode(base))
320
if not isinstance(t, LocalTransport):
552
t = get_transport(base)
553
if not isinstance(t, local.LocalTransport):
321
554
raise errors.NotLocalUrl(base)
322
bzrdir = BzrDir.create_branch_and_repo(safe_unicode(base),
323
force_new_repo=True).bzrdir
555
bzrdir = BzrDir.create_branch_and_repo(base,
557
format=format).bzrdir
324
558
return bzrdir.create_workingtree()
326
def create_workingtree(self, revision_id=None):
560
def create_workingtree(self, revision_id=None, from_branch=None,
561
accelerator_tree=None, hardlink=False):
327
562
"""Create a working tree at this BzrDir.
329
revision_id: create it as of this revision id.
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.
331
571
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):
595
"""Permanently disable the bzrdir.
597
This is done by renaming it to give the user some ability to recover
598
if there was a problem.
600
This will have horrible consequences if anyone has anything locked or
602
:param limit: number of times to retry
607
to_path = '.bzr.retired.%d' % i
608
self.root_transport.rename('.bzr', to_path)
609
note("renamed %s to %s"
610
% (self.root_transport.abspath('.bzr'), to_path))
612
except (errors.TransportError, IOError, errors.PathError):
619
def destroy_workingtree(self):
620
"""Destroy the working tree at this BzrDir.
622
Formats that do not support this may raise UnsupportedOperation.
624
raise NotImplementedError(self.destroy_workingtree)
626
def destroy_workingtree_metadata(self):
627
"""Destroy the control files for the working tree at this BzrDir.
629
The contents of working tree files are not affected.
630
Formats that do not support this may raise UnsupportedOperation.
632
raise NotImplementedError(self.destroy_workingtree_metadata)
634
def _find_containing(self, evaluate):
635
"""Find something in a containing control directory.
637
This method will scan containing control dirs, until it finds what
638
it is looking for, decides that it will never find it, or runs out
639
of containing control directories to check.
641
It is used to implement find_repository and
642
determine_repository_policy.
644
:param evaluate: A function returning (value, stop). If stop is True,
645
the value will be returned.
649
result, stop = evaluate(found_bzrdir)
652
next_transport = found_bzrdir.root_transport.clone('..')
653
if (found_bzrdir.root_transport.base == next_transport.base):
654
# top of the file system
656
# find the next containing bzrdir
658
found_bzrdir = BzrDir.open_containing_from_transport(
660
except errors.NotBranchError:
333
663
def find_repository(self):
334
"""Find the repository that should be used for a_bzrdir.
664
"""Find the repository that should be used.
336
666
This does not require a branch as we use it to find the repo for
337
667
new branches as well as to hook existing branches up to their
341
return self.open_repository()
342
except errors.NoRepositoryPresent:
344
next_transport = self.root_transport.clone('..')
347
found_bzrdir = BzrDir.open_containing_from_transport(
349
except errors.NotBranchError:
350
raise errors.NoRepositoryPresent(self)
670
def usable_repository(found_bzrdir):
671
# does it have a repository ?
352
673
repository = found_bzrdir.open_repository()
353
674
except errors.NoRepositoryPresent:
354
next_transport = found_bzrdir.root_transport.clone('..')
356
if ((found_bzrdir.root_transport.base ==
357
self.root_transport.base) or repository.is_shared()):
676
if found_bzrdir.root_transport.base == self.root_transport.base:
677
return repository, True
678
elif repository.is_shared():
679
return repository, True
360
raise errors.NoRepositoryPresent(self)
361
raise errors.NoRepositoryPresent(self)
683
found_repo = self._find_containing(usable_repository)
684
if found_repo is None:
685
raise errors.NoRepositoryPresent(self)
688
def get_branch_reference(self):
689
"""Return the referenced URL for the branch in this bzrdir.
691
:raises NotBranchError: If there is no Branch.
692
:return: The URL the branch in this bzrdir references if it is a
693
reference branch, or None for regular branches.
363
697
def get_branch_transport(self, branch_format):
364
698
"""Get the transport for use by branch format in this BzrDir.
366
700
Note that bzr dirs that do not support format strings will raise
367
701
IncompatibleFormat if the branch format they are given has
368
a format string, and vice verca.
702
a format string, and vice versa.
370
If branch_format is None, the transport is returned with no
371
checking. if it is not None, then the returned transport is
704
If branch_format is None, the transport is returned with no
705
checking. If it is not None, then the returned transport is
372
706
guaranteed to point to an existing directory ready for use.
374
708
raise NotImplementedError(self.get_branch_transport)
710
def _find_creation_modes(self):
711
"""Determine the appropriate modes for files and directories.
713
They're always set to be consistent with the base directory,
714
assuming that this transport allows setting modes.
716
# TODO: Do we need or want an option (maybe a config setting) to turn
717
# this off or override it for particular locations? -- mbp 20080512
718
if self._mode_check_done:
720
self._mode_check_done = True
722
st = self.transport.stat('.')
723
except errors.TransportNotPossible:
724
self._dir_mode = None
725
self._file_mode = None
727
# Check the directory mode, but also make sure the created
728
# directories and files are read-write for this user. This is
729
# mostly a workaround for filesystems which lie about being able to
730
# write to a directory (cygwin & win32)
731
if (st.st_mode & 07777 == 00000):
732
# FTP allows stat but does not return dir/file modes
733
self._dir_mode = None
734
self._file_mode = None
736
self._dir_mode = (st.st_mode & 07777) | 00700
737
# Remove the sticky and execute bits for files
738
self._file_mode = self._dir_mode & ~07111
740
def _get_file_mode(self):
741
"""Return Unix mode for newly created files, or None.
743
if not self._mode_check_done:
744
self._find_creation_modes()
745
return self._file_mode
747
def _get_dir_mode(self):
748
"""Return Unix mode for newly created directories, or None.
750
if not self._mode_check_done:
751
self._find_creation_modes()
752
return self._dir_mode
376
754
def get_repository_transport(self, repository_format):
377
755
"""Get the transport for use by repository format in this BzrDir.
379
757
Note that bzr dirs that do not support format strings will raise
380
758
IncompatibleFormat if the repository format they are given has
381
a format string, and vice verca.
759
a format string, and vice versa.
383
If repository_format is None, the transport is returned with no
384
checking. if it is not None, then the returned transport is
761
If repository_format is None, the transport is returned with no
762
checking. If it is not None, then the returned transport is
385
763
guaranteed to point to an existing directory ready for use.
387
765
raise NotImplementedError(self.get_repository_transport)
389
767
def get_workingtree_transport(self, tree_format):
390
768
"""Get the transport for use by workingtree format in this BzrDir.
392
770
Note that bzr dirs that do not support format strings will raise
393
IncompatibleFormat if the workingtree format they are given has
394
a format string, and vice verca.
771
IncompatibleFormat if the workingtree format they are given has a
772
format string, and vice versa.
396
If workingtree_format is None, the transport is returned with no
397
checking. if it is not None, then the returned transport is
774
If workingtree_format is None, the transport is returned with no
775
checking. If it is not None, then the returned transport is
398
776
guaranteed to point to an existing directory ready for use.
400
778
raise NotImplementedError(self.get_workingtree_transport)
780
def get_config(self):
781
"""Get configuration for this BzrDir."""
782
return config.BzrDirConfig(self)
784
def _get_config(self):
785
"""By default, no configuration is available."""
402
788
def __init__(self, _transport, _format):
403
789
"""Initialize a Bzr control dir object.
405
791
Only really common logic should reside here, concrete classes should be
406
792
made with varying behaviours.
427
833
def open_unsupported(base):
428
834
"""Open a branch which is not supported."""
429
835
return BzrDir.open(base, _unsupported=True)
432
def open(base, _unsupported=False):
433
"""Open an existing bzrdir, rooted at 'base' (url)
435
_unsupported is a private parameter to the BzrDir class.
437
t = get_transport(base)
438
mutter("trying to open %r with transport %r", base, t)
439
format = BzrDirFormat.find_format(t)
838
def open(base, _unsupported=False, possible_transports=None):
839
"""Open an existing bzrdir, rooted at 'base' (url).
841
:param _unsupported: a private parameter to the BzrDir class.
843
t = get_transport(base, possible_transports=possible_transports)
844
return BzrDir.open_from_transport(t, _unsupported=_unsupported)
847
def open_from_transport(transport, _unsupported=False,
848
_server_formats=True):
849
"""Open a bzrdir within a particular directory.
851
:param transport: Transport containing the bzrdir.
852
:param _unsupported: private.
854
for hook in BzrDir.hooks['pre_open']:
856
# Keep initial base since 'transport' may be modified while following
858
base = transport.base
859
def find_format(transport):
860
return transport, BzrDirFormat.find_format(
861
transport, _server_formats=_server_formats)
863
def redirected(transport, e, redirection_notice):
864
redirected_transport = transport._redirected_to(e.source, e.target)
865
if redirected_transport is None:
866
raise errors.NotBranchError(base)
867
note('%s is%s redirected to %s',
868
transport.base, e.permanently, redirected_transport.base)
869
return redirected_transport
872
transport, format = do_catching_redirections(find_format,
875
except errors.TooManyRedirections:
876
raise errors.NotBranchError(base)
440
878
BzrDir._check_supported(format, _unsupported)
441
return format.open(t, _found=True)
879
return format.open(transport, _found=True)
443
def open_branch(self, unsupported=False):
881
def open_branch(self, unsupported=False, ignore_fallbacks=False):
444
882
"""Open the branch object at this BzrDir if one is present.
446
884
If unsupported is True, then no longer supported branch formats can
449
887
TODO: static convenience version of this?
451
889
raise NotImplementedError(self.open_branch)
454
def open_containing(url):
892
def open_containing(url, possible_transports=None):
455
893
"""Open an existing branch which contains url.
457
895
:param url: url to search from.
458
896
See open_containing_from_transport for more detail.
460
return BzrDir.open_containing_from_transport(get_transport(url))
898
transport = get_transport(url, possible_transports)
899
return BzrDir.open_containing_from_transport(transport)
463
902
def open_containing_from_transport(a_transport):
464
"""Open an existing branch which contains a_transport.base
903
"""Open an existing branch which contains a_transport.base.
466
905
This probes for a branch at a_transport, and searches upwards from there.
468
907
Basically we keep looking up until we find the control directory or
469
908
run into the root. If there isn't one, raises NotBranchError.
470
If there is one and it is either an unrecognised format or an unsupported
909
If there is one and it is either an unrecognised format or an unsupported
471
910
format, UnknownFormatError or UnsupportedFormatError are raised.
472
911
If there is one, it is returned, along with the unused portion of url.
913
:return: The BzrDir that contains the path, and a Unicode path
914
for the rest of the URL.
474
916
# this gets the normalised url back. I.e. '.' -> the full path.
475
917
url = a_transport.base
478
format = BzrDirFormat.find_format(a_transport)
479
BzrDir._check_supported(format, False)
480
return format.open(a_transport), a_transport.relpath(url)
920
result = BzrDir.open_from_transport(a_transport)
921
return result, urlutils.unescape(a_transport.relpath(url))
481
922
except errors.NotBranchError, e:
482
mutter('not a branch in: %r %s', a_transport.base, e)
483
new_t = a_transport.clone('..')
925
new_t = a_transport.clone('..')
926
except errors.InvalidURLJoin:
927
# reached the root, whatever that may be
928
raise errors.NotBranchError(path=url)
484
929
if new_t.base == a_transport.base:
485
930
# reached the root, whatever that may be
486
931
raise errors.NotBranchError(path=url)
487
932
a_transport = new_t
934
def _get_tree_branch(self):
935
"""Return the branch and tree, if any, for this bzrdir.
937
Return None for tree if not present or inaccessible.
938
Raise NotBranchError if no branch is present.
939
:return: (tree, branch)
942
tree = self.open_workingtree()
943
except (errors.NoWorkingTree, errors.NotLocalUrl):
945
branch = self.open_branch()
951
def open_tree_or_branch(klass, location):
952
"""Return the branch and working tree at a location.
954
If there is no tree at the location, tree will be None.
955
If there is no branch at the location, an exception will be
957
:return: (tree, branch)
959
bzrdir = klass.open(location)
960
return bzrdir._get_tree_branch()
963
def open_containing_tree_or_branch(klass, location):
964
"""Return the branch and working tree contained by a location.
966
Returns (tree, branch, relpath).
967
If there is no tree at containing the location, tree will be None.
968
If there is no branch containing the location, an exception will be
970
relpath is the portion of the path that is contained by the branch.
972
bzrdir, relpath = klass.open_containing(location)
973
tree, branch = bzrdir._get_tree_branch()
974
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
489
1001
def open_repository(self, _unsupported=False):
490
1002
"""Open the repository object at this BzrDir if one is present.
492
This will not follow the Branch object pointer - its strictly a direct
1004
This will not follow the Branch object pointer - it's strictly a direct
493
1005
open facility. Most client code should use open_branch().repository to
494
1006
get at a repository.
496
_unsupported is a private parameter, not part of the api.
1008
:param _unsupported: a private parameter, not part of the api.
497
1009
TODO: static convenience version of this?
499
1011
raise NotImplementedError(self.open_repository)
501
def open_workingtree(self, _unsupported=False):
1013
def open_workingtree(self, _unsupported=False,
1014
recommend_upgrade=True, from_branch=None):
502
1015
"""Open the workingtree object at this BzrDir if one is present.
504
TODO: static convenience version of this?
1017
:param recommend_upgrade: Optional keyword parameter, when True (the
1018
default), emit through the ui module a recommendation that the user
1019
upgrade the working tree when the workingtree being opened is old
1020
(but still fully supported).
1021
:param from_branch: override bzrdir branch (for lightweight checkouts)
506
1023
raise NotImplementedError(self.open_workingtree)
508
1025
def has_branch(self):
509
1026
"""Tell if this bzrdir contains a branch.
511
1028
Note: if you're going to open the branch, you should just go ahead
512
and try, and not ask permission first. (This method just opens the
513
branch and discards it, and that's somewhat expensive.)
1029
and try, and not ask permission first. (This method just opens the
1030
branch and discards it, and that's somewhat expensive.)
516
1033
self.open_branch()
548
1134
if revision_id is not None, then the clone operation may tune
549
1135
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.
552
result = self._format.initialize(url)
553
basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
555
source_branch = self.open_branch()
1147
target_transport = get_transport(url, possible_transports)
1148
target_transport.ensure_base()
1149
cloning_format = self.cloning_metadir(stacked)
1150
# Create/update the result branch
1151
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
556
1158
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:
1183
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()
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,
1205
if wt.path2id('') is None:
1207
wt.set_root_id(self.open_workingtree.get_root_id())
1208
except errors.NoWorkingTree:
1214
if recurse == 'down':
1216
basis = wt.basis_tree()
1218
subtrees = basis.iter_references()
1219
elif result_branch is not None:
1220
basis = result_branch.basis_tree()
1222
subtrees = basis.iter_references()
1223
elif source_branch is not None:
1224
basis = source_branch.basis_tree()
1226
subtrees = basis.iter_references()
1231
for path, file_id in subtrees:
1232
target = urlutils.join(url, urlutils.escape(path))
1233
sublocation = source_branch.reference_parent(file_id, path)
1234
sublocation.bzrdir.sprout(target,
1235
basis.get_reference_revision(file_id, path),
1236
force_new_repo=force_new_repo, recurse=recurse,
1239
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()
557
1251
except errors.NotBranchError:
560
source_repository = self.open_repository()
561
except errors.NoRepositoryPresent:
562
# copy the entire basis one if there is one
563
# but there is no repository.
564
source_repository = basis_repo
569
result_repo = result.find_repository()
570
except errors.NoRepositoryPresent:
572
if source_repository is None and result_repo is not None:
574
elif source_repository is None and result_repo is None:
575
# no repo available, make a new one
576
result.create_repository()
577
elif source_repository is not None and result_repo is None:
578
# have source, and want to make a new target repo
579
# we dont clone the repo because that preserves attributes
580
# like is_shared(), and we have not yet implemented a
581
# repository sprout().
582
result_repo = result.create_repository()
583
if result_repo is not None:
584
# fetch needed content into target.
586
# XXX FIXME RBC 20060214 need tests for this when the basis
588
result_repo.fetch(basis_repo, revision_id=revision_id)
589
result_repo.fetch(source_repository, revision_id=revision_id)
590
if source_branch is not None:
591
source_branch.sprout(result, revision_id=revision_id)
593
result.create_branch()
594
if result_repo is None or result_repo.make_working_trees():
595
result.create_workingtree()
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()
599
1318
class BzrDirPreSplitOut(BzrDir):
947
1856
This returns a bzrlib.bzrdir.Converter object.
949
1858
This should return the best upgrader to step this format towards the
950
current default format. In the case of plugins we can/shouold provide
1859
current default format. In the case of plugins we can/should provide
951
1860
some means for them to extend the range of returnable converters.
953
:param format: Optional format to override the default foramt of the
1862
:param format: Optional format to override the default format of the
956
1865
raise NotImplementedError(self.get_converter)
958
def initialize(self, url):
1867
def initialize(self, url, possible_transports=None):
959
1868
"""Create a bzr control dir at this url and return an opened copy.
1870
While not deprecated, this method is very specific and its use will
1871
lead to many round trips to setup a working environment. See
1872
initialize_on_transport_ex for a [nearly] all-in-one method.
961
1874
Subclasses should typically override initialize_on_transport
962
1875
instead of this method.
964
return self.initialize_on_transport(get_transport(url))
1877
return self.initialize_on_transport(get_transport(url,
1878
possible_transports))
966
1880
def initialize_on_transport(self, transport):
967
1881
"""Initialize a new bzrdir in the base directory of a Transport."""
968
# Since we don'transport have a .bzr directory, inherit the
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
969
2002
# mode from the root directory
970
temp_control = LockableFiles(transport, '', TransportLock)
2003
temp_control = lockable_files.LockableFiles(transport,
2004
'', lockable_files.TransportLock)
971
2005
temp_control._transport.mkdir('.bzr',
972
# FIXME: RBC 20060121 dont peek under
2006
# FIXME: RBC 20060121 don't peek under
974
2008
mode=temp_control._dir_mode)
2009
if sys.platform == 'win32' and isinstance(transport, local.LocalTransport):
2010
win32utils.set_file_attr_hidden(transport._abspath('.bzr'))
975
2011
file_mode = temp_control._file_mode
976
2012
del temp_control
977
mutter('created control directory in ' + transport.base)
978
control = transport.clone('.bzr')
979
utf8_files = [('README',
980
"This is a Bazaar-NG control directory.\n"
981
"Do not change any files in this directory.\n"),
2013
bzrdir_transport = transport.clone('.bzr')
2014
utf8_files = [('README',
2015
"This is a Bazaar control directory.\n"
2016
"Do not change any files in this directory.\n"
2017
"See http://bazaar-vcs.org/ for more information about Bazaar.\n"),
982
2018
('branch-format', self.get_format_string()),
984
2020
# NB: no need to escape relative paths that are url safe.
985
control_files = LockableFiles(control, self._lock_file_name,
2021
control_files = lockable_files.LockableFiles(bzrdir_transport,
2022
self._lock_file_name, self._lock_class)
987
2023
control_files.create_lock()
988
2024
control_files.lock_write()
990
for file, content in utf8_files:
991
control_files.put_utf8(file, content)
2026
for (filename, content) in utf8_files:
2027
bzrdir_transport.put_bytes(filename, content,
993
2030
control_files.unlock()
994
2031
return self.open(transport, _found=True)
1788
3052
if not isinstance(repo._format, self.target_format.repository_format.__class__):
1789
3053
from bzrlib.repository import CopyConverter
1790
self.pb.note('starting repository conversion')
3054
ui.ui_factory.note('starting repository conversion')
1791
3055
converter = CopyConverter(self.target_format.repository_format)
1792
3056
converter.convert(repo, pb)
3058
branch = self.bzrdir.open_branch()
3059
except errors.NotBranchError:
3062
# TODO: conversions of Branch and Tree should be done by
3063
# InterXFormat lookups/some sort of registry.
3064
# Avoid circular imports
3065
from bzrlib import branch as _mod_branch
3066
old = branch._format.__class__
3067
new = self.target_format.get_branch_format().__class__
3069
if (old == _mod_branch.BzrBranchFormat5 and
3070
new in (_mod_branch.BzrBranchFormat6,
3071
_mod_branch.BzrBranchFormat7,
3072
_mod_branch.BzrBranchFormat8)):
3073
branch_converter = _mod_branch.Converter5to6()
3074
elif (old == _mod_branch.BzrBranchFormat6 and
3075
new in (_mod_branch.BzrBranchFormat7,
3076
_mod_branch.BzrBranchFormat8)):
3077
branch_converter = _mod_branch.Converter6to7()
3078
elif (old == _mod_branch.BzrBranchFormat7 and
3079
new is _mod_branch.BzrBranchFormat8):
3080
branch_converter = _mod_branch.Converter7to8()
3082
raise errors.BadConversionTarget("No converter", new,
3084
branch_converter.convert(branch)
3085
branch = self.bzrdir.open_branch()
3086
old = branch._format.__class__
3088
tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
3089
except (errors.NoWorkingTree, errors.NotLocalUrl):
3092
# TODO: conversions of Branch and Tree should be done by
3093
# InterXFormat lookups
3094
if (isinstance(tree, workingtree.WorkingTree3) and
3095
not isinstance(tree, workingtree_4.DirStateWorkingTree) and
3096
isinstance(self.target_format.workingtree_format,
3097
workingtree_4.DirStateWorkingTreeFormat)):
3098
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)
1793
3110
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.
3115
# we can make it a lazy object if the control formats is turned into something
3117
class RemoteBzrDirFormat(BzrDirMetaFormat1):
3118
"""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
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
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
def probe_transport(klass, transport):
3149
"""Return a RemoteBzrDirFormat object if it looks possible."""
3151
medium = transport.get_smart_medium()
3152
except (NotImplementedError, AttributeError,
3153
errors.TransportNotPossible, errors.NoSmartMedium,
3154
errors.SmartProtocolError):
3155
# no smart server, so not a branch for this format type.
3156
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)
3171
def initialize_on_transport(self, transport):
3173
# hand off the request to the smart server
3174
client_medium = transport.get_smart_medium()
3175
except errors.NoSmartMedium:
3176
# TODO: lookup the local format from a server hint.
3177
local_dir_format = BzrDirMetaFormat1()
3178
return local_dir_format.initialize_on_transport(transport)
3179
client = _SmartClient(client_medium)
3180
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
3337
def _open(self, transport):
3338
return remote.RemoteBzrDir(transport, self)
3340
def __eq__(self, other):
3341
if not isinstance(other, RemoteBzrDirFormat):
3343
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
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
3378
class BzrDirFormatInfo(object):
3380
def __init__(self, native, deprecated, hidden, experimental):
3381
self.deprecated = deprecated
3382
self.native = native
3383
self.hidden = hidden
3384
self.experimental = experimental
3387
class BzrDirFormatRegistry(registry.Registry):
3388
"""Registry of user-selectable BzrDir subformats.
3390
Differs from BzrDirFormat._control_formats in that it provides sub-formats,
3391
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
def register_metadir(self, key,
3405
repository_format, help, native=True, deprecated=False,
3411
"""Register a metadir subformat.
3413
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
3414
by the Repository/Branch/WorkingTreeformats.
3416
:param repository_format: The fully-qualified repository format class
3418
:param branch_format: Fully-qualified branch format class name as
3420
:param tree_format: Fully-qualified tree format class name as
3423
# This should be expanded to support setting WorkingTree and Branch
3424
# formats, once BzrDirMetaFormat1 supports that.
3425
def _load(full_name):
3426
mod_name, factory_name = full_name.rsplit('.', 1)
3428
mod = __import__(mod_name, globals(), locals(),
3430
except ImportError, e:
3431
raise ImportError('failed to load %s: %s' % (full_name, e))
3433
factory = getattr(mod, factory_name)
3434
except AttributeError:
3435
raise AttributeError('no factory %s in module %r'
3440
bd = BzrDirMetaFormat1()
3441
if branch_format is not None:
3442
bd.set_branch_format(_load(branch_format))
3443
if tree_format is not None:
3444
bd.workingtree_format = _load(tree_format)
3445
if repository_format is not None:
3446
bd.repository_format = _load(repository_format)
3448
self.register(key, helper, help, native, deprecated, hidden,
3449
experimental, alias)
3451
def register(self, key, factory, help, native=True, deprecated=False,
3452
hidden=False, experimental=False, alias=False):
3453
"""Register a BzrDirFormat factory.
3455
The factory must be a callable that takes one parameter: the key.
3456
It must produce an instance of the BzrDirFormat when called.
3458
This function mainly exists to prevent the info object from being
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)
3467
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)
3475
def set_default(self, key):
3476
"""Set the 'default' key to be a clone of the supplied key.
3478
This method must be called once and only once.
3480
registry.Registry.register(self, 'default', self.get(key),
3481
self.get_help(key), info=self.get_info(key))
3482
self._aliases.add('default')
3484
def set_default_repository(self, key):
3485
"""Set the FormatRegistry default and Repository default.
3487
This is a transitional method while Repository.set_default_format
3490
if 'default' in self:
3491
self.remove('default')
3492
self.set_default(key)
3493
format = self.get('default')()
3495
def make_bzrdir(self, key):
3496
return self.get(key)()
3498
def help_topic(self, topic):
3500
default_realkey = None
3501
default_help = self.get_help('default')
3503
for key in self._registration_order:
3504
if key == 'default':
3506
help = self.get_help(key)
3507
if help == default_help:
3508
default_realkey = key
3510
help_pairs.append((key, help))
3512
def wrapped(key, help, info):
3514
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'))
3522
deprecated_pairs = []
3523
experimental_pairs = []
3524
for key, help in help_pairs:
3525
info = self.get_info(key)
3528
elif info.deprecated:
3529
deprecated_pairs.append((key, help))
3530
elif info.experimental:
3531
experimental_pairs.append((key, help))
3533
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
if len(deprecated_pairs) > 0:
3545
other_output += "\nDeprecated formats are shown below.\n\n"
3546
for key, help in deprecated_pairs:
3547
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
3721
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
format_registry.register('weave', BzrDirFormat6,
3726
'Pre-0.8 format. Slower than knit and does not'
3727
' support checkouts or shared repositories.',
3730
format_registry.register_metadir('metaweave',
3731
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3732
'Transitional format in 0.8. Slower than knit.',
3733
branch_format='bzrlib.branch.BzrBranchFormat5',
3734
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',
3744
format_registry.register_metadir('dirstate',
3745
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3746
help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
3747
'above when accessed over the network.',
3748
branch_format='bzrlib.branch.BzrBranchFormat5',
3749
# this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
3750
# directly from workingtree_4 triggers a circular import.
3751
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3754
format_registry.register_metadir('dirstate-tags',
3755
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3756
help='New in 0.15: Fast local operations and improved scaling for '
3757
'network operations. Additionally adds support for tags.'
3758
' Incompatible with bzr < 0.15.',
3759
branch_format='bzrlib.branch.BzrBranchFormat6',
3760
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3763
format_registry.register_metadir('rich-root',
3764
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
3765
help='New in 1.0. Better handling of tree roots. Incompatible with'
3767
branch_format='bzrlib.branch.BzrBranchFormat6',
3768
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3771
format_registry.register_metadir('dirstate-with-subtree',
3772
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
3773
help='New in 0.15: Fast local operations and improved scaling for '
3774
'network operations. Additionally adds support for versioning nested '
3775
'bzr branches. Incompatible with bzr < 0.15.',
3776
branch_format='bzrlib.branch.BzrBranchFormat6',
3777
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')