434
389
policy = self.determine_repository_policy(force_new_repo)
435
390
return policy.acquire_repository()[0]
392
def _find_source_repo(self, add_cleanup, source_branch):
393
"""Find the source branch and repo for a sprout operation.
395
This is helper intended for use by _sprout.
397
:returns: (source_branch, source_repository). Either or both may be
398
None. If not None, they will be read-locked (and their unlock(s)
399
scheduled via the add_cleanup param).
401
if source_branch is not None:
402
add_cleanup(source_branch.lock_read().unlock)
403
return source_branch, source_branch.repository
405
source_branch = self.open_branch()
406
source_repository = source_branch.repository
407
except errors.NotBranchError:
410
source_repository = self.open_repository()
411
except errors.NoRepositoryPresent:
412
source_repository = None
414
add_cleanup(source_repository.lock_read().unlock)
416
add_cleanup(source_branch.lock_read().unlock)
417
return source_branch, source_repository
419
def sprout(self, url, revision_id=None, force_new_repo=False,
420
recurse='down', possible_transports=None,
421
accelerator_tree=None, hardlink=False, stacked=False,
422
source_branch=None, create_tree_if_local=True):
423
"""Create a copy of this controldir prepared for use as a new line of
426
If url's last component does not exist, it will be created.
428
Attributes related to the identity of the source branch like
429
branch nickname will be cleaned, a working tree is created
430
whether one existed before or not; and a local branch is always
433
if revision_id is not None, then the clone operation may tune
434
itself to download less data.
436
:param accelerator_tree: A tree which can be used for retrieving file
437
contents more quickly than the revision tree, i.e. a workingtree.
438
The revision tree will be used for cases where accelerator_tree's
439
content is different.
440
:param hardlink: If true, hard-link files from accelerator_tree,
442
:param stacked: If true, create a stacked branch referring to the
443
location of this control directory.
444
:param create_tree_if_local: If true, a working-tree will be created
445
when working locally.
447
operation = cleanup.OperationWithCleanups(self._sprout)
448
return operation.run(url, revision_id=revision_id,
449
force_new_repo=force_new_repo, recurse=recurse,
450
possible_transports=possible_transports,
451
accelerator_tree=accelerator_tree, hardlink=hardlink,
452
stacked=stacked, source_branch=source_branch,
453
create_tree_if_local=create_tree_if_local)
455
def _sprout(self, op, url, revision_id=None, force_new_repo=False,
456
recurse='down', possible_transports=None,
457
accelerator_tree=None, hardlink=False, stacked=False,
458
source_branch=None, create_tree_if_local=True):
459
add_cleanup = op.add_cleanup
460
fetch_spec_factory = fetch.FetchSpecFactory()
461
if revision_id is not None:
462
fetch_spec_factory.add_revision_ids([revision_id])
463
fetch_spec_factory.source_branch_stop_revision_id = revision_id
464
target_transport = _mod_transport.get_transport(url,
466
target_transport.ensure_base()
467
cloning_format = self.cloning_metadir(stacked)
468
# Create/update the result branch
469
result = cloning_format.initialize_on_transport(target_transport)
470
source_branch, source_repository = self._find_source_repo(
471
add_cleanup, source_branch)
472
fetch_spec_factory.source_branch = source_branch
473
# if a stacked branch wasn't requested, we don't create one
474
# even if the origin was stacked
475
if stacked and source_branch is not None:
476
stacked_branch_url = self.root_transport.base
478
stacked_branch_url = None
479
repository_policy = result.determine_repository_policy(
480
force_new_repo, stacked_branch_url, require_stacking=stacked)
481
result_repo, is_new_repo = repository_policy.acquire_repository()
482
add_cleanup(result_repo.lock_write().unlock)
483
fetch_spec_factory.source_repo = source_repository
484
fetch_spec_factory.target_repo = result_repo
485
if stacked or (len(result_repo._fallback_repositories) != 0):
486
target_repo_kind = fetch.TargetRepoKinds.STACKED
488
target_repo_kind = fetch.TargetRepoKinds.EMPTY
490
target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
491
fetch_spec_factory.target_repo_kind = target_repo_kind
492
if source_repository is not None:
493
fetch_spec = fetch_spec_factory.make_fetch_spec()
494
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
496
if source_branch is None:
497
# this is for sprouting a controldir without a branch; is that
499
# Not especially, but it's part of the contract.
500
result_branch = result.create_branch()
502
result_branch = source_branch.sprout(result,
503
revision_id=revision_id, repository_policy=repository_policy,
504
repository=result_repo)
505
mutter("created new branch %r" % (result_branch,))
507
# Create/update the result working tree
508
if (create_tree_if_local and
509
isinstance(target_transport, local.LocalTransport) and
510
(result_repo is None or result_repo.make_working_trees())):
511
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
512
hardlink=hardlink, from_branch=result_branch)
515
if wt.path2id('') is None:
517
wt.set_root_id(self.open_workingtree.get_root_id())
518
except errors.NoWorkingTree:
524
if recurse == 'down':
527
basis = wt.basis_tree()
528
elif result_branch is not None:
529
basis = result_branch.basis_tree()
530
elif source_branch is not None:
531
basis = source_branch.basis_tree()
532
if basis is not None:
533
add_cleanup(basis.lock_read().unlock)
534
subtrees = basis.iter_references()
537
for path, file_id in subtrees:
538
target = urlutils.join(url, urlutils.escape(path))
539
sublocation = source_branch.reference_parent(file_id, path)
540
sublocation.bzrdir.sprout(target,
541
basis.get_reference_revision(file_id, path),
542
force_new_repo=force_new_repo, recurse=recurse,
438
549
def create_branch_convenience(base, force_new_repo=False,
439
550
force_new_tree=None, format=None,
985
class BzrDirPreSplitOut(BzrDir):
986
"""A common class for the all-in-one formats."""
988
def __init__(self, _transport, _format):
989
"""See BzrDir.__init__."""
990
super(BzrDirPreSplitOut, self).__init__(_transport, _format)
991
self._control_files = lockable_files.LockableFiles(
992
self.get_branch_transport(None),
993
self._format._lock_file_name,
994
self._format._lock_class)
996
def break_lock(self):
997
"""Pre-splitout bzrdirs do not suffer from stale locks."""
998
raise NotImplementedError(self.break_lock)
1000
def cloning_metadir(self, require_stacking=False):
1001
"""Produce a metadir suitable for cloning with."""
1002
if require_stacking:
1003
return controldir.format_registry.make_bzrdir('1.6')
1004
return self._format.__class__()
1006
def clone(self, url, revision_id=None, force_new_repo=False,
1007
preserve_stacking=False):
1008
"""See BzrDir.clone().
1010
force_new_repo has no effect, since this family of formats always
1011
require a new repository.
1012
preserve_stacking has no effect, since no source branch using this
1013
family of formats can be stacked, so there is no stacking to preserve.
1015
self._make_tail(url)
1016
result = self._format._initialize_for_clone(url)
1017
self.open_repository().clone(result, revision_id=revision_id)
1018
from_branch = self.open_branch()
1019
from_branch.clone(result, revision_id=revision_id)
1021
tree = self.open_workingtree()
1022
except errors.NotLocalUrl:
1023
# make a new one, this format always has to have one.
1024
result._init_workingtree()
1029
def create_branch(self, name=None, repository=None):
1030
"""See BzrDir.create_branch."""
1031
if repository is not None:
1032
raise NotImplementedError(
1033
"create_branch(repository=<not None>) on %r" % (self,))
1034
return self._format.get_branch_format().initialize(self, name=name)
1036
def destroy_branch(self, name=None):
1037
"""See BzrDir.destroy_branch."""
1038
raise errors.UnsupportedOperation(self.destroy_branch, self)
1040
def create_repository(self, shared=False):
1041
"""See BzrDir.create_repository."""
1043
raise errors.IncompatibleFormat('shared repository', self._format)
1044
return self.open_repository()
1046
def destroy_repository(self):
1047
"""See BzrDir.destroy_repository."""
1048
raise errors.UnsupportedOperation(self.destroy_repository, self)
1050
def create_workingtree(self, revision_id=None, from_branch=None,
1051
accelerator_tree=None, hardlink=False):
1052
"""See BzrDir.create_workingtree."""
1053
# The workingtree is sometimes created when the bzrdir is created,
1054
# but not when cloning.
1056
# this looks buggy but is not -really-
1057
# because this format creates the workingtree when the bzrdir is
1059
# clone and sprout will have set the revision_id
1060
# and that will have set it for us, its only
1061
# specific uses of create_workingtree in isolation
1062
# that can do wonky stuff here, and that only
1063
# happens for creating checkouts, which cannot be
1064
# done on this format anyway. So - acceptable wart.
1066
warning("can't support hardlinked working trees in %r"
1069
result = self.open_workingtree(recommend_upgrade=False)
1070
except errors.NoSuchFile:
1071
result = self._init_workingtree()
1072
if revision_id is not None:
1073
if revision_id == _mod_revision.NULL_REVISION:
1074
result.set_parent_ids([])
1076
result.set_parent_ids([revision_id])
1079
def _init_workingtree(self):
1080
from bzrlib.workingtree import WorkingTreeFormat2
1082
return WorkingTreeFormat2().initialize(self)
1083
except errors.NotLocalUrl:
1084
# Even though we can't access the working tree, we need to
1085
# create its control files.
1086
return WorkingTreeFormat2()._stub_initialize_on_transport(
1087
self.transport, self._control_files._file_mode)
1089
def destroy_workingtree(self):
1090
"""See BzrDir.destroy_workingtree."""
1091
raise errors.UnsupportedOperation(self.destroy_workingtree, self)
1093
def destroy_workingtree_metadata(self):
1094
"""See BzrDir.destroy_workingtree_metadata."""
1095
raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1098
def get_branch_transport(self, branch_format, name=None):
1099
"""See BzrDir.get_branch_transport()."""
1100
if name is not None:
1101
raise errors.NoColocatedBranchSupport(self)
1102
if branch_format is None:
1103
return self.transport
1105
branch_format.get_format_string()
1106
except NotImplementedError:
1107
return self.transport
1108
raise errors.IncompatibleFormat(branch_format, self._format)
1110
def get_repository_transport(self, repository_format):
1111
"""See BzrDir.get_repository_transport()."""
1112
if repository_format is None:
1113
return self.transport
1115
repository_format.get_format_string()
1116
except NotImplementedError:
1117
return self.transport
1118
raise errors.IncompatibleFormat(repository_format, self._format)
1120
def get_workingtree_transport(self, workingtree_format):
1121
"""See BzrDir.get_workingtree_transport()."""
1122
if workingtree_format is None:
1123
return self.transport
1125
workingtree_format.get_format_string()
1126
except NotImplementedError:
1127
return self.transport
1128
raise errors.IncompatibleFormat(workingtree_format, self._format)
1130
def needs_format_conversion(self, format=None):
1131
"""See BzrDir.needs_format_conversion()."""
1132
# if the format is not the same as the system default,
1133
# an upgrade is needed.
1135
symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
1136
% 'needs_format_conversion(format=None)')
1137
format = BzrDirFormat.get_default_format()
1138
return not isinstance(self._format, format.__class__)
1140
def open_branch(self, name=None, unsupported=False,
1141
ignore_fallbacks=False):
1142
"""See BzrDir.open_branch."""
1143
from bzrlib.branch import BzrBranchFormat4
1144
format = BzrBranchFormat4()
1145
self._check_supported(format, unsupported)
1146
return format.open(self, name, _found=True)
1148
def sprout(self, url, revision_id=None, force_new_repo=False,
1149
possible_transports=None, accelerator_tree=None,
1150
hardlink=False, stacked=False, create_tree_if_local=True,
1151
source_branch=None):
1152
"""See BzrDir.sprout()."""
1153
if source_branch is not None:
1154
my_branch = self.open_branch()
1155
if source_branch.base != my_branch.base:
1156
raise AssertionError(
1157
"source branch %r is not within %r with branch %r" %
1158
(source_branch, self, my_branch))
1160
raise errors.UnstackableBranchFormat(
1161
self._format, self.root_transport.base)
1162
if not create_tree_if_local:
1163
raise errors.MustHaveWorkingTree(
1164
self._format, self.root_transport.base)
1165
from bzrlib.workingtree import WorkingTreeFormat2
1166
self._make_tail(url)
1167
result = self._format._initialize_for_clone(url)
1169
self.open_repository().clone(result, revision_id=revision_id)
1170
except errors.NoRepositoryPresent:
1173
self.open_branch().sprout(result, revision_id=revision_id)
1174
except errors.NotBranchError:
1177
# we always want a working tree
1178
WorkingTreeFormat2().initialize(result,
1179
accelerator_tree=accelerator_tree,
1184
class BzrDir4(BzrDirPreSplitOut):
1185
"""A .bzr version 4 control object.
1187
This is a deprecated format and may be removed after sept 2006.
1190
def create_repository(self, shared=False):
1191
"""See BzrDir.create_repository."""
1192
return self._format.repository_format.initialize(self, shared)
1194
def needs_format_conversion(self, format=None):
1195
"""Format 4 dirs are always in need of conversion."""
1197
symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
1198
% 'needs_format_conversion(format=None)')
1201
def open_repository(self):
1202
"""See BzrDir.open_repository."""
1203
from bzrlib.repofmt.weaverepo import RepositoryFormat4
1204
return RepositoryFormat4().open(self, _found=True)
1207
class BzrDir5(BzrDirPreSplitOut):
1208
"""A .bzr version 5 control object.
1210
This is a deprecated format and may be removed after sept 2006.
1213
def has_workingtree(self):
1214
"""See BzrDir.has_workingtree."""
1217
def open_repository(self):
1218
"""See BzrDir.open_repository."""
1219
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1220
return RepositoryFormat5().open(self, _found=True)
1222
def open_workingtree(self, _unsupported=False,
1223
recommend_upgrade=True):
1224
"""See BzrDir.create_workingtree."""
1225
from bzrlib.workingtree import WorkingTreeFormat2
1226
wt_format = WorkingTreeFormat2()
1227
# we don't warn here about upgrades; that ought to be handled for the
1229
return wt_format.open(self, _found=True)
1232
class BzrDir6(BzrDirPreSplitOut):
1233
"""A .bzr version 6 control object.
1235
This is a deprecated format and may be removed after sept 2006.
1238
def has_workingtree(self):
1239
"""See BzrDir.has_workingtree."""
1242
def open_repository(self):
1243
"""See BzrDir.open_repository."""
1244
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1245
return RepositoryFormat6().open(self, _found=True)
1247
def open_workingtree(self, _unsupported=False,
1248
recommend_upgrade=True):
1249
"""See BzrDir.create_workingtree."""
1250
# we don't warn here about upgrades; that ought to be handled for the
1252
from bzrlib.workingtree import WorkingTreeFormat2
1253
return WorkingTreeFormat2().open(self, _found=True)
1256
1136
class BzrDirMeta1(BzrDir):
1257
1137
"""A .bzr meta version 1 control object.
1729
def unregister_format(klass, format):
1730
BzrProber.unregister_bzrdir_format(format)
1731
controldir.ControlDirFormat.unregister_format(format)
1732
controldir.network_format_registry.remove(format.get_format_string())
1735
class BzrDirFormat4(BzrDirFormat):
1736
"""Bzr dir format 4.
1738
This format is a combined format for working tree, branch and repository.
1740
- Format 1 working trees [always]
1741
- Format 4 branches [always]
1742
- Format 4 repositories [always]
1744
This format is deprecated: it indexes texts using a text it which is
1745
removed in format 5; write support for this format has been removed.
1748
_lock_class = lockable_files.TransportLock
1750
def get_format_string(self):
1751
"""See BzrDirFormat.get_format_string()."""
1752
return "Bazaar-NG branch, format 0.0.4\n"
1754
def get_format_description(self):
1755
"""See BzrDirFormat.get_format_description()."""
1756
return "All-in-one format 4"
1758
def get_converter(self, format=None):
1759
"""See BzrDirFormat.get_converter()."""
1760
# there is one and only one upgrade path here.
1761
return ConvertBzrDir4To5()
1763
def initialize_on_transport(self, transport):
1764
"""Format 4 branches cannot be created."""
1765
raise errors.UninitializableFormat(self)
1767
def is_supported(self):
1768
"""Format 4 is not supported.
1770
It is not supported because the model changed from 4 to 5 and the
1771
conversion logic is expensive - so doing it on the fly was not
1776
def network_name(self):
1777
return self.get_format_string()
1779
def _open(self, transport):
1780
"""See BzrDirFormat._open."""
1781
return BzrDir4(transport, self)
1783
def __return_repository_format(self):
1784
"""Circular import protection."""
1785
from bzrlib.repofmt.weaverepo import RepositoryFormat4
1786
return RepositoryFormat4()
1787
repository_format = property(__return_repository_format)
1790
class BzrDirFormatAllInOne(BzrDirFormat):
1791
"""Common class for formats before meta-dirs."""
1793
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1794
create_prefix=False, force_new_repo=False, stacked_on=None,
1795
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1797
"""See BzrDirFormat.initialize_on_transport_ex."""
1798
require_stacking = (stacked_on is not None)
1799
# Format 5 cannot stack, but we've been asked to - actually init
1801
if require_stacking:
1802
format = BzrDirMetaFormat1()
1803
return format.initialize_on_transport_ex(transport,
1804
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1805
force_new_repo=force_new_repo, stacked_on=stacked_on,
1806
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1807
make_working_trees=make_working_trees, shared_repo=shared_repo)
1808
return BzrDirFormat.initialize_on_transport_ex(self, transport,
1809
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1810
force_new_repo=force_new_repo, stacked_on=stacked_on,
1811
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1812
make_working_trees=make_working_trees, shared_repo=shared_repo)
1815
class BzrDirFormat5(BzrDirFormatAllInOne):
1816
"""Bzr control format 5.
1818
This format is a combined format for working tree, branch and repository.
1820
- Format 2 working trees [always]
1821
- Format 4 branches [always]
1822
- Format 5 repositories [always]
1823
Unhashed stores in the repository.
1826
_lock_class = lockable_files.TransportLock
1828
def get_format_string(self):
1829
"""See BzrDirFormat.get_format_string()."""
1830
return "Bazaar-NG branch, format 5\n"
1832
def get_branch_format(self):
1833
from bzrlib import branch
1834
return branch.BzrBranchFormat4()
1836
def get_format_description(self):
1837
"""See BzrDirFormat.get_format_description()."""
1838
return "All-in-one format 5"
1840
def get_converter(self, format=None):
1841
"""See BzrDirFormat.get_converter()."""
1842
# there is one and only one upgrade path here.
1843
return ConvertBzrDir5To6()
1845
def _initialize_for_clone(self, url):
1846
return self.initialize_on_transport(
1847
_mod_transport.get_transport(url), _cloning=True)
1849
def initialize_on_transport(self, transport, _cloning=False):
1850
"""Format 5 dirs always have working tree, branch and repository.
1852
Except when they are being cloned.
1854
from bzrlib.branch import BzrBranchFormat4
1855
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1856
result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
1857
RepositoryFormat5().initialize(result, _internal=True)
1859
branch = BzrBranchFormat4().initialize(result)
1860
result._init_workingtree()
1863
def network_name(self):
1864
return self.get_format_string()
1866
def _open(self, transport):
1867
"""See BzrDirFormat._open."""
1868
return BzrDir5(transport, self)
1870
def __return_repository_format(self):
1871
"""Circular import protection."""
1872
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1873
return RepositoryFormat5()
1874
repository_format = property(__return_repository_format)
1877
class BzrDirFormat6(BzrDirFormatAllInOne):
1878
"""Bzr control format 6.
1880
This format is a combined format for working tree, branch and repository.
1882
- Format 2 working trees [always]
1883
- Format 4 branches [always]
1884
- Format 6 repositories [always]
1887
_lock_class = lockable_files.TransportLock
1889
def get_format_string(self):
1890
"""See BzrDirFormat.get_format_string()."""
1891
return "Bazaar-NG branch, format 6\n"
1893
def get_format_description(self):
1894
"""See BzrDirFormat.get_format_description()."""
1895
return "All-in-one format 6"
1897
def get_branch_format(self):
1898
from bzrlib import branch
1899
return branch.BzrBranchFormat4()
1901
def get_converter(self, format=None):
1902
"""See BzrDirFormat.get_converter()."""
1903
# there is one and only one upgrade path here.
1904
return ConvertBzrDir6ToMeta()
1906
def _initialize_for_clone(self, url):
1907
return self.initialize_on_transport(
1908
_mod_transport.get_transport(url), _cloning=True)
1910
def initialize_on_transport(self, transport, _cloning=False):
1911
"""Format 6 dirs always have working tree, branch and repository.
1913
Except when they are being cloned.
1915
from bzrlib.branch import BzrBranchFormat4
1916
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1917
result = super(BzrDirFormat6, self).initialize_on_transport(transport)
1918
RepositoryFormat6().initialize(result, _internal=True)
1920
branch = BzrBranchFormat4().initialize(result)
1921
result._init_workingtree()
1924
def network_name(self):
1925
return self.get_format_string()
1927
def _open(self, transport):
1928
"""See BzrDirFormat._open."""
1929
return BzrDir6(transport, self)
1931
def __return_repository_format(self):
1932
"""Circular import protection."""
1933
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1934
return RepositoryFormat6()
1935
repository_format = property(__return_repository_format)
1938
1613
class BzrDirMetaFormat1(BzrDirFormat):
1939
1614
"""Bzr meta control format 1
1941
1616
This is the first format with split out working tree, branch and repository
1944
- Format 3 working trees [optional]
1945
- Format 5 branches [optional]
1946
- Format 7 repositories [optional]
1621
- Format 3 working trees [optional]
1622
- Format 5 branches [optional]
1623
- Format 7 repositories [optional]
1949
1626
_lock_class = lockdir.LockDir
1628
fixed_components = False
1951
1630
def __init__(self):
1952
1631
self._workingtree_format = None
1953
1632
self._branch_format = None
2143
1826
# Register bzr formats
2144
BzrDirFormat.register_format(BzrDirFormat4())
2145
BzrDirFormat.register_format(BzrDirFormat5())
2146
BzrDirFormat.register_format(BzrDirFormat6())
2147
__default_format = BzrDirMetaFormat1()
2148
BzrDirFormat.register_format(__default_format)
2149
controldir.ControlDirFormat._default_format = __default_format
2152
class Converter(object):
2153
"""Converts a disk format object from one format to another."""
2155
def convert(self, to_convert, pb):
2156
"""Perform the conversion of to_convert, giving feedback via pb.
2158
:param to_convert: The disk object to convert.
2159
:param pb: a progress bar to use for progress information.
2162
def step(self, message):
2163
"""Update the pb by a step."""
2165
self.pb.update(message, self.count, self.total)
2168
class ConvertBzrDir4To5(Converter):
2169
"""Converts format 4 bzr dirs to format 5."""
2172
super(ConvertBzrDir4To5, self).__init__()
2173
self.converted_revs = set()
2174
self.absent_revisions = set()
2178
def convert(self, to_convert, pb):
2179
"""See Converter.convert()."""
2180
self.bzrdir = to_convert
2182
warnings.warn("pb parameter to convert() is deprecated")
2183
self.pb = ui.ui_factory.nested_progress_bar()
2185
ui.ui_factory.note('starting upgrade from format 4 to 5')
2186
if isinstance(self.bzrdir.transport, local.LocalTransport):
2187
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2188
self._convert_to_weaves()
2189
return BzrDir.open(self.bzrdir.user_url)
2193
def _convert_to_weaves(self):
2194
ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2197
stat = self.bzrdir.transport.stat('weaves')
2198
if not S_ISDIR(stat.st_mode):
2199
self.bzrdir.transport.delete('weaves')
2200
self.bzrdir.transport.mkdir('weaves')
2201
except errors.NoSuchFile:
2202
self.bzrdir.transport.mkdir('weaves')
2203
# deliberately not a WeaveFile as we want to build it up slowly.
2204
self.inv_weave = Weave('inventory')
2205
# holds in-memory weaves for all files
2206
self.text_weaves = {}
2207
self.bzrdir.transport.delete('branch-format')
2208
self.branch = self.bzrdir.open_branch()
2209
self._convert_working_inv()
2210
rev_history = self.branch.revision_history()
2211
# to_read is a stack holding the revisions we still need to process;
2212
# appending to it adds new highest-priority revisions
2213
self.known_revisions = set(rev_history)
2214
self.to_read = rev_history[-1:]
2216
rev_id = self.to_read.pop()
2217
if (rev_id not in self.revisions
2218
and rev_id not in self.absent_revisions):
2219
self._load_one_rev(rev_id)
2221
to_import = self._make_order()
2222
for i, rev_id in enumerate(to_import):
2223
self.pb.update('converting revision', i, len(to_import))
2224
self._convert_one_rev(rev_id)
2226
self._write_all_weaves()
2227
self._write_all_revs()
2228
ui.ui_factory.note('upgraded to weaves:')
2229
ui.ui_factory.note(' %6d revisions and inventories' % len(self.revisions))
2230
ui.ui_factory.note(' %6d revisions not present' % len(self.absent_revisions))
2231
ui.ui_factory.note(' %6d texts' % self.text_count)
2232
self._cleanup_spare_files_after_format4()
2233
self.branch._transport.put_bytes(
2235
BzrDirFormat5().get_format_string(),
2236
mode=self.bzrdir._get_file_mode())
2238
def _cleanup_spare_files_after_format4(self):
2239
# FIXME working tree upgrade foo.
2240
for n in 'merged-patches', 'pending-merged-patches':
2242
## assert os.path.getsize(p) == 0
2243
self.bzrdir.transport.delete(n)
2244
except errors.NoSuchFile:
2246
self.bzrdir.transport.delete_tree('inventory-store')
2247
self.bzrdir.transport.delete_tree('text-store')
2249
def _convert_working_inv(self):
2250
inv = xml4.serializer_v4.read_inventory(
2251
self.branch._transport.get('inventory'))
2252
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv, working=True)
2253
self.branch._transport.put_bytes('inventory', new_inv_xml,
2254
mode=self.bzrdir._get_file_mode())
2256
def _write_all_weaves(self):
2257
controlweaves = WeaveStore(self.bzrdir.transport, prefixed=False)
2258
weave_transport = self.bzrdir.transport.clone('weaves')
2259
weaves = WeaveStore(weave_transport, prefixed=False)
2260
transaction = WriteTransaction()
2264
for file_id, file_weave in self.text_weaves.items():
2265
self.pb.update('writing weave', i, len(self.text_weaves))
2266
weaves._put_weave(file_id, file_weave, transaction)
2268
self.pb.update('inventory', 0, 1)
2269
controlweaves._put_weave('inventory', self.inv_weave, transaction)
2270
self.pb.update('inventory', 1, 1)
2274
def _write_all_revs(self):
2275
"""Write all revisions out in new form."""
2276
self.bzrdir.transport.delete_tree('revision-store')
2277
self.bzrdir.transport.mkdir('revision-store')
2278
revision_transport = self.bzrdir.transport.clone('revision-store')
2280
from bzrlib.xml5 import serializer_v5
2281
from bzrlib.repofmt.weaverepo import RevisionTextStore
2282
revision_store = RevisionTextStore(revision_transport,
2283
serializer_v5, False, versionedfile.PrefixMapper(),
2284
lambda:True, lambda:True)
2286
for i, rev_id in enumerate(self.converted_revs):
2287
self.pb.update('write revision', i, len(self.converted_revs))
2288
text = serializer_v5.write_revision_to_string(
2289
self.revisions[rev_id])
2291
revision_store.add_lines(key, None, osutils.split_lines(text))
2295
def _load_one_rev(self, rev_id):
2296
"""Load a revision object into memory.
2298
Any parents not either loaded or abandoned get queued to be
2300
self.pb.update('loading revision',
2301
len(self.revisions),
2302
len(self.known_revisions))
2303
if not self.branch.repository.has_revision(rev_id):
2305
ui.ui_factory.note('revision {%s} not present in branch; '
2306
'will be converted as a ghost' %
2308
self.absent_revisions.add(rev_id)
2310
rev = self.branch.repository.get_revision(rev_id)
2311
for parent_id in rev.parent_ids:
2312
self.known_revisions.add(parent_id)
2313
self.to_read.append(parent_id)
2314
self.revisions[rev_id] = rev
2316
def _load_old_inventory(self, rev_id):
2317
f = self.branch.repository.inventory_store.get(rev_id)
2319
old_inv_xml = f.read()
2322
inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2323
inv.revision_id = rev_id
2324
rev = self.revisions[rev_id]
2327
def _load_updated_inventory(self, rev_id):
2328
inv_xml = self.inv_weave.get_text(rev_id)
2329
inv = xml5.serializer_v5.read_inventory_from_string(inv_xml, rev_id)
2332
def _convert_one_rev(self, rev_id):
2333
"""Convert revision and all referenced objects to new format."""
2334
rev = self.revisions[rev_id]
2335
inv = self._load_old_inventory(rev_id)
2336
present_parents = [p for p in rev.parent_ids
2337
if p not in self.absent_revisions]
2338
self._convert_revision_contents(rev, inv, present_parents)
2339
self._store_new_inv(rev, inv, present_parents)
2340
self.converted_revs.add(rev_id)
2342
def _store_new_inv(self, rev, inv, present_parents):
2343
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
2344
new_inv_sha1 = sha_string(new_inv_xml)
2345
self.inv_weave.add_lines(rev.revision_id,
2347
new_inv_xml.splitlines(True))
2348
rev.inventory_sha1 = new_inv_sha1
2350
def _convert_revision_contents(self, rev, inv, present_parents):
2351
"""Convert all the files within a revision.
2353
Also upgrade the inventory to refer to the text revision ids."""
2354
rev_id = rev.revision_id
2355
mutter('converting texts of revision {%s}',
2357
parent_invs = map(self._load_updated_inventory, present_parents)
2358
entries = inv.iter_entries()
2360
for path, ie in entries:
2361
self._convert_file_version(rev, ie, parent_invs)
2363
def _convert_file_version(self, rev, ie, parent_invs):
2364
"""Convert one version of one file.
2366
The file needs to be added into the weave if it is a merge
2367
of >=2 parents or if it's changed from its parent.
2369
file_id = ie.file_id
2370
rev_id = rev.revision_id
2371
w = self.text_weaves.get(file_id)
2374
self.text_weaves[file_id] = w
2375
text_changed = False
2376
parent_candiate_entries = ie.parent_candidates(parent_invs)
2377
heads = graph.Graph(self).heads(parent_candiate_entries.keys())
2378
# XXX: Note that this is unordered - and this is tolerable because
2379
# the previous code was also unordered.
2380
previous_entries = dict((head, parent_candiate_entries[head]) for head
2382
self.snapshot_ie(previous_entries, ie, w, rev_id)
2384
def get_parent_map(self, revision_ids):
2385
"""See graph.StackedParentsProvider.get_parent_map"""
2386
return dict((revision_id, self.revisions[revision_id])
2387
for revision_id in revision_ids
2388
if revision_id in self.revisions)
2390
def snapshot_ie(self, previous_revisions, ie, w, rev_id):
2391
# TODO: convert this logic, which is ~= snapshot to
2392
# a call to:. This needs the path figured out. rather than a work_tree
2393
# a v4 revision_tree can be given, or something that looks enough like
2394
# one to give the file content to the entry if it needs it.
2395
# and we need something that looks like a weave store for snapshot to
2397
#ie.snapshot(rev, PATH, previous_revisions, REVISION_TREE, InMemoryWeaveStore(self.text_weaves))
2398
if len(previous_revisions) == 1:
2399
previous_ie = previous_revisions.values()[0]
2400
if ie._unchanged(previous_ie):
2401
ie.revision = previous_ie.revision
2404
f = self.branch.repository._text_store.get(ie.text_id)
2406
file_lines = f.readlines()
2409
w.add_lines(rev_id, previous_revisions, file_lines)
2410
self.text_count += 1
2412
w.add_lines(rev_id, previous_revisions, [])
2413
ie.revision = rev_id
2415
def _make_order(self):
2416
"""Return a suitable order for importing revisions.
2418
The order must be such that an revision is imported after all
2419
its (present) parents.
2421
todo = set(self.revisions.keys())
2422
done = self.absent_revisions.copy()
2425
# scan through looking for a revision whose parents
2427
for rev_id in sorted(list(todo)):
2428
rev = self.revisions[rev_id]
2429
parent_ids = set(rev.parent_ids)
2430
if parent_ids.issubset(done):
2431
# can take this one now
2432
order.append(rev_id)
2438
class ConvertBzrDir5To6(Converter):
2439
"""Converts format 5 bzr dirs to format 6."""
2441
def convert(self, to_convert, pb):
2442
"""See Converter.convert()."""
2443
self.bzrdir = to_convert
2444
pb = ui.ui_factory.nested_progress_bar()
2446
ui.ui_factory.note('starting upgrade from format 5 to 6')
2447
self._convert_to_prefixed()
2448
return BzrDir.open(self.bzrdir.user_url)
2452
def _convert_to_prefixed(self):
2453
from bzrlib.store import TransportStore
2454
self.bzrdir.transport.delete('branch-format')
2455
for store_name in ["weaves", "revision-store"]:
2456
ui.ui_factory.note("adding prefixes to %s" % store_name)
2457
store_transport = self.bzrdir.transport.clone(store_name)
2458
store = TransportStore(store_transport, prefixed=True)
2459
for urlfilename in store_transport.list_dir('.'):
2460
filename = urlutils.unescape(urlfilename)
2461
if (filename.endswith(".weave") or
2462
filename.endswith(".gz") or
2463
filename.endswith(".sig")):
2464
file_id, suffix = os.path.splitext(filename)
2468
new_name = store._mapper.map((file_id,)) + suffix
2469
# FIXME keep track of the dirs made RBC 20060121
2471
store_transport.move(filename, new_name)
2472
except errors.NoSuchFile: # catches missing dirs strangely enough
2473
store_transport.mkdir(osutils.dirname(new_name))
2474
store_transport.move(filename, new_name)
2475
self.bzrdir.transport.put_bytes(
2477
BzrDirFormat6().get_format_string(),
2478
mode=self.bzrdir._get_file_mode())
2481
class ConvertBzrDir6ToMeta(Converter):
2482
"""Converts format 6 bzr dirs to metadirs."""
2484
def convert(self, to_convert, pb):
2485
"""See Converter.convert()."""
2486
from bzrlib.repofmt.weaverepo import RepositoryFormat7
2487
from bzrlib.branch import BzrBranchFormat5
2488
self.bzrdir = to_convert
2489
self.pb = ui.ui_factory.nested_progress_bar()
2491
self.total = 20 # the steps we know about
2492
self.garbage_inventories = []
2493
self.dir_mode = self.bzrdir._get_dir_mode()
2494
self.file_mode = self.bzrdir._get_file_mode()
2496
ui.ui_factory.note('starting upgrade from format 6 to metadir')
2497
self.bzrdir.transport.put_bytes(
2499
"Converting to format 6",
2500
mode=self.file_mode)
2501
# its faster to move specific files around than to open and use the apis...
2502
# first off, nuke ancestry.weave, it was never used.
2504
self.step('Removing ancestry.weave')
2505
self.bzrdir.transport.delete('ancestry.weave')
2506
except errors.NoSuchFile:
2508
# find out whats there
2509
self.step('Finding branch files')
2510
last_revision = self.bzrdir.open_branch().last_revision()
2511
bzrcontents = self.bzrdir.transport.list_dir('.')
2512
for name in bzrcontents:
2513
if name.startswith('basis-inventory.'):
2514
self.garbage_inventories.append(name)
2515
# create new directories for repository, working tree and branch
2516
repository_names = [('inventory.weave', True),
2517
('revision-store', True),
2519
self.step('Upgrading repository ')
2520
self.bzrdir.transport.mkdir('repository', mode=self.dir_mode)
2521
self.make_lock('repository')
2522
# we hard code the formats here because we are converting into
2523
# the meta format. The meta format upgrader can take this to a
2524
# future format within each component.
2525
self.put_format('repository', RepositoryFormat7())
2526
for entry in repository_names:
2527
self.move_entry('repository', entry)
2529
self.step('Upgrading branch ')
2530
self.bzrdir.transport.mkdir('branch', mode=self.dir_mode)
2531
self.make_lock('branch')
2532
self.put_format('branch', BzrBranchFormat5())
2533
branch_files = [('revision-history', True),
2534
('branch-name', True),
2536
for entry in branch_files:
2537
self.move_entry('branch', entry)
2539
checkout_files = [('pending-merges', True),
2540
('inventory', True),
2541
('stat-cache', False)]
2542
# If a mandatory checkout file is not present, the branch does not have
2543
# a functional checkout. Do not create a checkout in the converted
2545
for name, mandatory in checkout_files:
2546
if mandatory and name not in bzrcontents:
2547
has_checkout = False
2551
if not has_checkout:
2552
ui.ui_factory.note('No working tree.')
2553
# If some checkout files are there, we may as well get rid of them.
2554
for name, mandatory in checkout_files:
2555
if name in bzrcontents:
2556
self.bzrdir.transport.delete(name)
2558
from bzrlib.workingtree import WorkingTreeFormat3
2559
self.step('Upgrading working tree')
2560
self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
2561
self.make_lock('checkout')
2563
'checkout', WorkingTreeFormat3())
2564
self.bzrdir.transport.delete_multi(
2565
self.garbage_inventories, self.pb)
2566
for entry in checkout_files:
2567
self.move_entry('checkout', entry)
2568
if last_revision is not None:
2569
self.bzrdir.transport.put_bytes(
2570
'checkout/last-revision', last_revision)
2571
self.bzrdir.transport.put_bytes(
2573
BzrDirMetaFormat1().get_format_string(),
2574
mode=self.file_mode)
2576
return BzrDir.open(self.bzrdir.user_url)
2578
def make_lock(self, name):
2579
"""Make a lock for the new control dir name."""
2580
self.step('Make %s lock' % name)
2581
ld = lockdir.LockDir(self.bzrdir.transport,
2583
file_modebits=self.file_mode,
2584
dir_modebits=self.dir_mode)
2587
def move_entry(self, new_dir, entry):
2588
"""Move then entry name into new_dir."""
2590
mandatory = entry[1]
2591
self.step('Moving %s' % name)
2593
self.bzrdir.transport.move(name, '%s/%s' % (new_dir, name))
2594
except errors.NoSuchFile:
2598
def put_format(self, dirname, format):
2599
self.bzrdir.transport.put_bytes('%s/format' % dirname,
2600
format.get_format_string(),
2604
class ConvertMetaToMeta(Converter):
1827
BzrProber.formats.register(BzrDirMetaFormat1.get_format_string(),
1829
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1832
class ConvertMetaToMeta(controldir.Converter):
2605
1833
"""Converts the components of metadirs."""
2607
1835
def __init__(self, target_format):
2680
1907
return to_convert
2683
# This is not in remote.py because it's relatively small, and needs to be
2684
# registered. Putting it in remote.py creates a circular import problem.
2685
# we can make it a lazy object if the control formats is turned into something
2687
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2688
"""Format representing bzrdirs accessed via a smart server"""
2690
supports_workingtrees = False
2693
BzrDirMetaFormat1.__init__(self)
2694
# XXX: It's a bit ugly that the network name is here, because we'd
2695
# like to believe that format objects are stateless or at least
2696
# immutable, However, we do at least avoid mutating the name after
2697
# it's returned. See <https://bugs.launchpad.net/bzr/+bug/504102>
2698
self._network_name = None
2701
return "%s(_network_name=%r)" % (self.__class__.__name__,
2704
def get_format_description(self):
2705
if self._network_name:
2706
real_format = controldir.network_format_registry.get(self._network_name)
2707
return 'Remote: ' + real_format.get_format_description()
2708
return 'bzr remote bzrdir'
2710
def get_format_string(self):
2711
raise NotImplementedError(self.get_format_string)
2713
def network_name(self):
2714
if self._network_name:
2715
return self._network_name
2717
raise AssertionError("No network name set.")
2719
def initialize_on_transport(self, transport):
2721
# hand off the request to the smart server
2722
client_medium = transport.get_smart_medium()
2723
except errors.NoSmartMedium:
2724
# TODO: lookup the local format from a server hint.
2725
local_dir_format = BzrDirMetaFormat1()
2726
return local_dir_format.initialize_on_transport(transport)
2727
client = _SmartClient(client_medium)
2728
path = client.remote_path_from_transport(transport)
2730
response = client.call('BzrDirFormat.initialize', path)
2731
except errors.ErrorFromSmartServer, err:
2732
remote._translate_error(err, path=path)
2733
if response[0] != 'ok':
2734
raise errors.SmartProtocolError('unexpected response code %s' % (response,))
2735
format = RemoteBzrDirFormat()
2736
self._supply_sub_formats_to(format)
2737
return remote.RemoteBzrDir(transport, format)
2739
def parse_NoneTrueFalse(self, arg):
2746
raise AssertionError("invalid arg %r" % arg)
2748
def _serialize_NoneTrueFalse(self, arg):
2755
def _serialize_NoneString(self, arg):
2758
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
2759
create_prefix=False, force_new_repo=False, stacked_on=None,
2760
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
2763
# hand off the request to the smart server
2764
client_medium = transport.get_smart_medium()
2765
except errors.NoSmartMedium:
2768
# Decline to open it if the server doesn't support our required
2769
# version (3) so that the VFS-based transport will do it.
2770
if client_medium.should_probe():
2772
server_version = client_medium.protocol_version()
2773
if server_version != '2':
2777
except errors.SmartProtocolError:
2778
# Apparently there's no usable smart server there, even though
2779
# the medium supports the smart protocol.
2784
client = _SmartClient(client_medium)
2785
path = client.remote_path_from_transport(transport)
2786
if client_medium._is_remote_before((1, 16)):
2789
# TODO: lookup the local format from a server hint.
2790
local_dir_format = BzrDirMetaFormat1()
2791
self._supply_sub_formats_to(local_dir_format)
2792
return local_dir_format.initialize_on_transport_ex(transport,
2793
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2794
force_new_repo=force_new_repo, stacked_on=stacked_on,
2795
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2796
make_working_trees=make_working_trees, shared_repo=shared_repo,
2798
return self._initialize_on_transport_ex_rpc(client, path, transport,
2799
use_existing_dir, create_prefix, force_new_repo, stacked_on,
2800
stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
2802
def _initialize_on_transport_ex_rpc(self, client, path, transport,
2803
use_existing_dir, create_prefix, force_new_repo, stacked_on,
2804
stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
2806
args.append(self._serialize_NoneTrueFalse(use_existing_dir))
2807
args.append(self._serialize_NoneTrueFalse(create_prefix))
2808
args.append(self._serialize_NoneTrueFalse(force_new_repo))
2809
args.append(self._serialize_NoneString(stacked_on))
2810
# stack_on_pwd is often/usually our transport
2813
stack_on_pwd = transport.relpath(stack_on_pwd)
2814
if not stack_on_pwd:
2816
except errors.PathNotChild:
2818
args.append(self._serialize_NoneString(stack_on_pwd))
2819
args.append(self._serialize_NoneString(repo_format_name))
2820
args.append(self._serialize_NoneTrueFalse(make_working_trees))
2821
args.append(self._serialize_NoneTrueFalse(shared_repo))
2822
request_network_name = self._network_name or \
2823
BzrDirFormat.get_default_format().network_name()
2825
response = client.call('BzrDirFormat.initialize_ex_1.16',
2826
request_network_name, path, *args)
2827
except errors.UnknownSmartMethod:
2828
client._medium._remember_remote_is_before((1,16))
2829
local_dir_format = BzrDirMetaFormat1()
2830
self._supply_sub_formats_to(local_dir_format)
2831
return local_dir_format.initialize_on_transport_ex(transport,
2832
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2833
force_new_repo=force_new_repo, stacked_on=stacked_on,
2834
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2835
make_working_trees=make_working_trees, shared_repo=shared_repo,
2837
except errors.ErrorFromSmartServer, err:
2838
remote._translate_error(err, path=path)
2839
repo_path = response[0]
2840
bzrdir_name = response[6]
2841
require_stacking = response[7]
2842
require_stacking = self.parse_NoneTrueFalse(require_stacking)
2843
format = RemoteBzrDirFormat()
2844
format._network_name = bzrdir_name
2845
self._supply_sub_formats_to(format)
2846
bzrdir = remote.RemoteBzrDir(transport, format, _client=client)
2848
repo_format = remote.response_tuple_to_repo_format(response[1:])
2849
if repo_path == '.':
2852
repo_bzrdir_format = RemoteBzrDirFormat()
2853
repo_bzrdir_format._network_name = response[5]
2854
repo_bzr = remote.RemoteBzrDir(transport.clone(repo_path),
2858
final_stack = response[8] or None
2859
final_stack_pwd = response[9] or None
2861
final_stack_pwd = urlutils.join(
2862
transport.base, final_stack_pwd)
2863
remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
2864
if len(response) > 10:
2865
# Updated server verb that locks remotely.
2866
repo_lock_token = response[10] or None
2867
remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
2869
remote_repo.dont_leave_lock_in_place()
2871
remote_repo.lock_write()
2872
policy = UseExistingRepository(remote_repo, final_stack,
2873
final_stack_pwd, require_stacking)
2874
policy.acquire_repository()
2878
bzrdir._format.set_branch_format(self.get_branch_format())
2879
if require_stacking:
2880
# The repo has already been created, but we need to make sure that
2881
# we'll make a stackable branch.
2882
bzrdir._format.require_stacking(_skip_repo=True)
2883
return remote_repo, bzrdir, require_stacking, policy
2885
def _open(self, transport):
2886
return remote.RemoteBzrDir(transport, self)
2888
def __eq__(self, other):
2889
if not isinstance(other, RemoteBzrDirFormat):
2891
return self.get_format_description() == other.get_format_description()
2893
def __return_repository_format(self):
2894
# Always return a RemoteRepositoryFormat object, but if a specific bzr
2895
# repository format has been asked for, tell the RemoteRepositoryFormat
2896
# that it should use that for init() etc.
2897
result = remote.RemoteRepositoryFormat()
2898
custom_format = getattr(self, '_repository_format', None)
2900
if isinstance(custom_format, remote.RemoteRepositoryFormat):
2901
return custom_format
2903
# We will use the custom format to create repositories over the
2904
# wire; expose its details like rich_root_data for code to
2906
result._custom_format = custom_format
2909
def get_branch_format(self):
2910
result = BzrDirMetaFormat1.get_branch_format(self)
2911
if not isinstance(result, remote.RemoteBranchFormat):
2912
new_result = remote.RemoteBranchFormat()
2913
new_result._custom_format = result
2915
self.set_branch_format(new_result)
2919
repository_format = property(__return_repository_format,
2920
BzrDirMetaFormat1._set_repository_format) #.im_func)
2923
1910
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
3179
2150
'network operations. Additionally adds support for versioning nested '
3180
2151
'bzr branches. Incompatible with bzr < 0.15.',
3181
2152
branch_format='bzrlib.branch.BzrBranchFormat6',
3182
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2153
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3183
2154
experimental=True,
3186
2157
register_metadir(controldir.format_registry, 'pack-0.92',
3187
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
2158
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
3188
2159
help='New in 0.92: Pack-based format with data compatible with '
3189
2160
'dirstate-tags format repositories. Interoperates with '
3190
2161
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3192
2163
branch_format='bzrlib.branch.BzrBranchFormat6',
3193
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2164
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3195
2166
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
3196
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
2167
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
3197
2168
help='New in 0.92: Pack-based format with data compatible with '
3198
2169
'dirstate-with-subtree format repositories. Interoperates with '
3199
2170
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
3201
2172
branch_format='bzrlib.branch.BzrBranchFormat6',
3202
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2173
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3204
2175
experimental=True,
3206
2177
register_metadir(controldir.format_registry, 'rich-root-pack',
3207
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
2178
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
3208
2179
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
3209
2180
'(needed for bzr-svn and bzr-git).',
3210
2181
branch_format='bzrlib.branch.BzrBranchFormat6',
3211
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2182
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3214
2185
register_metadir(controldir.format_registry, '1.6',
3215
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
2186
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
3216
2187
help='A format that allows a branch to indicate that there is another '
3217
2188
'(stacked) repository that should be used to access data that is '
3218
2189
'not present locally.',
3219
2190
branch_format='bzrlib.branch.BzrBranchFormat7',
3220
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2191
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3223
2194
register_metadir(controldir.format_registry, '1.6.1-rich-root',
3224
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
2195
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
3225
2196
help='A variant of 1.6 that supports rich-root data '
3226
2197
'(needed for bzr-svn and bzr-git).',
3227
2198
branch_format='bzrlib.branch.BzrBranchFormat7',
3228
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2199
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3231
2202
register_metadir(controldir.format_registry, '1.9',
3232
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
2203
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
3233
2204
help='A repository format using B+tree indexes. These indexes '
3234
2205
'are smaller in size, have smarter caching and provide faster '
3235
2206
'performance for most operations.',
3236
2207
branch_format='bzrlib.branch.BzrBranchFormat7',
3237
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2208
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3240
2211
register_metadir(controldir.format_registry, '1.9-rich-root',
3241
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
2212
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
3242
2213
help='A variant of 1.9 that supports rich-root data '
3243
2214
'(needed for bzr-svn and bzr-git).',
3244
2215
branch_format='bzrlib.branch.BzrBranchFormat7',
3245
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2216
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3248
2219
register_metadir(controldir.format_registry, '1.14',
3249
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
2220
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
3250
2221
help='A working-tree format that supports content filtering.',
3251
2222
branch_format='bzrlib.branch.BzrBranchFormat7',
3252
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2223
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
3254
2225
register_metadir(controldir.format_registry, '1.14-rich-root',
3255
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
2226
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
3256
2227
help='A variant of 1.14 that supports rich-root data '
3257
2228
'(needed for bzr-svn and bzr-git).',
3258
2229
branch_format='bzrlib.branch.BzrBranchFormat7',
3259
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2230
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
3261
2232
# The following un-numbered 'development' formats should always just be aliases.
3262
2233
register_metadir(controldir.format_registry, 'development-subtree',