19
19
At format 7 this was split out into Branch, Repository and Checkout control
22
Note: This module has a lot of ``open`` functions/methods that return
23
references to in-memory objects. As a rule, there are no matching ``close``
24
methods. To free any associated resources, simply stop referencing the
23
# TODO: remove unittest dependency; put that stuff inside the test suite
25
# TODO: Can we move specific formats into separate modules to make this file
28
# TODO: Move old formats into a plugin to make this file smaller.
28
30
from cStringIO import StringIO
32
34
from bzrlib.lazy_import import lazy_import
33
35
lazy_import(globals(), """
34
from copy import deepcopy
35
36
from stat import S_ISDIR
38
from warnings import warn
39
41
from bzrlib import (
45
50
revision as _mod_revision,
54
61
from bzrlib.osutils import (
65
from bzrlib.repository import Repository
59
66
from bzrlib.smart.client import _SmartClient
60
67
from bzrlib.smart import protocol
61
from bzrlib.store.revision.text import TextRevisionStore
62
from bzrlib.store.text import TextStore
63
68
from bzrlib.store.versioned import WeaveStore
64
69
from bzrlib.transactions import WriteTransaction
65
70
from bzrlib.transport import (
145
157
format.get_format_description(),
148
def clone(self, url, revision_id=None, force_new_repo=False):
160
def clone(self, url, revision_id=None, force_new_repo=False,
161
preserve_stacking=False):
149
162
"""Clone this bzrdir and its contents to url verbatim.
151
If urls last component does not exist, it will be created.
153
if revision_id is not None, then the clone operation may tune
164
:param url: The url create the clone at. If url's last component does
165
not exist, it will be created.
166
:param revision_id: The tip revision-id to use for any branch or
167
working tree. If not None, then the clone operation may tune
154
168
itself to download less data.
155
:param force_new_repo: Do not use a shared repository for the target
169
:param force_new_repo: Do not use a shared repository for the target
156
170
even if one is available.
171
:param preserve_stacking: When cloning a stacked branch, stack the
172
new branch on top of the other branch's stacked-on branch.
158
174
return self.clone_on_transport(get_transport(url),
159
175
revision_id=revision_id,
160
force_new_repo=force_new_repo)
176
force_new_repo=force_new_repo,
177
preserve_stacking=preserve_stacking)
162
179
def clone_on_transport(self, transport, revision_id=None,
163
force_new_repo=False):
180
force_new_repo=False, preserve_stacking=False):
164
181
"""Clone this bzrdir and its contents to transport verbatim.
166
If the target directory does not exist, it will be created.
168
if revision_id is not None, then the clone operation may tune
183
:param transport: The transport for the location to produce the clone
184
at. If the target directory does not exist, it will be created.
185
:param revision_id: The tip revision-id to use for any branch or
186
working tree. If not None, then the clone operation may tune
169
187
itself to download less data.
170
:param force_new_repo: Do not use a shared repository for the target
188
:param force_new_repo: Do not use a shared repository for the target,
171
189
even if one is available.
190
:param preserve_stacking: When cloning a stacked branch, stack the
191
new branch on top of the other branch's stacked-on branch.
173
193
transport.ensure_base()
174
result = self._format.initialize_on_transport(transport)
194
result = self.cloning_metadir().initialize_on_transport(transport)
195
repository_policy = None
176
198
local_repo = self.find_repository()
177
199
except errors.NoRepositoryPresent:
178
200
local_repo = None
202
local_branch = self.open_branch()
203
except errors.NotBranchError:
206
# enable fallbacks when branch is not a branch reference
207
if local_branch.repository.has_same_location(local_repo):
208
local_repo = local_branch.repository
209
if preserve_stacking:
211
stack_on = local_branch.get_stacked_on_url()
212
except (errors.UnstackableBranchFormat,
213
errors.UnstackableRepositoryFormat,
180
218
# may need to copy content in
182
result_repo = local_repo.clone(
184
revision_id=revision_id)
185
result_repo.set_make_working_trees(local_repo.make_working_trees())
188
result_repo = result.find_repository()
189
# fetch content this dir needs.
190
result_repo.fetch(local_repo, revision_id=revision_id)
191
except errors.NoRepositoryPresent:
192
# needed to make one anyway.
193
result_repo = local_repo.clone(
195
revision_id=revision_id)
196
result_repo.set_make_working_trees(local_repo.make_working_trees())
219
repository_policy = result.determine_repository_policy(
220
force_new_repo, stack_on)
221
make_working_trees = local_repo.make_working_trees()
222
result_repo = repository_policy.acquire_repository(
223
make_working_trees, local_repo.is_shared())
224
result_repo.fetch(local_repo, revision_id=revision_id)
197
227
# 1 if there is a branch present
198
228
# make sure its content is available in the target repository
201
self.open_branch().clone(result, revision_id=revision_id)
202
except errors.NotBranchError:
205
self.open_workingtree().clone(result)
206
except (errors.NoWorkingTree, errors.NotLocalUrl):
230
if local_branch is not None:
231
result_branch = local_branch.clone(result, revision_id=revision_id)
232
if repository_policy is not None:
233
repository_policy.configure_branch(result_branch)
234
if result_repo is None or result_repo.make_working_trees():
236
self.open_workingtree().clone(result)
237
except (errors.NoWorkingTree, errors.NotLocalUrl):
210
241
# TODO: This should be given a Transport, and should chdir up; otherwise
213
244
t = get_transport(url)
216
# TODO: Should take a Transport
218
def create(cls, base, format=None):
248
def create(cls, base, format=None, possible_transports=None):
219
249
"""Create a new BzrDir at the url 'base'.
221
This will call the current default formats initialize with base
222
as the only parameter.
224
251
:param format: If supplied, the format of branch to create. If not
225
252
supplied, the default is used.
253
:param possible_transports: If supplied, a list of transports that
254
can be reused to share a remote connection.
227
256
if cls is not BzrDir:
228
257
raise AssertionError("BzrDir.create always creates the default"
229
258
" format, not one of %r" % cls)
230
t = get_transport(base)
259
t = get_transport(base, possible_transports)
232
261
if format is None:
233
262
format = BzrDirFormat.get_default_format()
234
return format.initialize(safe_unicode(base))
263
return format.initialize_on_transport(t)
266
def find_bzrdirs(transport, evaluate=None, list_current=None):
267
"""Find bzrdirs recursively from current location.
269
This is intended primarily as a building block for more sophisticated
270
functionality, like finding trees under a directory, or finding
271
branches that use a given repository.
272
:param evaluate: An optional callable that yields recurse, value,
273
where recurse controls whether this bzrdir is recursed into
274
and value is the value to yield. By default, all bzrdirs
275
are recursed into, and the return value is the bzrdir.
276
:param list_current: if supplied, use this function to list the current
277
directory, instead of Transport.list_dir
278
:return: a generator of found bzrdirs, or whatever evaluate returns.
280
if list_current is None:
281
def list_current(transport):
282
return transport.list_dir('')
284
def evaluate(bzrdir):
287
pending = [transport]
288
while len(pending) > 0:
289
current_transport = pending.pop()
292
bzrdir = BzrDir.open_from_transport(current_transport)
293
except errors.NotBranchError:
296
recurse, value = evaluate(bzrdir)
299
subdirs = list_current(current_transport)
300
except errors.NoSuchFile:
303
for subdir in sorted(subdirs, reverse=True):
304
pending.append(current_transport.clone(subdir))
307
def find_branches(transport):
308
"""Find all branches under a transport.
310
This will find all branches below the transport, including branches
311
inside other branches. Where possible, it will use
312
Repository.find_branches.
314
To list all the branches that use a particular Repository, see
315
Repository.find_branches
317
def evaluate(bzrdir):
319
repository = bzrdir.open_repository()
320
except errors.NoRepositoryPresent:
323
return False, (None, repository)
325
branch = bzrdir.open_branch()
326
except errors.NotBranchError:
327
return True, (None, None)
329
return True, (branch, None)
331
for branch, repo in BzrDir.find_bzrdirs(transport, evaluate=evaluate):
333
branches.extend(repo.find_branches())
334
if branch is not None:
335
branches.append(branch)
338
def destroy_repository(self):
339
"""Destroy the repository in this BzrDir"""
340
raise NotImplementedError(self.destroy_repository)
236
342
def create_branch(self):
237
343
"""Create a branch in this BzrDir.
239
The bzrdirs format will control what branch format is created.
345
The bzrdir's format will control what branch format is created.
240
346
For more control see BranchFormatXX.create(a_bzrdir).
242
348
raise NotImplementedError(self.create_branch)
350
def destroy_branch(self):
351
"""Destroy the branch in this BzrDir"""
352
raise NotImplementedError(self.destroy_branch)
245
355
def create_branch_and_repo(base, force_new_repo=False, format=None):
246
356
"""Create a new BzrDir, Branch and Repository at the url 'base'.
248
This will use the current default BzrDirFormat, and use whatever
358
This will use the current default BzrDirFormat unless one is
359
specified, and use whatever
249
360
repository format that that uses via bzrdir.create_branch and
250
361
create_repository. If a shared repository is available that is used
255
366
:param base: The URL to create the branch at.
256
367
:param force_new_repo: If True a new repository is always created.
368
:param format: If supplied, the format of branch to create. If not
369
supplied, the default is used.
258
371
bzrdir = BzrDir.create(base, format)
259
372
bzrdir._find_or_create_repository(force_new_repo)
260
373
return bzrdir.create_branch()
375
def determine_repository_policy(self, force_new_repo=False, stack_on=None,
376
stack_on_pwd=None, require_stacking=False):
377
"""Return an object representing a policy to use.
379
This controls whether a new repository is created, or a shared
380
repository used instead.
382
If stack_on is supplied, will not seek a containing shared repo.
383
:param force_new_repo: If True, require a new repository to be created.
384
:param stack_on: If supplied, the location to stack on. If not
385
supplied, a default_stack_on location may be used.
386
:param stack_on_pwd: If stack_on is relative, the location it is
389
def repository_policy(found_bzrdir):
392
config = found_bzrdir.get_config()
394
if config is not None:
395
stack_on = config.get_default_stack_on()
396
if stack_on is not None:
397
stack_on_pwd = found_bzrdir.root_transport.base
399
note('Using default stacking branch %s at %s', stack_on,
401
# does it have a repository ?
403
repository = found_bzrdir.open_repository()
404
except errors.NoRepositoryPresent:
407
if ((found_bzrdir.root_transport.base !=
408
self.root_transport.base) and not repository.is_shared()):
415
return UseExistingRepository(repository, stack_on,
416
stack_on_pwd, require_stacking=require_stacking), True
418
return CreateRepository(self, stack_on, stack_on_pwd,
419
require_stacking=require_stacking), True
421
if not force_new_repo:
423
policy = self._find_containing(repository_policy)
424
if policy is not None:
428
return UseExistingRepository(self.open_repository(),
429
stack_on, stack_on_pwd,
430
require_stacking=require_stacking)
431
except errors.NoRepositoryPresent:
433
return CreateRepository(self, stack_on, stack_on_pwd,
434
require_stacking=require_stacking)
262
436
def _find_or_create_repository(self, force_new_repo):
263
437
"""Create a new repository if needed, returning the repository."""
265
return self.create_repository()
267
return self.find_repository()
268
except errors.NoRepositoryPresent:
269
return self.create_repository()
438
policy = self.determine_repository_policy(force_new_repo)
439
return policy.acquire_repository()
272
442
def create_branch_convenience(base, force_new_repo=False,
273
force_new_tree=None, format=None):
443
force_new_tree=None, format=None,
444
possible_transports=None):
274
445
"""Create a new BzrDir, Branch and Repository at the url 'base'.
276
447
This is a convenience function - it will use an existing repository
277
448
if possible, can be told explicitly whether to create a working tree or
280
This will use the current default BzrDirFormat, and use whatever
451
This will use the current default BzrDirFormat unless one is
452
specified, and use whatever
281
453
repository format that that uses via bzrdir.create_branch and
282
454
create_repository. If a shared repository is available that is used
283
455
preferentially. Whatever repository is used, its tree creation policy
292
464
:param force_new_repo: If True a new repository is always created.
293
465
:param force_new_tree: If True or False force creation of a tree or
294
466
prevent such creation respectively.
295
:param format: Override for the for the bzrdir format to create
467
:param format: Override for the bzrdir format to create.
468
:param possible_transports: An optional reusable transports list.
297
470
if force_new_tree:
298
471
# check for non local urls
299
t = get_transport(safe_unicode(base))
472
t = get_transport(base, possible_transports)
300
473
if not isinstance(t, LocalTransport):
301
474
raise errors.NotLocalUrl(base)
302
bzrdir = BzrDir.create(base, format)
475
bzrdir = BzrDir.create(base, format, possible_transports)
303
476
repo = bzrdir._find_or_create_repository(force_new_repo)
304
477
result = bzrdir.create_branch()
305
if force_new_tree or (repo.make_working_trees() and
478
if force_new_tree or (repo.make_working_trees() and
306
479
force_new_tree is None):
308
481
bzrdir.create_workingtree()
309
482
except errors.NotLocalUrl:
314
def create_repository(base, shared=False, format=None):
315
"""Create a new BzrDir and Repository at the url 'base'.
317
If no format is supplied, this will default to the current default
318
BzrDirFormat by default, and use whatever repository format that that
319
uses for bzrdirformat.create_repository.
321
:param shared: Create a shared repository rather than a standalone
323
The Repository object is returned.
325
This must be overridden as an instance method in child classes, where
326
it should take no parameters and construct whatever repository format
327
that child class desires.
329
bzrdir = BzrDir.create(base, format)
330
return bzrdir.create_repository(shared)
333
487
def create_standalone_workingtree(base, format=None):
336
490
'base' must be a local path or a file:// url.
338
This will use the current default BzrDirFormat, and use whatever
492
This will use the current default BzrDirFormat unless one is
493
specified, and use whatever
339
494
repository format that that uses for bzrdirformat.create_workingtree,
340
495
create_branch and create_repository.
497
:param format: Override for the bzrdir format to create.
342
498
:return: The WorkingTree object.
344
t = get_transport(safe_unicode(base))
500
t = get_transport(base)
345
501
if not isinstance(t, LocalTransport):
346
502
raise errors.NotLocalUrl(base)
347
bzrdir = BzrDir.create_branch_and_repo(safe_unicode(base),
503
bzrdir = BzrDir.create_branch_and_repo(base,
348
504
force_new_repo=True,
349
505
format=format).bzrdir
350
506
return bzrdir.create_workingtree()
352
def create_workingtree(self, revision_id=None):
508
def create_workingtree(self, revision_id=None, from_branch=None,
509
accelerator_tree=None, hardlink=False):
353
510
"""Create a working tree at this BzrDir.
355
revision_id: create it as of this revision id.
512
:param revision_id: create it as of this revision id.
513
:param from_branch: override bzrdir branch (for lightweight checkouts)
514
:param accelerator_tree: A tree which can be used for retrieving file
515
contents more quickly than the revision tree, i.e. a workingtree.
516
The revision tree will be used for cases where accelerator_tree's
517
content is different.
357
519
raise NotImplementedError(self.create_workingtree)
359
def retire_bzrdir(self):
521
def retire_bzrdir(self, limit=10000):
360
522
"""Permanently disable the bzrdir.
362
524
This is done by renaming it to give the user some ability to recover
391
559
raise NotImplementedError(self.destroy_workingtree_metadata)
561
def _find_containing(self, evaluate):
562
"""Find something in a containing control directory.
564
This method will scan containing control dirs, until it finds what
565
it is looking for, decides that it will never find it, or runs out
566
of containing control directories to check.
568
It is used to implement find_repository and
569
determine_repository_policy.
571
:param evaluate: A function returning (value, stop). If stop is True,
572
the value will be returned.
576
result, stop = evaluate(found_bzrdir)
579
next_transport = found_bzrdir.root_transport.clone('..')
580
if (found_bzrdir.root_transport.base == next_transport.base):
581
# top of the file system
583
# find the next containing bzrdir
585
found_bzrdir = BzrDir.open_containing_from_transport(
587
except errors.NotBranchError:
393
590
def find_repository(self):
394
"""Find the repository that should be used for a_bzrdir.
591
"""Find the repository that should be used.
396
593
This does not require a branch as we use it to find the repo for
397
594
new branches as well as to hook existing branches up to their
401
return self.open_repository()
402
except errors.NoRepositoryPresent:
404
next_transport = self.root_transport.clone('..')
406
# find the next containing bzrdir
408
found_bzrdir = BzrDir.open_containing_from_transport(
410
except errors.NotBranchError:
412
raise errors.NoRepositoryPresent(self)
597
def usable_repository(found_bzrdir):
413
598
# does it have a repository ?
415
600
repository = found_bzrdir.open_repository()
416
601
except errors.NoRepositoryPresent:
417
next_transport = found_bzrdir.root_transport.clone('..')
418
if (found_bzrdir.root_transport.base == next_transport.base):
419
# top of the file system
423
if ((found_bzrdir.root_transport.base ==
424
self.root_transport.base) or repository.is_shared()):
603
if found_bzrdir.root_transport.base == self.root_transport.base:
604
return repository, True
605
elif repository.is_shared():
606
return repository, True
427
raise errors.NoRepositoryPresent(self)
428
raise errors.NoRepositoryPresent(self)
610
found_repo = self._find_containing(usable_repository)
611
if found_repo is None:
612
raise errors.NoRepositoryPresent(self)
430
615
def get_branch_reference(self):
431
616
"""Return the referenced URL for the branch in this bzrdir.
444
629
a format string, and vice versa.
446
631
If branch_format is None, the transport is returned with no
447
checking. if it is not None, then the returned transport is
632
checking. If it is not None, then the returned transport is
448
633
guaranteed to point to an existing directory ready for use.
450
635
raise NotImplementedError(self.get_branch_transport)
637
def _find_creation_modes(self):
638
"""Determine the appropriate modes for files and directories.
640
They're always set to be consistent with the base directory,
641
assuming that this transport allows setting modes.
643
# TODO: Do we need or want an option (maybe a config setting) to turn
644
# this off or override it for particular locations? -- mbp 20080512
645
if self._mode_check_done:
647
self._mode_check_done = True
649
st = self.transport.stat('.')
650
except errors.TransportNotPossible:
651
self._dir_mode = None
652
self._file_mode = None
654
# Check the directory mode, but also make sure the created
655
# directories and files are read-write for this user. This is
656
# mostly a workaround for filesystems which lie about being able to
657
# write to a directory (cygwin & win32)
658
self._dir_mode = (st.st_mode & 07777) | 00700
659
# Remove the sticky and execute bits for files
660
self._file_mode = self._dir_mode & ~07111
662
def _get_file_mode(self):
663
"""Return Unix mode for newly created files, or None.
665
if not self._mode_check_done:
666
self._find_creation_modes()
667
return self._file_mode
669
def _get_dir_mode(self):
670
"""Return Unix mode for newly created directories, or None.
672
if not self._mode_check_done:
673
self._find_creation_modes()
674
return self._dir_mode
452
676
def get_repository_transport(self, repository_format):
453
677
"""Get the transport for use by repository format in this BzrDir.
626
857
raise errors.NotBranchError(path=url)
627
858
a_transport = new_t
860
def _get_tree_branch(self):
861
"""Return the branch and tree, if any, for this bzrdir.
863
Return None for tree if not present or inaccessible.
864
Raise NotBranchError if no branch is present.
865
:return: (tree, branch)
868
tree = self.open_workingtree()
869
except (errors.NoWorkingTree, errors.NotLocalUrl):
871
branch = self.open_branch()
877
def open_tree_or_branch(klass, location):
878
"""Return the branch and working tree at a location.
880
If there is no tree at the location, tree will be None.
881
If there is no branch at the location, an exception will be
883
:return: (tree, branch)
885
bzrdir = klass.open(location)
886
return bzrdir._get_tree_branch()
630
889
def open_containing_tree_or_branch(klass, location):
631
890
"""Return the branch and working tree contained by a location.
637
896
relpath is the portion of the path that is contained by the branch.
639
898
bzrdir, relpath = klass.open_containing(location)
641
tree = bzrdir.open_workingtree()
642
except (errors.NoWorkingTree, errors.NotLocalUrl):
644
branch = bzrdir.open_branch()
899
tree, branch = bzrdir._get_tree_branch()
647
900
return tree, branch, relpath
903
def open_containing_tree_branch_or_repository(klass, location):
904
"""Return the working tree, branch and repo contained by a location.
906
Returns (tree, branch, repository, relpath).
907
If there is no tree containing the location, tree will be None.
908
If there is no branch containing the location, branch will be None.
909
If there is no repository containing the location, repository will be
911
relpath is the portion of the path that is contained by the innermost
914
If no tree, branch or repository is found, a NotBranchError is raised.
916
bzrdir, relpath = klass.open_containing(location)
918
tree, branch = bzrdir._get_tree_branch()
919
except errors.NotBranchError:
921
repo = bzrdir.find_repository()
922
return None, None, repo, relpath
923
except (errors.NoRepositoryPresent):
924
raise errors.NotBranchError(location)
925
return tree, branch, branch.repository, relpath
649
927
def open_repository(self, _unsupported=False):
650
928
"""Open the repository object at this BzrDir if one is present.
652
This will not follow the Branch object pointer - its strictly a direct
930
This will not follow the Branch object pointer - it's strictly a direct
653
931
open facility. Most client code should use open_branch().repository to
654
932
get at a repository.
656
_unsupported is a private parameter, not part of the api.
934
:param _unsupported: a private parameter, not part of the api.
657
935
TODO: static convenience version of this?
659
937
raise NotImplementedError(self.open_repository)
661
939
def open_workingtree(self, _unsupported=False,
662
recommend_upgrade=True):
940
recommend_upgrade=True, from_branch=None):
663
941
"""Open the workingtree object at this BzrDir if one is present.
665
943
:param recommend_upgrade: Optional keyword parameter, when True (the
666
944
default), emit through the ui module a recommendation that the user
667
945
upgrade the working tree when the workingtree being opened is old
668
946
(but still fully supported).
947
:param from_branch: override bzrdir branch (for lightweight checkouts)
670
949
raise NotImplementedError(self.open_workingtree)
761
1041
if revision_id is not None, then the clone operation may tune
762
1042
itself to download less data.
1043
:param accelerator_tree: A tree which can be used for retrieving file
1044
contents more quickly than the revision tree, i.e. a workingtree.
1045
The revision tree will be used for cases where accelerator_tree's
1046
content is different.
1047
:param hardlink: If true, hard-link files from accelerator_tree,
1049
:param stacked: If true, create a stacked branch referring to the
1050
location of this control directory.
764
target_transport = get_transport(url)
1052
target_transport = get_transport(url, possible_transports)
765
1053
target_transport.ensure_base()
766
1054
cloning_format = self.cloning_metadir()
767
1055
result = cloning_format.initialize_on_transport(target_transport)
769
1057
source_branch = self.open_branch()
770
1058
source_repository = source_branch.repository
1060
stacked_branch_url = self.root_transport.base
1062
# if a stacked branch wasn't requested, we don't create one
1063
# even if the origin was stacked
1064
stacked_branch_url = None
771
1065
except errors.NotBranchError:
772
1066
source_branch = None
774
1068
source_repository = self.open_repository()
775
1069
except errors.NoRepositoryPresent:
776
1070
source_repository = None
781
result_repo = result.find_repository()
782
except errors.NoRepositoryPresent:
784
if source_repository is None and result_repo is not None:
786
elif source_repository is None and result_repo is None:
787
# no repo available, make a new one
788
result.create_repository()
789
elif source_repository is not None and result_repo is None:
790
# have source, and want to make a new target repo
791
result_repo = source_repository.sprout(result, revision_id=revision_id)
793
# fetch needed content into target.
794
if source_repository is not None:
796
# source_repository.copy_content_into(result_repo, revision_id=revision_id)
797
# so we can override the copy method
798
result_repo.fetch(source_repository, revision_id=revision_id)
1071
stacked_branch_url = None
1072
repository_policy = result.determine_repository_policy(
1073
force_new_repo, stacked_branch_url, require_stacking=stacked)
1074
result_repo = repository_policy.acquire_repository()
1075
if source_repository is not None:
1076
result_repo.fetch(source_repository, revision_id=revision_id)
1078
# Create/update the result branch
799
1079
if source_branch is not None:
800
source_branch.sprout(result, revision_id=revision_id)
1080
result_branch = source_branch.sprout(result,
1081
revision_id=revision_id)
802
result.create_branch()
803
# TODO: jam 20060426 we probably need a test in here in the
804
# case that the newly sprouted branch is a remote one
805
if result_repo is None or result_repo.make_working_trees():
806
wt = result.create_workingtree()
1083
result_branch = result.create_branch()
1084
repository_policy.configure_branch(result_branch)
1086
# Create/update the result working tree
1087
if isinstance(target_transport, LocalTransport) and (
1088
result_repo is None or result_repo.make_working_trees()):
1089
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
809
1093
if wt.path2id('') is None:
859
1140
"""Pre-splitout bzrdirs do not suffer from stale locks."""
860
1141
raise NotImplementedError(self.break_lock)
862
def clone(self, url, revision_id=None, force_new_repo=False):
863
"""See BzrDir.clone()."""
1143
def cloning_metadir(self):
1144
"""Produce a metadir suitable for cloning with."""
1145
return self._format.__class__()
1147
def clone(self, url, revision_id=None, force_new_repo=False,
1148
preserve_stacking=False):
1149
"""See BzrDir.clone().
1151
force_new_repo has no effect, since this family of formats always
1152
require a new repository.
1153
preserve_stacking has no effect, since no source branch using this
1154
family of formats can be stacked, so there is no stacking to preserve.
864
1156
from bzrlib.workingtree import WorkingTreeFormat2
865
1157
self._make_tail(url)
866
1158
result = self._format._initialize_for_clone(url)
876
1168
except errors.NotLocalUrl:
877
1169
# but we cannot do it for remote trees.
878
1170
to_branch = result.open_branch()
879
WorkingTreeFormat2().stub_initialize_remote(to_branch.control_files)
1171
WorkingTreeFormat2()._stub_initialize_remote(to_branch)
882
1174
def create_branch(self):
883
1175
"""See BzrDir.create_branch."""
884
1176
return self.open_branch()
1178
def destroy_branch(self):
1179
"""See BzrDir.destroy_branch."""
1180
raise errors.UnsupportedOperation(self.destroy_branch, self)
886
1182
def create_repository(self, shared=False):
887
1183
"""See BzrDir.create_repository."""
889
1185
raise errors.IncompatibleFormat('shared repository', self._format)
890
1186
return self.open_repository()
892
def create_workingtree(self, revision_id=None):
1188
def destroy_repository(self):
1189
"""See BzrDir.destroy_repository."""
1190
raise errors.UnsupportedOperation(self.destroy_repository, self)
1192
def create_workingtree(self, revision_id=None, from_branch=None,
1193
accelerator_tree=None, hardlink=False):
893
1194
"""See BzrDir.create_workingtree."""
894
1195
# this looks buggy but is not -really-
895
1196
# because this format creates the workingtree when the bzrdir is
962
1263
self._check_supported(format, unsupported)
963
1264
return format.open(self, _found=True)
965
def sprout(self, url, revision_id=None, force_new_repo=False):
1266
def sprout(self, url, revision_id=None, force_new_repo=False,
1267
possible_transports=None, accelerator_tree=None,
1268
hardlink=False, stacked=False):
966
1269
"""See BzrDir.sprout()."""
1271
raise errors.UnstackableBranchFormat(
1272
self._format, self.root_transport.base)
967
1273
from bzrlib.workingtree import WorkingTreeFormat2
968
1274
self._make_tail(url)
969
1275
result = self._format._initialize_for_clone(url)
1058
1366
"""See BzrDir.create_branch."""
1059
1367
return self._format.get_branch_format().initialize(self)
1369
def destroy_branch(self):
1370
"""See BzrDir.create_branch."""
1371
self.transport.delete_tree('branch')
1061
1373
def create_repository(self, shared=False):
1062
1374
"""See BzrDir.create_repository."""
1063
1375
return self._format.repository_format.initialize(self, shared)
1065
def create_workingtree(self, revision_id=None):
1377
def destroy_repository(self):
1378
"""See BzrDir.destroy_repository."""
1379
self.transport.delete_tree('repository')
1381
def create_workingtree(self, revision_id=None, from_branch=None,
1382
accelerator_tree=None, hardlink=False):
1066
1383
"""See BzrDir.create_workingtree."""
1067
from bzrlib.workingtree import WorkingTreeFormat
1068
return self._format.workingtree_format.initialize(self, revision_id)
1384
return self._format.workingtree_format.initialize(
1385
self, revision_id, from_branch=from_branch,
1386
accelerator_tree=accelerator_tree, hardlink=hardlink)
1070
1388
def destroy_workingtree(self):
1071
1389
"""See BzrDir.destroy_workingtree."""
1072
1390
wt = self.open_workingtree(recommend_upgrade=False)
1073
1391
repository = wt.branch.repository
1074
1392
empty = repository.revision_tree(_mod_revision.NULL_REVISION)
1075
wt.revert([], old_tree=empty)
1393
wt.revert(old_tree=empty)
1076
1394
self.destroy_workingtree_metadata()
1078
1396
def destroy_workingtree_metadata(self):
1309
1631
# FIXME: RBC 20060121 don't peek under
1311
1633
mode=temp_control._dir_mode)
1634
if sys.platform == 'win32' and isinstance(transport, LocalTransport):
1635
win32utils.set_file_attr_hidden(transport._abspath('.bzr'))
1312
1636
file_mode = temp_control._file_mode
1313
1637
del temp_control
1314
mutter('created control directory in ' + transport.base)
1315
control = transport.clone('.bzr')
1316
utf8_files = [('README',
1317
"This is a Bazaar-NG control directory.\n"
1318
"Do not change any files in this directory.\n"),
1638
bzrdir_transport = transport.clone('.bzr')
1639
utf8_files = [('README',
1640
"This is a Bazaar control directory.\n"
1641
"Do not change any files in this directory.\n"
1642
"See http://bazaar-vcs.org/ for more information about Bazaar.\n"),
1319
1643
('branch-format', self.get_format_string()),
1321
1645
# NB: no need to escape relative paths that are url safe.
1322
control_files = lockable_files.LockableFiles(control,
1323
self._lock_file_name, self._lock_class)
1646
control_files = lockable_files.LockableFiles(bzrdir_transport,
1647
self._lock_file_name, self._lock_class)
1324
1648
control_files.create_lock()
1325
1649
control_files.lock_write()
1327
for file, content in utf8_files:
1328
control_files.put_utf8(file, content)
1651
for (filename, content) in utf8_files:
1652
bzrdir_transport.put_bytes(filename, content,
1330
1655
control_files.unlock()
1331
1656
return self.open(transport, _found=True)
1700
2020
BzrDirFormat._default_format = __default_format
1703
class BzrDirTestProviderAdapter(object):
1704
"""A tool to generate a suite testing multiple bzrdir formats at once.
1706
This is done by copying the test once for each transport and injecting
1707
the transport_server, transport_readonly_server, and bzrdir_format
1708
classes into each copy. Each copy is also given a new id() to make it
1712
def __init__(self, vfs_factory, transport_server, transport_readonly_server,
1714
"""Create an object to adapt tests.
1716
:param vfs_server: A factory to create a Transport Server which has
1717
all the VFS methods working, and is writable.
1719
self._vfs_factory = vfs_factory
1720
self._transport_server = transport_server
1721
self._transport_readonly_server = transport_readonly_server
1722
self._formats = formats
1724
def adapt(self, test):
1725
result = unittest.TestSuite()
1726
for format in self._formats:
1727
new_test = deepcopy(test)
1728
new_test.vfs_transport_factory = self._vfs_factory
1729
new_test.transport_server = self._transport_server
1730
new_test.transport_readonly_server = self._transport_readonly_server
1731
new_test.bzrdir_format = format
1732
def make_new_test_id():
1733
new_id = "%s(%s)" % (new_test.id(), format.__class__.__name__)
1734
return lambda: new_id
1735
new_test.id = make_new_test_id()
1736
result.addTest(new_test)
1740
2023
class Converter(object):
1741
2024
"""Converts a disk format object from one format to another."""
1857
2143
self.bzrdir.transport.mkdir('revision-store')
1858
2144
revision_transport = self.bzrdir.transport.clone('revision-store')
1859
2145
# TODO permissions
1860
_revision_store = TextRevisionStore(TextStore(revision_transport,
2146
from bzrlib.xml5 import serializer_v5
2147
from bzrlib.repofmt.weaverepo import RevisionTextStore
2148
revision_store = RevisionTextStore(revision_transport,
2149
serializer_v5, False, versionedfile.PrefixMapper(),
2150
lambda:True, lambda:True)
1864
transaction = WriteTransaction()
1865
2152
for i, rev_id in enumerate(self.converted_revs):
1866
2153
self.pb.update('write revision', i, len(self.converted_revs))
1867
_revision_store.add_revision(self.revisions[rev_id], transaction)
2154
text = serializer_v5.write_revision_to_string(
2155
self.revisions[rev_id])
2157
revision_store.add_lines(key, None, osutils.split_lines(text))
1869
2159
self.pb.clear()
1884
2174
self.absent_revisions.add(rev_id)
1886
rev = self.branch.repository._revision_store.get_revision(rev_id,
1887
self.branch.repository.get_transaction())
2176
rev = self.branch.repository.get_revision(rev_id)
1888
2177
for parent_id in rev.parent_ids:
1889
2178
self.known_revisions.add(parent_id)
1890
2179
self.to_read.append(parent_id)
1891
2180
self.revisions[rev_id] = rev
1893
2182
def _load_old_inventory(self, rev_id):
1894
assert rev_id not in self.converted_revs
1895
2183
old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
1896
2184
inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
1897
2185
inv.revision_id = rev_id
1898
2186
rev = self.revisions[rev_id]
1899
if rev.inventory_sha1:
1900
assert rev.inventory_sha1 == sha_string(old_inv_xml), \
1901
'inventory sha mismatch for {%s}' % rev_id
1904
2189
def _load_updated_inventory(self, rev_id):
1905
assert rev_id in self.converted_revs
1906
2190
inv_xml = self.inv_weave.get_text(rev_id)
1907
inv = xml5.serializer_v5.read_inventory_from_string(inv_xml)
2191
inv = xml5.serializer_v5.read_inventory_from_string(inv_xml, rev_id)
1910
2194
def _convert_one_rev(self, rev_id):
1914
2198
present_parents = [p for p in rev.parent_ids
1915
2199
if p not in self.absent_revisions]
1916
2200
self._convert_revision_contents(rev, inv, present_parents)
1917
self._store_new_weave(rev, inv, present_parents)
2201
self._store_new_inv(rev, inv, present_parents)
1918
2202
self.converted_revs.add(rev_id)
1920
def _store_new_weave(self, rev, inv, present_parents):
1921
# the XML is now updated with text versions
1923
entries = inv.iter_entries()
1925
for path, ie in entries:
1926
assert getattr(ie, 'revision', None) is not None, \
1927
'no revision on {%s} in {%s}' % \
1928
(file_id, rev.revision_id)
2204
def _store_new_inv(self, rev, inv, present_parents):
1929
2205
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
1930
2206
new_inv_sha1 = sha_string(new_inv_xml)
1931
self.inv_weave.add_lines(rev.revision_id,
2207
self.inv_weave.add_lines(rev.revision_id,
1932
2208
present_parents,
1933
2209
new_inv_xml.splitlines(True))
1934
2210
rev.inventory_sha1 = new_inv_sha1
1959
2235
w = Weave(file_id)
1960
2236
self.text_weaves[file_id] = w
1961
2237
text_changed = False
1962
previous_entries = ie.find_previous_heads(parent_invs,
1966
for old_revision in previous_entries:
1967
# if this fails, its a ghost ?
1968
assert old_revision in self.converted_revs, \
1969
"Revision {%s} not in converted_revs" % old_revision
2238
parent_candiate_entries = ie.parent_candidates(parent_invs)
2239
heads = graph.Graph(self).heads(parent_candiate_entries.keys())
2240
# XXX: Note that this is unordered - and this is tolerable because
2241
# the previous code was also unordered.
2242
previous_entries = dict((head, parent_candiate_entries[head]) for head
1970
2244
self.snapshot_ie(previous_entries, ie, w, rev_id)
1972
assert getattr(ie, 'revision', None) is not None
2247
@symbol_versioning.deprecated_method(symbol_versioning.one_one)
2248
def get_parents(self, revision_ids):
2249
for revision_id in revision_ids:
2250
yield self.revisions[revision_id].parent_ids
2252
def get_parent_map(self, revision_ids):
2253
"""See graph._StackedParentsProvider.get_parent_map"""
2254
return dict((revision_id, self.revisions[revision_id])
2255
for revision_id in revision_ids
2256
if revision_id in self.revisions)
1974
2258
def snapshot_ie(self, previous_revisions, ie, w, rev_id):
1975
2259
# TODO: convert this logic, which is ~= snapshot to
2041
2323
if (filename.endswith(".weave") or
2042
2324
filename.endswith(".gz") or
2043
2325
filename.endswith(".sig")):
2044
file_id = os.path.splitext(filename)[0]
2326
file_id, suffix = os.path.splitext(filename)
2046
2328
file_id = filename
2047
prefix_dir = store.hash_prefix(file_id)
2330
new_name = store._mapper.map((file_id,)) + suffix
2048
2331
# FIXME keep track of the dirs made RBC 20060121
2050
store_transport.move(filename, prefix_dir + '/' + filename)
2333
store_transport.move(filename, new_name)
2051
2334
except errors.NoSuchFile: # catches missing dirs strangely enough
2052
store_transport.mkdir(prefix_dir)
2053
store_transport.move(filename, prefix_dir + '/' + filename)
2054
self.bzrdir._control_files.put_utf8('branch-format', BzrDirFormat6().get_format_string())
2335
store_transport.mkdir(osutils.dirname(new_name))
2336
store_transport.move(filename, new_name)
2337
self.bzrdir.transport.put_bytes(
2339
BzrDirFormat6().get_format_string(),
2340
mode=self.bzrdir._get_file_mode())
2057
2343
class ConvertBzrDir6ToMeta(Converter):
2204
2497
# TODO: conversions of Branch and Tree should be done by
2205
# InterXFormat lookups
2498
# InterXFormat lookups/some sort of registry.
2206
2499
# Avoid circular imports
2207
2500
from bzrlib import branch as _mod_branch
2208
if (branch._format.__class__ is _mod_branch.BzrBranchFormat5 and
2209
self.target_format.get_branch_format().__class__ is
2210
_mod_branch.BzrBranchFormat6):
2211
branch_converter = _mod_branch.Converter5to6()
2501
old = branch._format.__class__
2502
new = self.target_format.get_branch_format().__class__
2504
if (old == _mod_branch.BzrBranchFormat5 and
2505
new in (_mod_branch.BzrBranchFormat6,
2506
_mod_branch.BzrBranchFormat7)):
2507
branch_converter = _mod_branch.Converter5to6()
2508
elif (old == _mod_branch.BzrBranchFormat6 and
2509
new == _mod_branch.BzrBranchFormat7):
2510
branch_converter = _mod_branch.Converter6to7()
2512
raise errors.BadConversionTarget("No converter", new)
2212
2513
branch_converter.convert(branch)
2514
branch = self.bzrdir.open_branch()
2515
old = branch._format.__class__
2214
2517
tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
2215
2518
except (errors.NoWorkingTree, errors.NotLocalUrl):
2239
2542
def probe_transport(klass, transport):
2240
2543
"""Return a RemoteBzrDirFormat object if it looks possible."""
2242
client = transport.get_smart_client()
2545
medium = transport.get_smart_medium()
2243
2546
except (NotImplementedError, AttributeError,
2244
errors.TransportNotPossible):
2547
errors.TransportNotPossible, errors.NoSmartMedium,
2548
errors.SmartProtocolError):
2245
2549
# no smart server, so not a branch for this format type.
2246
2550
raise errors.NotBranchError(path=transport.base)
2248
# Send a 'hello' request in protocol version one, and decline to
2249
# open it if the server doesn't support our required version (2) so
2250
# that the VFS-based transport will do it.
2251
request = client.get_request()
2252
smart_protocol = protocol.SmartClientRequestProtocolOne(request)
2253
server_version = smart_protocol.query_version()
2254
if server_version != 2:
2255
raise errors.NotBranchError(path=transport.base)
2552
# Decline to open it if the server doesn't support our required
2553
# version (3) so that the VFS-based transport will do it.
2554
if medium.should_probe():
2556
server_version = medium.protocol_version()
2557
except errors.SmartProtocolError:
2558
# Apparently there's no usable smart server there, even though
2559
# the medium supports the smart protocol.
2560
raise errors.NotBranchError(path=transport.base)
2561
if server_version != '2':
2562
raise errors.NotBranchError(path=transport.base)
2258
2565
def initialize_on_transport(self, transport):
2260
2567
# hand off the request to the smart server
2261
medium = transport.get_smart_medium()
2568
client_medium = transport.get_smart_medium()
2262
2569
except errors.NoSmartMedium:
2263
2570
# TODO: lookup the local format from a server hint.
2264
2571
local_dir_format = BzrDirMetaFormat1()
2265
2572
return local_dir_format.initialize_on_transport(transport)
2266
client = _SmartClient(medium)
2573
client = _SmartClient(client_medium)
2267
2574
path = client.remote_path_from_transport(transport)
2268
response = _SmartClient(medium).call('BzrDirFormat.initialize', path)
2269
assert response[0] in ('ok', ), 'unexpected response code %s' % (response,)
2575
response = client.call('BzrDirFormat.initialize', path)
2576
if response[0] != 'ok':
2577
raise errors.SmartProtocolError('unexpected response code %s' % (response,))
2270
2578
return remote.RemoteBzrDir(transport)
2272
2580
def _open(self, transport):
2350
2671
This function mainly exists to prevent the info object from being
2351
2672
supplied directly.
2353
registry.Registry.register(self, key, factory, help,
2354
BzrDirFormatInfo(native, deprecated, hidden))
2674
registry.Registry.register(self, key, factory, help,
2675
BzrDirFormatInfo(native, deprecated, hidden, experimental))
2677
self._aliases.add(key)
2356
2679
def register_lazy(self, key, module_name, member_name, help, native=True,
2357
deprecated=False, hidden=False):
2358
registry.Registry.register_lazy(self, key, module_name, member_name,
2359
help, BzrDirFormatInfo(native, deprecated, hidden))
2680
deprecated=False, hidden=False, experimental=False, alias=False):
2681
registry.Registry.register_lazy(self, key, module_name, member_name,
2682
help, BzrDirFormatInfo(native, deprecated, hidden, experimental))
2684
self._aliases.add(key)
2361
2686
def set_default(self, key):
2362
2687
"""Set the 'default' key to be a clone of the supplied key.
2364
2689
This method must be called once and only once.
2366
registry.Registry.register(self, 'default', self.get(key),
2691
registry.Registry.register(self, 'default', self.get(key),
2367
2692
self.get_help(key), info=self.get_info(key))
2693
self._aliases.add('default')
2369
2695
def set_default_repository(self, key):
2370
2696
"""Set the FormatRegistry default and Repository default.
2404
2727
def wrapped(key, help, info):
2405
2728
if info.native:
2406
2729
help = '(native) ' + help
2407
return ' %s:\n%s\n\n' % (key,
2730
return ':%s:\n%s\n\n' % (key,
2408
2731
textwrap.fill(help, initial_indent=' ',
2409
2732
subsequent_indent=' '))
2410
output += wrapped('%s/default' % default_realkey, default_help,
2411
self.get_info('default'))
2733
if default_realkey is not None:
2734
output += wrapped(default_realkey, '(default) %s' % default_help,
2735
self.get_info('default'))
2412
2736
deprecated_pairs = []
2737
experimental_pairs = []
2413
2738
for key, help in help_pairs:
2414
2739
info = self.get_info(key)
2415
2740
if info.hidden:
2417
2742
elif info.deprecated:
2418
2743
deprecated_pairs.append((key, help))
2744
elif info.experimental:
2745
experimental_pairs.append((key, help))
2420
2747
output += wrapped(key, help, info)
2748
if len(experimental_pairs) > 0:
2749
output += "Experimental formats are shown below.\n\n"
2750
for key, help in experimental_pairs:
2751
info = self.get_info(key)
2752
output += wrapped(key, help, info)
2421
2753
if len(deprecated_pairs) > 0:
2422
output += "Deprecated formats\n------------------\n\n"
2754
output += "Deprecated formats are shown below.\n\n"
2423
2755
for key, help in deprecated_pairs:
2424
2756
info = self.get_info(key)
2425
2757
output += wrapped(key, help, info)
2762
class RepositoryAcquisitionPolicy(object):
2763
"""Abstract base class for repository acquisition policies.
2765
A repository acquisition policy decides how a BzrDir acquires a repository
2766
for a branch that is being created. The most basic policy decision is
2767
whether to create a new repository or use an existing one.
2769
def __init__(self, stack_on, stack_on_pwd, require_stacking):
2772
:param stack_on: A location to stack on
2773
:param stack_on_pwd: If stack_on is relative, the location it is
2775
:param require_stacking: If True, it is a failure to not stack.
2777
self._stack_on = stack_on
2778
self._stack_on_pwd = stack_on_pwd
2779
self._require_stacking = require_stacking
2781
def configure_branch(self, branch):
2782
"""Apply any configuration data from this policy to the branch.
2784
Default implementation sets repository stacking.
2786
if self._stack_on is None:
2788
if self._stack_on_pwd is None:
2789
stack_on = self._stack_on
2792
stack_on = urlutils.rebase_url(self._stack_on,
2794
branch.bzrdir.root_transport.base)
2795
except errors.InvalidRebaseURLs:
2796
stack_on = self._get_full_stack_on()
2798
branch.set_stacked_on_url(stack_on)
2799
except errors.UnstackableBranchFormat:
2800
if self._require_stacking:
2803
def _get_full_stack_on(self):
2804
"""Get a fully-qualified URL for the stack_on location."""
2805
if self._stack_on is None:
2807
if self._stack_on_pwd is None:
2808
return self._stack_on
2810
return urlutils.join(self._stack_on_pwd, self._stack_on)
2812
def _add_fallback(self, repository):
2813
"""Add a fallback to the supplied repository, if stacking is set."""
2814
stack_on = self._get_full_stack_on()
2815
if stack_on is None:
2817
stacked_dir = BzrDir.open(stack_on)
2819
stacked_repo = stacked_dir.open_branch().repository
2820
except errors.NotBranchError:
2821
stacked_repo = stacked_dir.open_repository()
2823
repository.add_fallback_repository(stacked_repo)
2824
except errors.UnstackableRepositoryFormat:
2825
if self._require_stacking:
2828
def acquire_repository(self, make_working_trees=None, shared=False):
2829
"""Acquire a repository for this bzrdir.
2831
Implementations may create a new repository or use a pre-exising
2833
:param make_working_trees: If creating a repository, set
2834
make_working_trees to this value (if non-None)
2835
:param shared: If creating a repository, make it shared if True
2836
:return: A repository
2838
raise NotImplemented(RepositoryAcquisitionPolicy.acquire_repository)
2841
class CreateRepository(RepositoryAcquisitionPolicy):
2842
"""A policy of creating a new repository"""
2844
def __init__(self, bzrdir, stack_on=None, stack_on_pwd=None,
2845
require_stacking=False):
2848
:param bzrdir: The bzrdir to create the repository on.
2849
:param stack_on: A location to stack on
2850
:param stack_on_pwd: If stack_on is relative, the location it is
2853
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2855
self._bzrdir = bzrdir
2857
def acquire_repository(self, make_working_trees=None, shared=False):
2858
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2860
Creates the desired repository in the bzrdir we already have.
2862
repository = self._bzrdir.create_repository(shared=shared)
2863
self._add_fallback(repository)
2864
if make_working_trees is not None:
2865
repository.set_make_working_trees(make_working_trees)
2869
class UseExistingRepository(RepositoryAcquisitionPolicy):
2870
"""A policy of reusing an existing repository"""
2872
def __init__(self, repository, stack_on=None, stack_on_pwd=None,
2873
require_stacking=False):
2876
:param repository: The repository to use.
2877
:param stack_on: A location to stack on
2878
:param stack_on_pwd: If stack_on is relative, the location it is
2881
RepositoryAcquisitionPolicy.__init__(self, stack_on, stack_on_pwd,
2883
self._repository = repository
2885
def acquire_repository(self, make_working_trees=None, shared=False):
2886
"""Implementation of RepositoryAcquisitionPolicy.acquire_repository
2888
Returns an existing repository to use
2890
self._add_fallback(self._repository)
2891
return self._repository
2430
2894
format_registry = BzrDirFormatRegistry()
2431
2895
format_registry.register('weave', BzrDirFormat6,
2432
2896
'Pre-0.8 format. Slower than knit and does not'
2467
2938
'bzr branches. Incompatible with bzr < 0.15.',
2468
2939
branch_format='bzrlib.branch.BzrBranchFormat6',
2469
2940
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2472
format_registry.set_default('dirstate')
2944
format_registry.register_metadir('pack-0.92',
2945
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
2946
help='New in 0.92: Pack-based format with data compatible with '
2947
'dirstate-tags format repositories. Interoperates with '
2948
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2949
'Previously called knitpack-experimental. '
2950
'For more information, see '
2951
'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
2952
branch_format='bzrlib.branch.BzrBranchFormat6',
2953
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2955
format_registry.register_metadir('pack-0.92-subtree',
2956
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
2957
help='New in 0.92: Pack-based format with data compatible with '
2958
'dirstate-with-subtree format repositories. Interoperates with '
2959
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2960
'Previously called knitpack-experimental. '
2961
'For more information, see '
2962
'http://doc.bazaar-vcs.org/latest/developers/packrepo.html.',
2963
branch_format='bzrlib.branch.BzrBranchFormat6',
2964
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2968
format_registry.register_metadir('rich-root-pack',
2969
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
2970
help='New in 1.0: Pack-based format with data compatible with '
2971
'rich-root format repositories. Incompatible with'
2973
branch_format='bzrlib.branch.BzrBranchFormat6',
2974
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2976
# The following two formats should always just be aliases.
2977
format_registry.register_metadir('development',
2978
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment1',
2979
help='Current development format. Can convert data to and from pack-0.92 '
2980
'(and anything compatible with pack-0.92) format repositories. '
2981
'Repositories and branches in this format can only be read by bzr.dev. '
2983
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
2985
branch_format='bzrlib.branch.BzrBranchFormat7',
2986
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2990
format_registry.register_metadir('development-subtree',
2991
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment1Subtree',
2992
help='Current development format, subtree variant. Can convert data to and '
2993
'from pack-0.92-subtree (and anything compatible with '
2994
'pack-0.92-subtree) format repositories. Repositories and branches in '
2995
'this format can only be read by bzr.dev. Please read '
2996
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
2998
branch_format='bzrlib.branch.BzrBranchFormat7',
2999
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3003
# And the development formats which the will have aliased one of follow:
3004
format_registry.register_metadir('development0',
3005
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment0',
3006
help='Trivial rename of pack-0.92 to provide a development format. '
3008
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3010
branch_format='bzrlib.branch.BzrBranchFormat6',
3011
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3015
format_registry.register_metadir('development0-subtree',
3016
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment0Subtree',
3017
help='Trivial rename of pack-0.92-subtree to provide a development format. '
3019
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3021
branch_format='bzrlib.branch.BzrBranchFormat6',
3022
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3026
format_registry.register_metadir('development1',
3027
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment1',
3028
help='A branch and pack based repository that supports stacking. '
3030
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3032
branch_format='bzrlib.branch.BzrBranchFormat7',
3033
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3037
format_registry.register_metadir('development1-subtree',
3038
'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment1Subtree',
3039
help='A branch and pack based repository that supports stacking. '
3041
'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3043
branch_format='bzrlib.branch.BzrBranchFormat7',
3044
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3048
# The current format that is made on 'bzr init'.
3049
format_registry.set_default('pack-0.92')