125
86
"""Return true if this bzrdir is one whose format we can convert from."""
128
def check_conversion_target(self, target_format):
129
target_repo_format = target_format.repository_format
130
source_repo_format = self._format.repository_format
131
source_repo_format.check_conversion_target(target_repo_format)
134
def _check_supported(format, allow_unsupported,
135
recommend_upgrade=True,
137
"""Give an error or warning on old formats.
139
:param format: may be any kind of format - workingtree, branch,
142
:param allow_unsupported: If true, allow opening
143
formats that are strongly deprecated, and which may
144
have limited functionality.
146
:param recommend_upgrade: If true (default), warn
147
the user through the ui object that they may wish
148
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.
150
# TODO: perhaps move this into a base Format class; it's not BzrDir
151
# specific. mbp 20070323
152
95
if not allow_unsupported and not format.is_supported():
153
96
# see open_downlevel to open legacy branches.
154
97
raise errors.UnsupportedFormatError(format=format)
155
if recommend_upgrade \
156
and getattr(format, 'upgrade_recommended', False):
157
ui.ui_factory.recommend_upgrade(
158
format.get_format_description(),
161
def clone(self, url, revision_id=None, force_new_repo=False,
162
preserve_stacking=False):
99
def clone(self, url, revision_id=None, basis=None, force_new_repo=False):
163
100
"""Clone this bzrdir and its contents to url verbatim.
165
:param url: The url create the clone at. If url's last component does
166
not exist, it will be created.
167
:param revision_id: The tip revision-id to use for any branch or
168
working tree. If not None, then the clone operation may tune
169
itself to download less data.
170
:param force_new_repo: Do not use a shared repository for the target
171
even if one is available.
172
:param preserve_stacking: When cloning a stacked branch, stack the
173
new branch on top of the other branch's stacked-on branch.
175
return self.clone_on_transport(get_transport(url),
176
revision_id=revision_id,
177
force_new_repo=force_new_repo,
178
preserve_stacking=preserve_stacking)
180
def clone_on_transport(self, transport, revision_id=None,
181
force_new_repo=False, preserve_stacking=False,
183
"""Clone this bzrdir and its contents to transport verbatim.
185
:param transport: The transport for the location to produce the clone
186
at. If the target directory does not exist, it will be created.
187
:param revision_id: The tip revision-id to use for any branch or
188
working tree. If not None, then the clone operation may tune
189
itself to download less data.
190
:param force_new_repo: Do not use a shared repository for the target,
191
even if one is available.
192
:param preserve_stacking: When cloning a stacked branch, stack the
193
new branch on top of the other branch's stacked-on branch.
195
transport.ensure_base()
196
require_stacking = (stacked_on is not None)
197
format = self.cloning_metadir(require_stacking)
198
# Bug: We create a metadir without knowing if it can support stacking,
199
# we should look up the policy needs first.
200
result = format.initialize_on_transport(transport)
201
repository_policy = None
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
105
itself to download less data.
106
:param force_new_repo: Do not use a shared repository for the target
107
even if one is available.
110
basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
111
result = self._format.initialize(url)
203
113
local_repo = self.find_repository()
204
114
except errors.NoRepositoryPresent:
205
115
local_repo = None
207
local_branch = self.open_branch()
208
except errors.NotBranchError:
211
# enable fallbacks when branch is not a branch reference
212
if local_branch.repository.has_same_location(local_repo):
213
local_repo = local_branch.repository
214
if preserve_stacking:
216
stacked_on = local_branch.get_stacked_on_url()
217
except (errors.UnstackableBranchFormat,
218
errors.UnstackableRepositoryFormat,
223
117
# may need to copy content in
224
repository_policy = result.determine_repository_policy(
225
force_new_repo, stacked_on, self.root_transport.base,
226
require_stacking=require_stacking)
227
make_working_trees = local_repo.make_working_trees()
228
result_repo, is_new_repo = repository_policy.acquire_repository(
229
make_working_trees, local_repo.is_shared())
230
if not require_stacking and repository_policy._require_stacking:
231
require_stacking = True
232
result._format.require_stacking()
233
if is_new_repo and not require_stacking and revision_id is not None:
234
fetch_spec = graph.PendingAncestryResult(
235
[revision_id], local_repo)
236
result_repo.fetch(local_repo, fetch_spec=fetch_spec)
119
result_repo = local_repo.clone(
121
revision_id=revision_id,
123
result_repo.set_make_working_trees(local_repo.make_working_trees())
238
result_repo.fetch(local_repo, revision_id=revision_id)
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)
132
result_repo.fetch(local_repo, revision_id=revision_id)
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())
241
140
# 1 if there is a branch present
242
141
# make sure its content is available in the target repository
244
if local_branch is not None:
245
result_branch = local_branch.clone(result, revision_id=revision_id,
246
repository_policy=repository_policy)
248
# Cheaper to check if the target is not local, than to try making
250
result.root_transport.local_abspath('.')
251
if result_repo is None or result_repo.make_working_trees():
252
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)
253
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
257
174
# TODO: This should be given a Transport, and should chdir up; otherwise
258
175
# this will open a new connection.
259
176
def _make_tail(self, url):
260
t = get_transport(url)
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
264
def create(cls, base, format=None, possible_transports=None):
187
def create(cls, base):
265
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.
267
:param format: If supplied, the format of branch to create. If not
268
supplied, the default is used.
269
:param possible_transports: If supplied, a list of transports that
270
can be reused to share a remote connection.
193
If you need a specific format, consider creating an instance
194
of that and calling initialize().
272
196
if cls is not BzrDir:
273
raise AssertionError("BzrDir.create always creates the default"
274
" format, not one of %r" % cls)
275
t = get_transport(base, possible_transports)
278
format = BzrDirFormat.get_default_format()
279
return format.initialize_on_transport(t)
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:
312
recurse, value = evaluate(bzrdir)
315
subdirs = list_current(current_transport)
316
except errors.NoSuchFile:
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, (None, repository)
341
branch = bzrdir.open_branch()
342
except errors.NotBranchError:
343
return True, (None, None)
345
return True, (branch, None)
347
for branch, repo in BzrDir.find_bzrdirs(transport, evaluate=evaluate):
349
branches.extend(repo.find_branches())
350
if branch is not None:
351
branches.append(branch)
354
def destroy_repository(self):
355
"""Destroy the repository in this BzrDir"""
356
raise NotImplementedError(self.destroy_repository)
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))
358
208
def create_branch(self):
359
209
"""Create a branch in this BzrDir.
361
The bzrdir's format will control what branch format is created.
211
The bzrdirs format will control what branch format is created.
362
212
For more control see BranchFormatXX.create(a_bzrdir).
364
214
raise NotImplementedError(self.create_branch)
366
def destroy_branch(self):
367
"""Destroy the branch in this BzrDir"""
368
raise NotImplementedError(self.destroy_branch)
371
def create_branch_and_repo(base, force_new_repo=False, format=None):
217
def create_branch_and_repo(base, force_new_repo=False):
372
218
"""Create a new BzrDir, Branch and Repository at the url 'base'.
374
This will use the current default BzrDirFormat unless one is
375
specified, and use whatever
220
This will use the current default BzrDirFormat, and use whatever
376
221
repository format that that uses via bzrdir.create_branch and
377
222
create_repository. If a shared repository is available that is used
475
258
The created Branch object is returned.
476
259
If a working tree cannot be made due to base not being a file:// url,
477
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
478
261
data is created on disk and NotLocalUrl is raised.
480
263
:param base: The URL to create the branch at.
481
264
:param force_new_repo: If True a new repository is always created.
482
: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
483
266
prevent such creation respectively.
484
:param format: Override for the bzrdir format to create.
485
:param possible_transports: An optional reusable transports list.
267
:param format: Override for the for the bzrdir format to create
487
269
if force_new_tree:
488
270
# check for non local urls
489
t = get_transport(base, possible_transports)
490
if not isinstance(t, local.LocalTransport):
271
t = get_transport(safe_unicode(base))
272
if not isinstance(t, LocalTransport):
491
273
raise errors.NotLocalUrl(base)
492
bzrdir = BzrDir.create(base, format, possible_transports)
275
bzrdir = BzrDir.create(base)
277
bzrdir = format.initialize(base)
493
278
repo = bzrdir._find_or_create_repository(force_new_repo)
494
279
result = bzrdir.create_branch()
495
if force_new_tree or (repo.make_working_trees() and
280
if force_new_tree or (repo.make_working_trees() and
496
281
force_new_tree is None):
498
283
bzrdir.create_workingtree()
499
284
except errors.NotLocalUrl:
504
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):
505
308
"""Create a new BzrDir, WorkingTree, Branch and Repository at 'base'.
507
310
'base' must be a local path or a file:// url.
509
This will use the current default BzrDirFormat unless one is
510
specified, and use whatever
312
This will use the current default BzrDirFormat, and use whatever
511
313
repository format that that uses for bzrdirformat.create_workingtree,
512
314
create_branch and create_repository.
514
:param format: Override for the bzrdir format to create.
515
:return: The WorkingTree object.
316
The WorkingTree object is returned.
517
t = get_transport(base)
518
if not isinstance(t, local.LocalTransport):
318
t = get_transport(safe_unicode(base))
319
if not isinstance(t, LocalTransport):
519
320
raise errors.NotLocalUrl(base)
520
bzrdir = BzrDir.create_branch_and_repo(base,
522
format=format).bzrdir
321
bzrdir = BzrDir.create_branch_and_repo(safe_unicode(base),
322
force_new_repo=True).bzrdir
523
323
return bzrdir.create_workingtree()
525
def create_workingtree(self, revision_id=None, from_branch=None,
526
accelerator_tree=None, hardlink=False):
325
def create_workingtree(self, revision_id=None):
527
326
"""Create a working tree at this BzrDir.
529
:param revision_id: create it as of this revision id.
530
:param from_branch: override bzrdir branch (for lightweight checkouts)
531
:param accelerator_tree: A tree which can be used for retrieving file
532
contents more quickly than the revision tree, i.e. a workingtree.
533
The revision tree will be used for cases where accelerator_tree's
534
content is different.
328
revision_id: create it as of this revision id.
536
330
raise NotImplementedError(self.create_workingtree)
538
def backup_bzrdir(self):
539
"""Backup this bzr control directory.
332
def find_repository(self):
333
"""Find the repository that should be used for a_bzrdir.
541
:return: Tuple with old path name and new path name
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
543
pb = ui.ui_factory.nested_progress_bar()
545
# FIXME: bug 300001 -- the backup fails if the backup directory
546
# already exists, but it should instead either remove it or make
547
# a new backup directory.
549
# FIXME: bug 262450 -- the backup directory should have the same
550
# permissions as the .bzr directory (probably a bug in copy_tree)
551
old_path = self.root_transport.abspath('.bzr')
552
new_path = self.root_transport.abspath('backup.bzr')
553
pb.note('making backup of %s' % (old_path,))
554
pb.note(' to %s' % (new_path,))
555
self.root_transport.copy_tree('.bzr', 'backup.bzr')
556
return (old_path, new_path)
560
def retire_bzrdir(self, limit=10000):
561
"""Permanently disable the bzrdir.
563
This is done by renaming it to give the user some ability to recover
564
if there was a problem.
566
This will have horrible consequences if anyone has anything locked or
568
:param limit: number of times to retry
573
to_path = '.bzr.retired.%d' % i
574
self.root_transport.rename('.bzr', to_path)
575
note("renamed %s to %s"
576
% (self.root_transport.abspath('.bzr'), to_path))
578
except (errors.TransportError, IOError, errors.PathError):
585
def destroy_workingtree(self):
586
"""Destroy the working tree at this BzrDir.
588
Formats that do not support this may raise UnsupportedOperation.
590
raise NotImplementedError(self.destroy_workingtree)
592
def destroy_workingtree_metadata(self):
593
"""Destroy the control files for the working tree at this BzrDir.
595
The contents of working tree files are not affected.
596
Formats that do not support this may raise UnsupportedOperation.
598
raise NotImplementedError(self.destroy_workingtree_metadata)
600
def _find_containing(self, evaluate):
601
"""Find something in a containing control directory.
603
This method will scan containing control dirs, until it finds what
604
it is looking for, decides that it will never find it, or runs out
605
of containing control directories to check.
607
It is used to implement find_repository and
608
determine_repository_policy.
610
:param evaluate: A function returning (value, stop). If stop is True,
611
the value will be returned.
615
result, stop = evaluate(found_bzrdir)
618
next_transport = found_bzrdir.root_transport.clone('..')
619
if (found_bzrdir.root_transport.base == next_transport.base):
620
# top of the file system
340
return self.open_repository()
341
except errors.NoRepositoryPresent:
343
next_transport = self.root_transport.clone('..')
622
345
# find the next containing bzrdir
624
347
found_bzrdir = BzrDir.open_containing_from_transport(
625
348
next_transport)[0]
626
349
except errors.NotBranchError:
629
def find_repository(self):
630
"""Find the repository that should be used.
632
This does not require a branch as we use it to find the repo for
633
new branches as well as to hook existing branches up to their
636
def usable_repository(found_bzrdir):
351
raise errors.NoRepositoryPresent(self)
637
352
# does it have a repository ?
639
354
repository = found_bzrdir.open_repository()
640
355
except errors.NoRepositoryPresent:
642
if found_bzrdir.root_transport.base == self.root_transport.base:
643
return repository, True
644
elif repository.is_shared():
645
return repository, True
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()):
649
found_repo = self._find_containing(usable_repository)
650
if found_repo is None:
651
raise errors.NoRepositoryPresent(self)
654
def get_branch_reference(self):
655
"""Return the referenced URL for the branch in this bzrdir.
657
:raises NotBranchError: If there is no Branch.
658
:return: The URL the branch in this bzrdir references if it is a
659
reference branch, or None for regular branches.
366
raise errors.NoRepositoryPresent(self)
367
raise errors.NoRepositoryPresent(self)
663
369
def get_branch_transport(self, branch_format):
664
370
"""Get the transport for use by branch format in this BzrDir.
796
452
def open_unsupported(base):
797
453
"""Open a branch which is not supported."""
798
454
return BzrDir.open(base, _unsupported=True)
801
def open(base, _unsupported=False, possible_transports=None):
802
"""Open an existing bzrdir, rooted at 'base' (url).
804
:param _unsupported: a private parameter to the BzrDir class.
806
t = get_transport(base, possible_transports=possible_transports)
807
return BzrDir.open_from_transport(t, _unsupported=_unsupported)
810
def open_from_transport(transport, _unsupported=False,
811
_server_formats=True):
812
"""Open a bzrdir within a particular directory.
814
:param transport: Transport containing the bzrdir.
815
:param _unsupported: private.
817
for hook in BzrDir.hooks['pre_open']:
819
# Keep initial base since 'transport' may be modified while following
821
base = transport.base
822
def find_format(transport):
823
return transport, BzrDirFormat.find_format(
824
transport, _server_formats=_server_formats)
826
def redirected(transport, e, redirection_notice):
827
redirected_transport = transport._redirected_to(e.source, e.target)
828
if redirected_transport is None:
829
raise errors.NotBranchError(base)
830
note('%s is%s redirected to %s',
831
transport.base, e.permanently, redirected_transport.base)
832
return redirected_transport
835
transport, format = do_catching_redirections(find_format,
838
except errors.TooManyRedirections:
839
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)
841
465
BzrDir._check_supported(format, _unsupported)
842
return format.open(transport, _found=True)
466
return format.open(t, _found=True)
844
def open_branch(self, unsupported=False, ignore_fallbacks=False):
468
def open_branch(self, unsupported=False):
845
469
"""Open the branch object at this BzrDir if one is present.
847
471
If unsupported is True, then no longer supported branch formats can
850
474
TODO: static convenience version of this?
852
476
raise NotImplementedError(self.open_branch)
855
def open_containing(url, possible_transports=None):
479
def open_containing(url):
856
480
"""Open an existing branch which contains url.
858
482
:param url: url to search from.
859
483
See open_containing_from_transport for more detail.
861
transport = get_transport(url, possible_transports)
862
return BzrDir.open_containing_from_transport(transport)
485
return BzrDir.open_containing_from_transport(get_transport(url))
865
488
def open_containing_from_transport(a_transport):
866
"""Open an existing branch which contains a_transport.base.
489
"""Open an existing branch which contains a_transport.base
868
491
This probes for a branch at a_transport, and searches upwards from there.
870
493
Basically we keep looking up until we find the control directory or
871
494
run into the root. If there isn't one, raises NotBranchError.
872
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
873
496
format, UnknownFormatError or UnsupportedFormatError are raised.
874
497
If there is one, it is returned, along with the unused portion of url.
876
:return: The BzrDir that contains the path, and a Unicode path
499
:return: The BzrDir that contains the path, and a Unicode path
877
500
for the rest of the URL.
879
502
# this gets the normalised url back. I.e. '.' -> the full path.
880
503
url = a_transport.base
883
result = BzrDir.open_from_transport(a_transport)
884
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))
885
509
except errors.NotBranchError, e:
510
## mutter('not a branch in: %r %s', a_transport.base, e)
888
new_t = a_transport.clone('..')
889
except errors.InvalidURLJoin:
890
# reached the root, whatever that may be
891
raise errors.NotBranchError(path=url)
512
new_t = a_transport.clone('..')
892
513
if new_t.base == a_transport.base:
893
514
# reached the root, whatever that may be
894
515
raise errors.NotBranchError(path=url)
895
516
a_transport = new_t
897
def _get_tree_branch(self):
898
"""Return the branch and tree, if any, for this bzrdir.
900
Return None for tree if not present or inaccessible.
901
Raise NotBranchError if no branch is present.
902
:return: (tree, branch)
905
tree = self.open_workingtree()
906
except (errors.NoWorkingTree, errors.NotLocalUrl):
908
branch = self.open_branch()
914
def open_tree_or_branch(klass, location):
915
"""Return the branch and working tree at a location.
917
If there is no tree at the location, tree will be None.
918
If there is no branch at the location, an exception will be
920
:return: (tree, branch)
922
bzrdir = klass.open(location)
923
return bzrdir._get_tree_branch()
926
def open_containing_tree_or_branch(klass, location):
927
"""Return the branch and working tree contained by a location.
929
Returns (tree, branch, relpath).
930
If there is no tree at containing the location, tree will be None.
931
If there is no branch containing the location, an exception will be
933
relpath is the portion of the path that is contained by the branch.
935
bzrdir, relpath = klass.open_containing(location)
936
tree, branch = bzrdir._get_tree_branch()
937
return tree, branch, relpath
940
def open_containing_tree_branch_or_repository(klass, location):
941
"""Return the working tree, branch and repo contained by a location.
943
Returns (tree, branch, repository, relpath).
944
If there is no tree containing the location, tree will be None.
945
If there is no branch containing the location, branch will be None.
946
If there is no repository containing the location, repository will be
948
relpath is the portion of the path that is contained by the innermost
951
If no tree, branch or repository is found, a NotBranchError is raised.
953
bzrdir, relpath = klass.open_containing(location)
955
tree, branch = bzrdir._get_tree_branch()
956
except errors.NotBranchError:
958
repo = bzrdir.find_repository()
959
return None, None, repo, relpath
960
except (errors.NoRepositoryPresent):
961
raise errors.NotBranchError(location)
962
return tree, branch, branch.repository, relpath
964
518
def open_repository(self, _unsupported=False):
965
519
"""Open the repository object at this BzrDir if one is present.
967
This will not follow the Branch object pointer - it's strictly a direct
521
This will not follow the Branch object pointer - its strictly a direct
968
522
open facility. Most client code should use open_branch().repository to
969
523
get at a repository.
971
:param _unsupported: a private parameter, not part of the api.
525
_unsupported is a private parameter, not part of the api.
972
526
TODO: static convenience version of this?
974
528
raise NotImplementedError(self.open_repository)
976
def open_workingtree(self, _unsupported=False,
977
recommend_upgrade=True, from_branch=None):
530
def open_workingtree(self, _unsupported=False):
978
531
"""Open the workingtree object at this BzrDir if one is present.
980
:param recommend_upgrade: Optional keyword parameter, when True (the
981
default), emit through the ui module a recommendation that the user
982
upgrade the working tree when the workingtree being opened is old
983
(but still fully supported).
984
:param from_branch: override bzrdir branch (for lightweight checkouts)
533
TODO: static convenience version of this?
986
535
raise NotImplementedError(self.open_workingtree)
988
537
def has_branch(self):
989
538
"""Tell if this bzrdir contains a branch.
991
540
Note: if you're going to open the branch, you should just go ahead
992
and try, and not ask permission first. (This method just opens the
993
branch and discards it, and that's somewhat expensive.)
541
and try, and not ask permission first. (This method just opens the
542
branch and discards it, and that's somewhat expensive.)
996
545
self.open_branch()
1093
577
if revision_id is not None, then the clone operation may tune
1094
578
itself to download less data.
1095
:param accelerator_tree: A tree which can be used for retrieving file
1096
contents more quickly than the revision tree, i.e. a workingtree.
1097
The revision tree will be used for cases where accelerator_tree's
1098
content is different.
1099
:param hardlink: If true, hard-link files from accelerator_tree,
1101
:param stacked: If true, create a stacked branch referring to the
1102
location of this control directory.
1103
:param create_tree_if_local: If true, a working-tree will be created
1104
when working locally.
1106
target_transport = get_transport(url, possible_transports)
1107
target_transport.ensure_base()
1108
cloning_format = self.cloning_metadir(stacked)
1109
# Create/update the result branch
1110
result = cloning_format.initialize_on_transport(target_transport)
1111
# if a stacked branch wasn't requested, we don't create one
1112
# even if the origin was stacked
1113
stacked_branch_url = None
1114
if source_branch is not None:
1116
stacked_branch_url = self.root_transport.base
581
result = self._format.initialize(url)
582
basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
584
source_branch = self.open_branch()
1117
585
source_repository = source_branch.repository
1120
source_branch = self.open_branch()
1121
source_repository = source_branch.repository
1123
stacked_branch_url = self.root_transport.base
1124
except errors.NotBranchError:
1125
source_branch = None
1127
source_repository = self.open_repository()
1128
except errors.NoRepositoryPresent:
1129
source_repository = None
1130
repository_policy = result.determine_repository_policy(
1131
force_new_repo, stacked_branch_url, require_stacking=stacked)
1132
result_repo, is_new_repo = repository_policy.acquire_repository()
1133
if is_new_repo and revision_id is not None and not stacked:
1134
fetch_spec = graph.PendingAncestryResult(
1135
[revision_id], source_repository)
1138
if source_repository is not None:
1139
# Fetch while stacked to prevent unstacked fetch from
1141
if fetch_spec is None:
1142
result_repo.fetch(source_repository, revision_id=revision_id)
1144
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
1146
if source_branch is None:
1147
# this is for sprouting a bzrdir without a branch; is that
1149
# Not especially, but it's part of the contract.
1150
result_branch = result.create_branch()
1152
result_branch = source_branch.sprout(result,
1153
revision_id=revision_id, repository_policy=repository_policy)
1154
mutter("created new branch %r" % (result_branch,))
1156
# Create/update the result working tree
1157
if (create_tree_if_local and
1158
isinstance(target_transport, local.LocalTransport) and
1159
(result_repo is None or result_repo.make_working_trees())):
1160
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
1164
if wt.path2id('') is None:
1166
wt.set_root_id(self.open_workingtree.get_root_id())
1167
except errors.NoWorkingTree:
1173
if recurse == 'down':
1175
basis = wt.basis_tree()
1177
subtrees = basis.iter_references()
1178
elif result_branch is not None:
1179
basis = result_branch.basis_tree()
1181
subtrees = basis.iter_references()
1182
elif source_branch is not None:
1183
basis = source_branch.basis_tree()
1185
subtrees = basis.iter_references()
1190
for path, file_id in subtrees:
1191
target = urlutils.join(url, urlutils.escape(path))
1192
sublocation = source_branch.reference_parent(file_id, path)
1193
sublocation.bzrdir.sprout(target,
1194
basis.get_reference_revision(file_id, path),
1195
force_new_repo=force_new_repo, recurse=recurse,
1198
if basis is not None:
586
except errors.NotBranchError:
589
source_repository = self.open_repository()
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()
1202
def push_branch(self, source, revision_id=None, overwrite=False,
1204
"""Push the source branch into this BzrDir."""
1206
# If we can open a branch, use its direct repository, otherwise see
1207
# if there is a repository without a branch.
1209
br_to = self.open_branch()
1210
except errors.NotBranchError:
1211
# Didn't find a branch, can we find a repository?
1212
repository_to = self.find_repository()
1214
# Found a branch, so we must have found a repository
1215
repository_to = br_to.repository
1217
push_result = PushResult()
1218
push_result.source_branch = source
1220
# We have a repository but no branch, copy the revisions, and then
1222
repository_to.fetch(source.repository, revision_id=revision_id)
1223
br_to = source.clone(self, revision_id=revision_id)
1224
if source.get_push_location() is None or remember:
1225
source.set_push_location(br_to.base)
1226
push_result.stacked_on = None
1227
push_result.branch_push_result = None
1228
push_result.old_revno = None
1229
push_result.old_revid = _mod_revision.NULL_REVISION
1230
push_result.target_branch = br_to
1231
push_result.master_branch = None
1232
push_result.workingtree_updated = False
1234
# We have successfully opened the branch, remember if necessary:
1235
if source.get_push_location() is None or remember:
1236
source.set_push_location(br_to.base)
1238
tree_to = self.open_workingtree()
1239
except errors.NotLocalUrl:
1240
push_result.branch_push_result = source.push(br_to,
1241
overwrite, stop_revision=revision_id)
1242
push_result.workingtree_updated = False
1243
except errors.NoWorkingTree:
1244
push_result.branch_push_result = source.push(br_to,
1245
overwrite, stop_revision=revision_id)
1246
push_result.workingtree_updated = None # Not applicable
1248
tree_to.lock_write()
1250
push_result.branch_push_result = source.push(
1251
tree_to.branch, overwrite, stop_revision=revision_id)
1255
push_result.workingtree_updated = True
1256
push_result.old_revno = push_result.branch_push_result.old_revno
1257
push_result.old_revid = push_result.branch_push_result.old_revid
1258
push_result.target_branch = \
1259
push_result.branch_push_result.target_branch
1263
class BzrDirHooks(hooks.Hooks):
1264
"""Hooks for BzrDir operations."""
1267
"""Create the default hooks."""
1268
hooks.Hooks.__init__(self)
1269
self.create_hook(hooks.HookPoint('pre_open',
1270
"Invoked before attempting to open a BzrDir with the transport "
1271
"that the open will use.", (1, 14), None))
1273
# install the default hooks
1274
BzrDir.hooks = BzrDirHooks()
1277
630
class BzrDirPreSplitOut(BzrDir):
1278
631
"""A common class for the all-in-one formats."""
2773
1812
self.pb.note('starting repository conversion')
2774
1813
converter = CopyConverter(self.target_format.repository_format)
2775
1814
converter.convert(repo, pb)
2777
branch = self.bzrdir.open_branch()
2778
except errors.NotBranchError:
2781
# TODO: conversions of Branch and Tree should be done by
2782
# InterXFormat lookups/some sort of registry.
2783
# Avoid circular imports
2784
from bzrlib import branch as _mod_branch
2785
old = branch._format.__class__
2786
new = self.target_format.get_branch_format().__class__
2788
if (old == _mod_branch.BzrBranchFormat5 and
2789
new in (_mod_branch.BzrBranchFormat6,
2790
_mod_branch.BzrBranchFormat7)):
2791
branch_converter = _mod_branch.Converter5to6()
2792
elif (old == _mod_branch.BzrBranchFormat6 and
2793
new == _mod_branch.BzrBranchFormat7):
2794
branch_converter = _mod_branch.Converter6to7()
2796
raise errors.BadConversionTarget("No converter", new)
2797
branch_converter.convert(branch)
2798
branch = self.bzrdir.open_branch()
2799
old = branch._format.__class__
2801
tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
2802
except (errors.NoWorkingTree, errors.NotLocalUrl):
2805
# TODO: conversions of Branch and Tree should be done by
2806
# InterXFormat lookups
2807
if (isinstance(tree, workingtree.WorkingTree3) and
2808
not isinstance(tree, workingtree_4.DirStateWorkingTree) and
2809
isinstance(self.target_format.workingtree_format,
2810
workingtree_4.DirStateWorkingTreeFormat)):
2811
workingtree_4.Converter3to4().convert(tree)
2812
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
2813
not isinstance(tree, workingtree_4.WorkingTree5) and
2814
isinstance(self.target_format.workingtree_format,
2815
workingtree_4.WorkingTreeFormat5)):
2816
workingtree_4.Converter4to5().convert(tree)
2817
if (isinstance(tree, workingtree_4.DirStateWorkingTree) and
2818
not isinstance(tree, workingtree_4.WorkingTree6) and
2819
isinstance(self.target_format.workingtree_format,
2820
workingtree_4.WorkingTreeFormat6)):
2821
workingtree_4.Converter4or5to6().convert(tree)
2822
1815
return to_convert
2825
# This is not in remote.py because it's small, and needs to be registered.
2826
# Putting it in remote.py creates a circular import problem.
2827
# we can make it a lazy object if the control formats is turned into something
2829
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2830
"""Format representing bzrdirs accessed via a smart server"""
2833
BzrDirMetaFormat1.__init__(self)
2834
self._network_name = None
2836
def get_format_description(self):
2837
return 'bzr remote bzrdir'
2839
def get_format_string(self):
2840
raise NotImplementedError(self.get_format_string)
2842
def network_name(self):
2843
if self._network_name:
2844
return self._network_name
2846
raise AssertionError("No network name set.")
2849
def probe_transport(klass, transport):
2850
"""Return a RemoteBzrDirFormat object if it looks possible."""
2852
medium = transport.get_smart_medium()
2853
except (NotImplementedError, AttributeError,
2854
errors.TransportNotPossible, errors.NoSmartMedium,
2855
errors.SmartProtocolError):
2856
# no smart server, so not a branch for this format type.
2857
raise errors.NotBranchError(path=transport.base)
2859
# Decline to open it if the server doesn't support our required
2860
# version (3) so that the VFS-based transport will do it.
2861
if medium.should_probe():
2863
server_version = medium.protocol_version()
2864
except errors.SmartProtocolError:
2865
# Apparently there's no usable smart server there, even though
2866
# the medium supports the smart protocol.
2867
raise errors.NotBranchError(path=transport.base)
2868
if server_version != '2':
2869
raise errors.NotBranchError(path=transport.base)
2872
def initialize_on_transport(self, transport):
2874
# hand off the request to the smart server
2875
client_medium = transport.get_smart_medium()
2876
except errors.NoSmartMedium:
2877
# TODO: lookup the local format from a server hint.
2878
local_dir_format = BzrDirMetaFormat1()
2879
return local_dir_format.initialize_on_transport(transport)
2880
client = _SmartClient(client_medium)
2881
path = client.remote_path_from_transport(transport)
2882
response = client.call('BzrDirFormat.initialize', path)
2883
if response[0] != 'ok':
2884
raise errors.SmartProtocolError('unexpected response code %s' % (response,))
2885
format = RemoteBzrDirFormat()
2886
self._supply_sub_formats_to(format)
2887
return remote.RemoteBzrDir(transport, format)
2889
def _open(self, transport):
2890
return remote.RemoteBzrDir(transport, self)
2892
def __eq__(self, other):
2893
if not isinstance(other, RemoteBzrDirFormat):
2895
return self.get_format_description() == other.get_format_description()
2897
def __return_repository_format(self):
2898
# Always return a RemoteRepositoryFormat object, but if a specific bzr
2899
# repository format has been asked for, tell the RemoteRepositoryFormat
2900
# that it should use that for init() etc.
2901
result = remote.RemoteRepositoryFormat()
2902
custom_format = getattr(self, '_repository_format', None)
2904
if isinstance(custom_format, remote.RemoteRepositoryFormat):
2905
return custom_format
2907
# We will use the custom format to create repositories over the
2908
# wire; expose its details like rich_root_data for code to
2910
result._custom_format = custom_format
2913
def get_branch_format(self):
2914
result = BzrDirMetaFormat1.get_branch_format(self)
2915
if not isinstance(result, remote.RemoteBranchFormat):
2916
new_result = remote.RemoteBranchFormat()
2917
new_result._custom_format = result
2919
self.set_branch_format(new_result)
2923
repository_format = property(__return_repository_format,
2924
BzrDirMetaFormat1._set_repository_format) #.im_func)
2927
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
2930
class BzrDirFormatInfo(object):
2932
def __init__(self, native, deprecated, hidden, experimental):
2933
self.deprecated = deprecated
2934
self.native = native
2935
self.hidden = hidden
2936
self.experimental = experimental
2939
class BzrDirFormatRegistry(registry.Registry):
2940
"""Registry of user-selectable BzrDir subformats.
2942
Differs from BzrDirFormat._control_formats in that it provides sub-formats,
2943
e.g. BzrDirMeta1 with weave repository. Also, it's more user-oriented.
2947
"""Create a BzrDirFormatRegistry."""
2948
self._aliases = set()
2949
self._registration_order = list()
2950
super(BzrDirFormatRegistry, self).__init__()
2953
"""Return a set of the format names which are aliases."""
2954
return frozenset(self._aliases)
2956
def register_metadir(self, key,
2957
repository_format, help, native=True, deprecated=False,
2963
"""Register a metadir subformat.
2965
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
2966
by the Repository/Branch/WorkingTreeformats.
2968
:param repository_format: The fully-qualified repository format class
2970
:param branch_format: Fully-qualified branch format class name as
2972
:param tree_format: Fully-qualified tree format class name as
2975
# This should be expanded to support setting WorkingTree and Branch
2976
# formats, once BzrDirMetaFormat1 supports that.
2977
def _load(full_name):
2978
mod_name, factory_name = full_name.rsplit('.', 1)
2980
mod = __import__(mod_name, globals(), locals(),
2982
except ImportError, e:
2983
raise ImportError('failed to load %s: %s' % (full_name, e))
2985
factory = getattr(mod, factory_name)
2986
except AttributeError:
2987
raise AttributeError('no factory %s in module %r'
2992
bd = BzrDirMetaFormat1()
2993
if branch_format is not None:
2994
bd.set_branch_format(_load(branch_format))
2995
if tree_format is not None:
2996
bd.workingtree_format = _load(tree_format)
2997
if repository_format is not None:
2998
bd.repository_format = _load(repository_format)
3000
self.register(key, helper, help, native, deprecated, hidden,
3001
experimental, alias)
3003
def register(self, key, factory, help, native=True, deprecated=False,
3004
hidden=False, experimental=False, alias=False):
3005
"""Register a BzrDirFormat factory.
3007
The factory must be a callable that takes one parameter: the key.
3008
It must produce an instance of the BzrDirFormat when called.
3010
This function mainly exists to prevent the info object from being
3013
registry.Registry.register(self, key, factory, help,
3014
BzrDirFormatInfo(native, deprecated, hidden, experimental))
3016
self._aliases.add(key)
3017
self._registration_order.append(key)
3019
def register_lazy(self, key, module_name, member_name, help, native=True,
3020
deprecated=False, hidden=False, experimental=False, alias=False):
3021
registry.Registry.register_lazy(self, key, module_name, member_name,
3022
help, BzrDirFormatInfo(native, deprecated, hidden, experimental))
3024
self._aliases.add(key)
3025
self._registration_order.append(key)
3027
def set_default(self, key):
3028
"""Set the 'default' key to be a clone of the supplied key.
3030
This method must be called once and only once.
3032
registry.Registry.register(self, 'default', self.get(key),
3033
self.get_help(key), info=self.get_info(key))
3034
self._aliases.add('default')
3036
def set_default_repository(self, key):
3037
"""Set the FormatRegistry default and Repository default.
3039
This is a transitional method while Repository.set_default_format
3042
if 'default' in self:
3043
self.remove('default')
3044
self.set_default(key)
3045
format = self.get('default')()
3047
def make_bzrdir(self, key):
3048
return self.get(key)()
3050
def help_topic(self, topic):
3052
default_realkey = None
3053
default_help = self.get_help('default')
3055
for key in self._registration_order:
3056
if key == 'default':
3058
help = self.get_help(key)
3059
if help == default_help:
3060
default_realkey = key
3062
help_pairs.append((key, help))
3064
def wrapped(key, help, info):
3066
help = '(native) ' + help
3067
return ':%s:\n%s\n\n' % (key,
3068
textwrap.fill(help, initial_indent=' ',
3069
subsequent_indent=' '))
3070
if default_realkey is not None:
3071
output += wrapped(default_realkey, '(default) %s' % default_help,
3072
self.get_info('default'))
3073
deprecated_pairs = []
3074
experimental_pairs = []
3075
for key, help in help_pairs:
3076
info = self.get_info(key)
3079
elif info.deprecated:
3080
deprecated_pairs.append((key, help))
3081
elif info.experimental:
3082
experimental_pairs.append((key, help))
3084
output += wrapped(key, help, info)
3085
output += "\nSee ``bzr help formats`` for more about storage formats."
3087
if len(experimental_pairs) > 0:
3088
other_output += "Experimental formats are shown below.\n\n"
3089
for key, help in experimental_pairs:
3090
info = self.get_info(key)
3091
other_output += wrapped(key, help, info)
3094
"No experimental formats are available.\n\n"
3095
if len(deprecated_pairs) > 0:
3096
other_output += "\nDeprecated formats are shown below.\n\n"
3097
for key, help in deprecated_pairs:
3098
info = self.get_info(key)
3099
other_output += wrapped(key, help, info)
3102
"\nNo deprecated formats are available.\n\n"
3104
"\nSee ``bzr help formats`` for more about storage formats."
3106
if topic == 'other-formats':
3112
class RepositoryAcquisitionPolicy(object):
3113
"""Abstract base class for repository acquisition policies.
3115
A repository acquisition policy decides how a BzrDir acquires a repository
3116
for a branch that is being created. The most basic policy decision is
3117
whether to create a new repository or use an existing one.
3119
def __init__(self, stack_on, stack_on_pwd, require_stacking):
3122
:param stack_on: A location to stack on
3123
:param stack_on_pwd: If stack_on is relative, the location it is
3125
:param require_stacking: If True, it is a failure to not stack.
3127
self._stack_on = stack_on
3128
self._stack_on_pwd = stack_on_pwd
3129
self._require_stacking = require_stacking
3131
def configure_branch(self, branch):
3132
"""Apply any configuration data from this policy to the branch.
3134
Default implementation sets repository stacking.
3136
if self._stack_on is None:
3138
if self._stack_on_pwd is None:
3139
stack_on = self._stack_on
3142
stack_on = urlutils.rebase_url(self._stack_on,
3144
branch.bzrdir.root_transport.base)
3145
except errors.InvalidRebaseURLs:
3146
stack_on = self._get_full_stack_on()
3148
branch.set_stacked_on_url(stack_on)
3149
except (errors.UnstackableBranchFormat,
3150
errors.UnstackableRepositoryFormat):
3151
if self._require_stacking:
3154
def _get_full_stack_on(self):
3155
"""Get a fully-qualified URL for the stack_on location."""
3156
if self._stack_on is None:
3158
if self._stack_on_pwd is None:
3159
return self._stack_on
3161
return urlutils.join(self._stack_on_pwd, self._stack_on)
3163
def _add_fallback(self, repository, possible_transports=None):
3164
"""Add a fallback to the supplied repository, if stacking is set."""
3165
stack_on = self._get_full_stack_on()
3166
if stack_on is None:
3168
stacked_dir = BzrDir.open(stack_on,
3169
possible_transports=possible_transports)
3171
stacked_repo = stacked_dir.open_branch().repository
3172
except errors.NotBranchError:
3173
stacked_repo = stacked_dir.open_repository()
3175
repository.add_fallback_repository(stacked_repo)
3176
except errors.UnstackableRepositoryFormat:
3177
if self._require_stacking:
3180
self._require_stacking = True
3182
def acquire_repository(self, make_working_trees=None, shared=False):
3183
"""Acquire a repository for this bzrdir.
3185
Implementations may create a new repository or use a pre-exising
3187
:param make_working_trees: If creating a repository, set
3188
make_working_trees to this value (if non-None)
3189
:param shared: If creating a repository, make it shared if True
3190
:return: A repository, is_new_flag (True if the repository was
3193
raise NotImplemented(RepositoryAcquisitionPolicy.acquire_repository)
3196
class CreateRepository(RepositoryAcquisitionPolicy):
3197
"""A policy of creating a new repository"""
3199
def __init__(self, bzrdir, stack_on=None, stack_on_pwd=None,
3200
require_stacking=False):
3203
:param bzrdir: The bzrdir to create the repository on.
3204
:param stack_on: A location to stack on
3205
:param stack_on_pwd: If stack_on is relative, the location it is
3208
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
3210
self._bzrdir = bzrdir
3212
def acquire_repository(self, make_working_trees=None, shared=False):
3213
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
3215
Creates the desired repository in the bzrdir we already have.
3217
stack_on = self._get_full_stack_on()
3219
# Stacking is desired. requested by the target, but does the place it
3220
# points at support stacking? If it doesn't then we should
3221
# not implicitly upgrade. We check this here.
3222
format = self._bzrdir._format
3223
if not (format.repository_format.supports_external_lookups
3224
and format.get_branch_format().supports_stacking()):
3225
# May need to upgrade - but only do if the target also
3226
# supports stacking. Note that this currently wastes
3227
# network round trips to check - but we only do this
3228
# when the source can't stack so it will fade away
3229
# as people do upgrade.
3231
target_dir = BzrDir.open(stack_on,
3232
possible_transports=[self._bzrdir.root_transport])
3233
except errors.NotBranchError:
3234
# Nothing there, don't change formats
3238
target_branch = target_dir.open_branch()
3239
except errors.NotBranchError:
3240
# No branch, don't change formats
3243
branch_format = target_branch._format
3244
repo_format = target_branch.repository._format
3245
if not (branch_format.supports_stacking()
3246
and repo_format.supports_external_lookups):
3247
# Doesn't stack itself, don't force an upgrade
3250
# Does support stacking, use its format.
3251
format.repository_format = repo_format
3252
format.set_branch_format(branch_format)
3253
note('Source format does not support stacking, '
3254
'using format: \'%s\'\n %s\n',
3255
branch_format.get_format_description(),
3256
repo_format.get_format_description())
3257
if not self._require_stacking:
3258
# We have picked up automatic stacking somewhere.
3259
note('Using default stacking branch %s at %s', self._stack_on,
3261
repository = self._bzrdir.create_repository(shared=shared)
3262
self._add_fallback(repository,
3263
possible_transports=[self._bzrdir.transport])
3264
if make_working_trees is not None:
3265
repository.set_make_working_trees(make_working_trees)
3266
return repository, True
3269
class UseExistingRepository(RepositoryAcquisitionPolicy):
3270
"""A policy of reusing an existing repository"""
3272
def __init__(self, repository, stack_on=None, stack_on_pwd=None,
3273
require_stacking=False):
3276
:param repository: The repository to use.
3277
:param stack_on: A location to stack on
3278
:param stack_on_pwd: If stack_on is relative, the location it is
3281
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
3283
self._repository = repository
3285
def acquire_repository(self, make_working_trees=None, shared=False):
3286
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
3288
Returns an existing repository to use.
3290
self._add_fallback(self._repository,
3291
possible_transports=[self._repository.bzrdir.transport])
3292
return self._repository, False
3295
# Please register new formats after old formats so that formats
3296
# appear in chronological order and format descriptions can build
3298
format_registry = BzrDirFormatRegistry()
3299
# The pre-0.8 formats have their repository format network name registered in
3300
# repository.py. MetaDir formats have their repository format network name
3301
# inferred from their disk format string.
3302
format_registry.register('weave', BzrDirFormat6,
3303
'Pre-0.8 format. Slower than knit and does not'
3304
' support checkouts or shared repositories.',
3306
format_registry.register_metadir('metaweave',
3307
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3308
'Transitional format in 0.8. Slower than knit.',
3309
branch_format='bzrlib.branch.BzrBranchFormat5',
3310
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3312
format_registry.register_metadir('knit',
3313
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3314
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
3315
branch_format='bzrlib.branch.BzrBranchFormat5',
3316
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3318
format_registry.register_metadir('dirstate',
3319
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3320
help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
3321
'above when accessed over the network.',
3322
branch_format='bzrlib.branch.BzrBranchFormat5',
3323
# this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
3324
# directly from workingtree_4 triggers a circular import.
3325
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3327
format_registry.register_metadir('dirstate-tags',
3328
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3329
help='New in 0.15: Fast local operations and improved scaling for '
3330
'network operations. Additionally adds support for tags.'
3331
' Incompatible with bzr < 0.15.',
3332
branch_format='bzrlib.branch.BzrBranchFormat6',
3333
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3335
format_registry.register_metadir('rich-root',
3336
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
3337
help='New in 1.0. Better handling of tree roots. Incompatible with'
3339
branch_format='bzrlib.branch.BzrBranchFormat6',
3340
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3342
format_registry.register_metadir('dirstate-with-subtree',
3343
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
3344
help='New in 0.15: Fast local operations and improved scaling for '
3345
'network operations. Additionally adds support for versioning nested '
3346
'bzr branches. Incompatible with bzr < 0.15.',
3347
branch_format='bzrlib.branch.BzrBranchFormat6',
3348
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3352
format_registry.register_metadir('pack-0.92',
3353
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
3354
help='New in 0.92: Pack-based format with data compatible with '
3355
'dirstate-tags format repositories. Interoperates with '
3356
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3357
'Previously called knitpack-experimental. '
3358
'For more information, see '
3359
'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
3360
branch_format='bzrlib.branch.BzrBranchFormat6',
3361
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3363
format_registry.register_metadir('pack-0.92-subtree',
3364
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
3365
help='New in 0.92: Pack-based format with data compatible with '
3366
'dirstate-with-subtree format repositories. Interoperates with '
3367
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3368
'Previously called knitpack-experimental. '
3369
'For more information, see '
3370
'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
3371
branch_format='bzrlib.branch.BzrBranchFormat6',
3372
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3376
format_registry.register_metadir('rich-root-pack',
3377
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3378
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
3379
'(needed for bzr-svn and bzr-git).',
3380
branch_format='bzrlib.branch.BzrBranchFormat6',
3381
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3383
format_registry.register_metadir('1.6',
3384
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3385
help='A format that allows a branch to indicate that there is another '
3386
'(stacked) repository that should be used to access data that is '
3387
'not present locally.',
3388
branch_format='bzrlib.branch.BzrBranchFormat7',
3389
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3391
format_registry.register_metadir('1.6.1-rich-root',
3392
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3393
help='A variant of 1.6 that supports rich-root data '
3394
'(needed for bzr-svn and bzr-git).',
3395
branch_format='bzrlib.branch.BzrBranchFormat7',
3396
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3398
format_registry.register_metadir('1.9',
3399
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3400
help='A repository format using B+tree indexes. These indexes '
3401
'are smaller in size, have smarter caching and provide faster '
3402
'performance for most operations.',
3403
branch_format='bzrlib.branch.BzrBranchFormat7',
3404
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3406
format_registry.register_metadir('1.9-rich-root',
3407
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3408
help='A variant of 1.9 that supports rich-root data '
3409
'(needed for bzr-svn and bzr-git).',
3410
branch_format='bzrlib.branch.BzrBranchFormat7',
3411
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3413
format_registry.register_metadir('1.14',
3414
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3415
help='A working-tree format that supports content filtering.',
3416
branch_format='bzrlib.branch.BzrBranchFormat7',
3417
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3419
format_registry.register_metadir('1.14-rich-root',
3420
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3421
help='A variant of 1.14 that supports rich-root data '
3422
'(needed for bzr-svn and bzr-git).',
3423
branch_format='bzrlib.branch.BzrBranchFormat7',
3424
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3426
# The following two formats should always just be aliases.
3427
format_registry.register_metadir('development',
3428
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2',
3429
help='Current development format. Can convert data to and from pack-0.92 '
3430
'(and anything compatible with pack-0.92) format repositories. '
3431
'Repositories and branches in this format can only be read by bzr.dev. '
3433
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3435
branch_format='bzrlib.branch.BzrBranchFormat7',
3436
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3440
format_registry.register_metadir('development-subtree',
3441
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3442
help='Current development format, subtree variant. Can convert data to and '
3443
'from pack-0.92-subtree (and anything compatible with '
3444
'pack-0.92-subtree) format repositories. Repositories and branches in '
3445
'this format can only be read by bzr.dev. Please read '
3446
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3448
branch_format='bzrlib.branch.BzrBranchFormat7',
3449
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3453
# And the development formats above will have aliased one of the following:
3454
format_registry.register_metadir('development2',
3455
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2',
3456
help='1.6.1 with B+Tree based index. '
3458
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3460
branch_format='bzrlib.branch.BzrBranchFormat7',
3461
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3465
format_registry.register_metadir('development2-subtree',
3466
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3467
help='1.6.1-subtree with B+Tree based index. '
3469
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3471
branch_format='bzrlib.branch.BzrBranchFormat7',
3472
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3476
# These next two formats should be removed when the gc formats are
3477
# updated to use WorkingTreeFormat6 and are merged into bzr.dev
3478
format_registry.register_metadir('development-wt6',
3479
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3480
help='1.14 with filtered views. '
3482
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3484
branch_format='bzrlib.branch.BzrBranchFormat7',
3485
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3489
format_registry.register_metadir('development-wt6-rich-root',
3490
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3491
help='A variant of development-wt6 that supports rich-root data '
3492
'(needed for bzr-svn and bzr-git).',
3493
branch_format='bzrlib.branch.BzrBranchFormat7',
3494
tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3498
# The following format should be an alias for the rich root equivalent
3499
# of the default format
3500
format_registry.register_metadir('default-rich-root',
3501
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3502
help='Default format, rich root variant. (needed for bzr-svn and bzr-git).',
3503
branch_format='bzrlib.branch.BzrBranchFormat6',
3504
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3507
# The current format that is made on 'bzr init'.
3508
format_registry.set_default('pack-0.92')