390
438
policy = self.determine_repository_policy(force_new_repo)
391
439
return policy.acquire_repository()[0]
393
def _find_source_repo(self, add_cleanup, source_branch):
394
"""Find the source branch and repo for a sprout operation.
396
This is helper intended for use by _sprout.
398
:returns: (source_branch, source_repository). Either or both may be
399
None. If not None, they will be read-locked (and their unlock(s)
400
scheduled via the add_cleanup param).
402
if source_branch is not None:
403
add_cleanup(source_branch.lock_read().unlock)
404
return source_branch, source_branch.repository
406
source_branch = self.open_branch()
407
source_repository = source_branch.repository
408
except errors.NotBranchError:
411
source_repository = self.open_repository()
412
except errors.NoRepositoryPresent:
413
source_repository = None
415
add_cleanup(source_repository.lock_read().unlock)
417
add_cleanup(source_branch.lock_read().unlock)
418
return source_branch, source_repository
420
def sprout(self, url, revision_id=None, force_new_repo=False,
421
recurse='down', possible_transports=None,
422
accelerator_tree=None, hardlink=False, stacked=False,
423
source_branch=None, create_tree_if_local=True):
424
"""Create a copy of this controldir prepared for use as a new line of
427
If url's last component does not exist, it will be created.
429
Attributes related to the identity of the source branch like
430
branch nickname will be cleaned, a working tree is created
431
whether one existed before or not; and a local branch is always
434
if revision_id is not None, then the clone operation may tune
435
itself to download less data.
437
:param accelerator_tree: A tree which can be used for retrieving file
438
contents more quickly than the revision tree, i.e. a workingtree.
439
The revision tree will be used for cases where accelerator_tree's
440
content is different.
441
:param hardlink: If true, hard-link files from accelerator_tree,
443
:param stacked: If true, create a stacked branch referring to the
444
location of this control directory.
445
:param create_tree_if_local: If true, a working-tree will be created
446
when working locally.
448
operation = cleanup.OperationWithCleanups(self._sprout)
449
return operation.run(url, revision_id=revision_id,
450
force_new_repo=force_new_repo, recurse=recurse,
451
possible_transports=possible_transports,
452
accelerator_tree=accelerator_tree, hardlink=hardlink,
453
stacked=stacked, source_branch=source_branch,
454
create_tree_if_local=create_tree_if_local)
456
def _sprout(self, op, url, revision_id=None, force_new_repo=False,
457
recurse='down', possible_transports=None,
458
accelerator_tree=None, hardlink=False, stacked=False,
459
source_branch=None, create_tree_if_local=True):
460
add_cleanup = op.add_cleanup
461
fetch_spec_factory = fetch.FetchSpecFactory()
462
if revision_id is not None:
463
fetch_spec_factory.add_revision_ids([revision_id])
464
fetch_spec_factory.source_branch_stop_revision_id = revision_id
465
target_transport = _mod_transport.get_transport(url,
467
target_transport.ensure_base()
468
cloning_format = self.cloning_metadir(stacked)
469
# Create/update the result branch
470
result = cloning_format.initialize_on_transport(target_transport)
471
source_branch, source_repository = self._find_source_repo(
472
add_cleanup, source_branch)
473
fetch_spec_factory.source_branch = source_branch
474
# if a stacked branch wasn't requested, we don't create one
475
# even if the origin was stacked
476
if stacked and source_branch is not None:
477
stacked_branch_url = self.root_transport.base
479
stacked_branch_url = None
480
repository_policy = result.determine_repository_policy(
481
force_new_repo, stacked_branch_url, require_stacking=stacked)
482
result_repo, is_new_repo = repository_policy.acquire_repository()
483
add_cleanup(result_repo.lock_write().unlock)
484
fetch_spec_factory.source_repo = source_repository
485
fetch_spec_factory.target_repo = result_repo
486
if stacked or (len(result_repo._fallback_repositories) != 0):
487
target_repo_kind = fetch.TargetRepoKinds.STACKED
489
target_repo_kind = fetch.TargetRepoKinds.EMPTY
491
target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
492
fetch_spec_factory.target_repo_kind = target_repo_kind
493
if source_repository is not None:
494
fetch_spec = fetch_spec_factory.make_fetch_spec()
495
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
497
if source_branch is None:
498
# this is for sprouting a controldir without a branch; is that
500
# Not especially, but it's part of the contract.
501
result_branch = result.create_branch()
503
result_branch = source_branch.sprout(result,
504
revision_id=revision_id, repository_policy=repository_policy,
505
repository=result_repo)
506
mutter("created new branch %r" % (result_branch,))
508
# Create/update the result working tree
509
if (create_tree_if_local and
510
isinstance(target_transport, local.LocalTransport) and
511
(result_repo is None or result_repo.make_working_trees())):
512
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
513
hardlink=hardlink, from_branch=result_branch)
516
if wt.path2id('') is None:
518
wt.set_root_id(self.open_workingtree.get_root_id())
519
except errors.NoWorkingTree:
525
if recurse == 'down':
528
basis = wt.basis_tree()
529
elif result_branch is not None:
530
basis = result_branch.basis_tree()
531
elif source_branch is not None:
532
basis = source_branch.basis_tree()
533
if basis is not None:
534
add_cleanup(basis.lock_read().unlock)
535
subtrees = basis.iter_references()
538
for path, file_id in subtrees:
539
target = urlutils.join(url, urlutils.escape(path))
540
sublocation = source_branch.reference_parent(file_id, path)
541
sublocation.bzrdir.sprout(target,
542
basis.get_reference_revision(file_id, path),
543
force_new_repo=force_new_repo, recurse=recurse,
548
442
def create_branch_convenience(base, force_new_repo=False,
549
443
force_new_tree=None, format=None,
989
class BzrDirPreSplitOut(BzrDir):
990
"""A common class for the all-in-one formats."""
992
def __init__(self, _transport, _format):
993
"""See BzrDir.__init__."""
994
super(BzrDirPreSplitOut, self).__init__(_transport, _format)
995
self._control_files = lockable_files.LockableFiles(
996
self.get_branch_transport(None),
997
self._format._lock_file_name,
998
self._format._lock_class)
1000
def break_lock(self):
1001
"""Pre-splitout bzrdirs do not suffer from stale locks."""
1002
raise NotImplementedError(self.break_lock)
1004
def cloning_metadir(self, require_stacking=False):
1005
"""Produce a metadir suitable for cloning with."""
1006
if require_stacking:
1007
return controldir.format_registry.make_bzrdir('1.6')
1008
return self._format.__class__()
1010
def clone(self, url, revision_id=None, force_new_repo=False,
1011
preserve_stacking=False):
1012
"""See BzrDir.clone().
1014
force_new_repo has no effect, since this family of formats always
1015
require a new repository.
1016
preserve_stacking has no effect, since no source branch using this
1017
family of formats can be stacked, so there is no stacking to preserve.
1019
self._make_tail(url)
1020
result = self._format._initialize_for_clone(url)
1021
self.open_repository().clone(result, revision_id=revision_id)
1022
from_branch = self.open_branch()
1023
from_branch.clone(result, revision_id=revision_id)
1025
tree = self.open_workingtree()
1026
except errors.NotLocalUrl:
1027
# make a new one, this format always has to have one.
1028
result._init_workingtree()
1033
def create_branch(self, name=None, repository=None):
1034
"""See BzrDir.create_branch."""
1035
if repository is not None:
1036
raise NotImplementedError(
1037
"create_branch(repository=<not None>) on %r" % (self,))
1038
return self._format.get_branch_format().initialize(self, name=name)
1040
def destroy_branch(self, name=None):
1041
"""See BzrDir.destroy_branch."""
1042
raise errors.UnsupportedOperation(self.destroy_branch, self)
1044
def create_repository(self, shared=False):
1045
"""See BzrDir.create_repository."""
1047
raise errors.IncompatibleFormat('shared repository', self._format)
1048
return self.open_repository()
1050
def destroy_repository(self):
1051
"""See BzrDir.destroy_repository."""
1052
raise errors.UnsupportedOperation(self.destroy_repository, self)
1054
def create_workingtree(self, revision_id=None, from_branch=None,
1055
accelerator_tree=None, hardlink=False):
1056
"""See BzrDir.create_workingtree."""
1057
# The workingtree is sometimes created when the bzrdir is created,
1058
# but not when cloning.
1060
# this looks buggy but is not -really-
1061
# because this format creates the workingtree when the bzrdir is
1063
# clone and sprout will have set the revision_id
1064
# and that will have set it for us, its only
1065
# specific uses of create_workingtree in isolation
1066
# that can do wonky stuff here, and that only
1067
# happens for creating checkouts, which cannot be
1068
# done on this format anyway. So - acceptable wart.
1070
warning("can't support hardlinked working trees in %r"
1073
result = self.open_workingtree(recommend_upgrade=False)
1074
except errors.NoSuchFile:
1075
result = self._init_workingtree()
1076
if revision_id is not None:
1077
if revision_id == _mod_revision.NULL_REVISION:
1078
result.set_parent_ids([])
1080
result.set_parent_ids([revision_id])
1083
def _init_workingtree(self):
1084
from bzrlib.workingtree import WorkingTreeFormat2
1086
return WorkingTreeFormat2().initialize(self)
1087
except errors.NotLocalUrl:
1088
# Even though we can't access the working tree, we need to
1089
# create its control files.
1090
return WorkingTreeFormat2()._stub_initialize_on_transport(
1091
self.transport, self._control_files._file_mode)
1093
def destroy_workingtree(self):
1094
"""See BzrDir.destroy_workingtree."""
1095
raise errors.UnsupportedOperation(self.destroy_workingtree, self)
1097
def destroy_workingtree_metadata(self):
1098
"""See BzrDir.destroy_workingtree_metadata."""
1099
raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1102
def get_branch_transport(self, branch_format, name=None):
1103
"""See BzrDir.get_branch_transport()."""
1104
if name is not None:
1105
raise errors.NoColocatedBranchSupport(self)
1106
if branch_format is None:
1107
return self.transport
1109
branch_format.get_format_string()
1110
except NotImplementedError:
1111
return self.transport
1112
raise errors.IncompatibleFormat(branch_format, self._format)
1114
def get_repository_transport(self, repository_format):
1115
"""See BzrDir.get_repository_transport()."""
1116
if repository_format is None:
1117
return self.transport
1119
repository_format.get_format_string()
1120
except NotImplementedError:
1121
return self.transport
1122
raise errors.IncompatibleFormat(repository_format, self._format)
1124
def get_workingtree_transport(self, workingtree_format):
1125
"""See BzrDir.get_workingtree_transport()."""
1126
if workingtree_format is None:
1127
return self.transport
1129
workingtree_format.get_format_string()
1130
except NotImplementedError:
1131
return self.transport
1132
raise errors.IncompatibleFormat(workingtree_format, self._format)
1134
def needs_format_conversion(self, format=None):
1135
"""See BzrDir.needs_format_conversion()."""
1136
# if the format is not the same as the system default,
1137
# an upgrade is needed.
1139
symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
1140
% 'needs_format_conversion(format=None)')
1141
format = BzrDirFormat.get_default_format()
1142
return not isinstance(self._format, format.__class__)
1144
def open_branch(self, name=None, unsupported=False,
1145
ignore_fallbacks=False):
1146
"""See BzrDir.open_branch."""
1147
from bzrlib.branch import BzrBranchFormat4
1148
format = BzrBranchFormat4()
1149
self._check_supported(format, unsupported)
1150
return format.open(self, name, _found=True)
1152
def sprout(self, url, revision_id=None, force_new_repo=False,
1153
possible_transports=None, accelerator_tree=None,
1154
hardlink=False, stacked=False, create_tree_if_local=True,
1155
source_branch=None):
1156
"""See BzrDir.sprout()."""
1157
if source_branch is not None:
1158
my_branch = self.open_branch()
1159
if source_branch.base != my_branch.base:
1160
raise AssertionError(
1161
"source branch %r is not within %r with branch %r" %
1162
(source_branch, self, my_branch))
1164
raise errors.UnstackableBranchFormat(
1165
self._format, self.root_transport.base)
1166
if not create_tree_if_local:
1167
raise errors.MustHaveWorkingTree(
1168
self._format, self.root_transport.base)
1169
from bzrlib.workingtree import WorkingTreeFormat2
1170
self._make_tail(url)
1171
result = self._format._initialize_for_clone(url)
1173
self.open_repository().clone(result, revision_id=revision_id)
1174
except errors.NoRepositoryPresent:
1177
self.open_branch().sprout(result, revision_id=revision_id)
1178
except errors.NotBranchError:
1181
# we always want a working tree
1182
WorkingTreeFormat2().initialize(result,
1183
accelerator_tree=accelerator_tree,
1188
class BzrDir4(BzrDirPreSplitOut):
1189
"""A .bzr version 4 control object.
1191
This is a deprecated format and may be removed after sept 2006.
1194
def create_repository(self, shared=False):
1195
"""See BzrDir.create_repository."""
1196
return self._format.repository_format.initialize(self, shared)
1198
def needs_format_conversion(self, format=None):
1199
"""Format 4 dirs are always in need of conversion."""
1201
symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
1202
% 'needs_format_conversion(format=None)')
1205
def open_repository(self):
1206
"""See BzrDir.open_repository."""
1207
from bzrlib.repofmt.weaverepo import RepositoryFormat4
1208
return RepositoryFormat4().open(self, _found=True)
1211
class BzrDir5(BzrDirPreSplitOut):
1212
"""A .bzr version 5 control object.
1214
This is a deprecated format and may be removed after sept 2006.
1217
def has_workingtree(self):
1218
"""See BzrDir.has_workingtree."""
1221
def open_repository(self):
1222
"""See BzrDir.open_repository."""
1223
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1224
return RepositoryFormat5().open(self, _found=True)
1226
def open_workingtree(self, _unsupported=False,
1227
recommend_upgrade=True):
1228
"""See BzrDir.create_workingtree."""
1229
from bzrlib.workingtree import WorkingTreeFormat2
1230
wt_format = WorkingTreeFormat2()
1231
# we don't warn here about upgrades; that ought to be handled for the
1233
return wt_format.open(self, _found=True)
1236
class BzrDir6(BzrDirPreSplitOut):
1237
"""A .bzr version 6 control object.
1239
This is a deprecated format and may be removed after sept 2006.
1242
def has_workingtree(self):
1243
"""See BzrDir.has_workingtree."""
1246
def open_repository(self):
1247
"""See BzrDir.open_repository."""
1248
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1249
return RepositoryFormat6().open(self, _found=True)
1251
def open_workingtree(self, _unsupported=False,
1252
recommend_upgrade=True):
1253
"""See BzrDir.create_workingtree."""
1254
# we don't warn here about upgrades; that ought to be handled for the
1256
from bzrlib.workingtree import WorkingTreeFormat2
1257
return WorkingTreeFormat2().open(self, _found=True)
1136
1260
class BzrDirMeta1(BzrDir):
1137
1261
"""A .bzr meta version 1 control object.
1733
def unregister_format(klass, format):
1734
BzrProber.unregister_bzrdir_format(format)
1735
controldir.ControlDirFormat.unregister_format(format)
1736
controldir.network_format_registry.remove(format.get_format_string())
1739
class BzrDirFormat4(BzrDirFormat):
1740
"""Bzr dir format 4.
1742
This format is a combined format for working tree, branch and repository.
1744
- Format 1 working trees [always]
1745
- Format 4 branches [always]
1746
- Format 4 repositories [always]
1748
This format is deprecated: it indexes texts using a text it which is
1749
removed in format 5; write support for this format has been removed.
1752
_lock_class = lockable_files.TransportLock
1754
def get_format_string(self):
1755
"""See BzrDirFormat.get_format_string()."""
1756
return "Bazaar-NG branch, format 0.0.4\n"
1758
def get_format_description(self):
1759
"""See BzrDirFormat.get_format_description()."""
1760
return "All-in-one format 4"
1762
def get_converter(self, format=None):
1763
"""See BzrDirFormat.get_converter()."""
1764
# there is one and only one upgrade path here.
1765
return ConvertBzrDir4To5()
1767
def initialize_on_transport(self, transport):
1768
"""Format 4 branches cannot be created."""
1769
raise errors.UninitializableFormat(self)
1771
def is_supported(self):
1772
"""Format 4 is not supported.
1774
It is not supported because the model changed from 4 to 5 and the
1775
conversion logic is expensive - so doing it on the fly was not
1780
def network_name(self):
1781
return self.get_format_string()
1783
def _open(self, transport):
1784
"""See BzrDirFormat._open."""
1785
return BzrDir4(transport, self)
1787
def __return_repository_format(self):
1788
"""Circular import protection."""
1789
from bzrlib.repofmt.weaverepo import RepositoryFormat4
1790
return RepositoryFormat4()
1791
repository_format = property(__return_repository_format)
1794
class BzrDirFormatAllInOne(BzrDirFormat):
1795
"""Common class for formats before meta-dirs."""
1797
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1798
create_prefix=False, force_new_repo=False, stacked_on=None,
1799
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1801
"""See BzrDirFormat.initialize_on_transport_ex."""
1802
require_stacking = (stacked_on is not None)
1803
# Format 5 cannot stack, but we've been asked to - actually init
1805
if require_stacking:
1806
format = BzrDirMetaFormat1()
1807
return format.initialize_on_transport_ex(transport,
1808
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1809
force_new_repo=force_new_repo, stacked_on=stacked_on,
1810
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1811
make_working_trees=make_working_trees, shared_repo=shared_repo)
1812
return BzrDirFormat.initialize_on_transport_ex(self, transport,
1813
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1814
force_new_repo=force_new_repo, stacked_on=stacked_on,
1815
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1816
make_working_trees=make_working_trees, shared_repo=shared_repo)
1819
class BzrDirFormat5(BzrDirFormatAllInOne):
1820
"""Bzr control format 5.
1822
This format is a combined format for working tree, branch and repository.
1824
- Format 2 working trees [always]
1825
- Format 4 branches [always]
1826
- Format 5 repositories [always]
1827
Unhashed stores in the repository.
1830
_lock_class = lockable_files.TransportLock
1832
def get_format_string(self):
1833
"""See BzrDirFormat.get_format_string()."""
1834
return "Bazaar-NG branch, format 5\n"
1836
def get_branch_format(self):
1837
from bzrlib import branch
1838
return branch.BzrBranchFormat4()
1840
def get_format_description(self):
1841
"""See BzrDirFormat.get_format_description()."""
1842
return "All-in-one format 5"
1844
def get_converter(self, format=None):
1845
"""See BzrDirFormat.get_converter()."""
1846
# there is one and only one upgrade path here.
1847
return ConvertBzrDir5To6()
1849
def _initialize_for_clone(self, url):
1850
return self.initialize_on_transport(
1851
_mod_transport.get_transport(url), _cloning=True)
1853
def initialize_on_transport(self, transport, _cloning=False):
1854
"""Format 5 dirs always have working tree, branch and repository.
1856
Except when they are being cloned.
1858
from bzrlib.branch import BzrBranchFormat4
1859
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1860
result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
1861
RepositoryFormat5().initialize(result, _internal=True)
1863
branch = BzrBranchFormat4().initialize(result)
1864
result._init_workingtree()
1867
def network_name(self):
1868
return self.get_format_string()
1870
def _open(self, transport):
1871
"""See BzrDirFormat._open."""
1872
return BzrDir5(transport, self)
1874
def __return_repository_format(self):
1875
"""Circular import protection."""
1876
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1877
return RepositoryFormat5()
1878
repository_format = property(__return_repository_format)
1881
class BzrDirFormat6(BzrDirFormatAllInOne):
1882
"""Bzr control format 6.
1884
This format is a combined format for working tree, branch and repository.
1886
- Format 2 working trees [always]
1887
- Format 4 branches [always]
1888
- Format 6 repositories [always]
1891
_lock_class = lockable_files.TransportLock
1893
def get_format_string(self):
1894
"""See BzrDirFormat.get_format_string()."""
1895
return "Bazaar-NG branch, format 6\n"
1897
def get_format_description(self):
1898
"""See BzrDirFormat.get_format_description()."""
1899
return "All-in-one format 6"
1901
def get_branch_format(self):
1902
from bzrlib import branch
1903
return branch.BzrBranchFormat4()
1905
def get_converter(self, format=None):
1906
"""See BzrDirFormat.get_converter()."""
1907
# there is one and only one upgrade path here.
1908
return ConvertBzrDir6ToMeta()
1910
def _initialize_for_clone(self, url):
1911
return self.initialize_on_transport(
1912
_mod_transport.get_transport(url), _cloning=True)
1914
def initialize_on_transport(self, transport, _cloning=False):
1915
"""Format 6 dirs always have working tree, branch and repository.
1917
Except when they are being cloned.
1919
from bzrlib.branch import BzrBranchFormat4
1920
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1921
result = super(BzrDirFormat6, self).initialize_on_transport(transport)
1922
RepositoryFormat6().initialize(result, _internal=True)
1924
branch = BzrBranchFormat4().initialize(result)
1925
result._init_workingtree()
1928
def network_name(self):
1929
return self.get_format_string()
1931
def _open(self, transport):
1932
"""See BzrDirFormat._open."""
1933
return BzrDir6(transport, self)
1935
def __return_repository_format(self):
1936
"""Circular import protection."""
1937
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1938
return RepositoryFormat6()
1939
repository_format = property(__return_repository_format)
1615
1942
class BzrDirMetaFormat1(BzrDirFormat):
1616
1943
"""Bzr meta control format 1
1618
1945
This is the first format with split out working tree, branch and repository
1623
- Format 3 working trees [optional]
1624
- Format 5 branches [optional]
1625
- Format 7 repositories [optional]
1948
- Format 3 working trees [optional]
1949
- Format 5 branches [optional]
1950
- Format 7 repositories [optional]
1628
1953
_lock_class = lockdir.LockDir
1630
fixed_components = False
1632
1955
def __init__(self):
1633
1956
self._workingtree_format = None
1634
1957
self._branch_format = None
1828
2147
# Register bzr formats
1829
BzrProber.formats.register(BzrDirMetaFormat1.get_format_string(),
1831
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1834
class ConvertMetaToMeta(controldir.Converter):
2148
BzrDirFormat.register_format(BzrDirFormat4())
2149
BzrDirFormat.register_format(BzrDirFormat5())
2150
BzrDirFormat.register_format(BzrDirFormat6())
2151
__default_format = BzrDirMetaFormat1()
2152
BzrDirFormat.register_format(__default_format)
2153
controldir.ControlDirFormat._default_format = __default_format
2156
class Converter(object):
2157
"""Converts a disk format object from one format to another."""
2159
def convert(self, to_convert, pb):
2160
"""Perform the conversion of to_convert, giving feedback via pb.
2162
:param to_convert: The disk object to convert.
2163
:param pb: a progress bar to use for progress information.
2166
def step(self, message):
2167
"""Update the pb by a step."""
2169
self.pb.update(message, self.count, self.total)
2172
class ConvertBzrDir4To5(Converter):
2173
"""Converts format 4 bzr dirs to format 5."""
2176
super(ConvertBzrDir4To5, self).__init__()
2177
self.converted_revs = set()
2178
self.absent_revisions = set()
2182
def convert(self, to_convert, pb):
2183
"""See Converter.convert()."""
2184
self.bzrdir = to_convert
2186
warnings.warn("pb parameter to convert() is deprecated")
2187
self.pb = ui.ui_factory.nested_progress_bar()
2189
ui.ui_factory.note('starting upgrade from format 4 to 5')
2190
if isinstance(self.bzrdir.transport, local.LocalTransport):
2191
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2192
self._convert_to_weaves()
2193
return BzrDir.open(self.bzrdir.user_url)
2197
def _convert_to_weaves(self):
2198
ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2201
stat = self.bzrdir.transport.stat('weaves')
2202
if not S_ISDIR(stat.st_mode):
2203
self.bzrdir.transport.delete('weaves')
2204
self.bzrdir.transport.mkdir('weaves')
2205
except errors.NoSuchFile:
2206
self.bzrdir.transport.mkdir('weaves')
2207
# deliberately not a WeaveFile as we want to build it up slowly.
2208
self.inv_weave = Weave('inventory')
2209
# holds in-memory weaves for all files
2210
self.text_weaves = {}
2211
self.bzrdir.transport.delete('branch-format')
2212
self.branch = self.bzrdir.open_branch()
2213
self._convert_working_inv()
2214
rev_history = self.branch.revision_history()
2215
# to_read is a stack holding the revisions we still need to process;
2216
# appending to it adds new highest-priority revisions
2217
self.known_revisions = set(rev_history)
2218
self.to_read = rev_history[-1:]
2220
rev_id = self.to_read.pop()
2221
if (rev_id not in self.revisions
2222
and rev_id not in self.absent_revisions):
2223
self._load_one_rev(rev_id)
2225
to_import = self._make_order()
2226
for i, rev_id in enumerate(to_import):
2227
self.pb.update('converting revision', i, len(to_import))
2228
self._convert_one_rev(rev_id)
2230
self._write_all_weaves()
2231
self._write_all_revs()
2232
ui.ui_factory.note('upgraded to weaves:')
2233
ui.ui_factory.note(' %6d revisions and inventories' % len(self.revisions))
2234
ui.ui_factory.note(' %6d revisions not present' % len(self.absent_revisions))
2235
ui.ui_factory.note(' %6d texts' % self.text_count)
2236
self._cleanup_spare_files_after_format4()
2237
self.branch._transport.put_bytes(
2239
BzrDirFormat5().get_format_string(),
2240
mode=self.bzrdir._get_file_mode())
2242
def _cleanup_spare_files_after_format4(self):
2243
# FIXME working tree upgrade foo.
2244
for n in 'merged-patches', 'pending-merged-patches':
2246
## assert os.path.getsize(p) == 0
2247
self.bzrdir.transport.delete(n)
2248
except errors.NoSuchFile:
2250
self.bzrdir.transport.delete_tree('inventory-store')
2251
self.bzrdir.transport.delete_tree('text-store')
2253
def _convert_working_inv(self):
2254
inv = xml4.serializer_v4.read_inventory(
2255
self.branch._transport.get('inventory'))
2256
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv, working=True)
2257
self.branch._transport.put_bytes('inventory', new_inv_xml,
2258
mode=self.bzrdir._get_file_mode())
2260
def _write_all_weaves(self):
2261
controlweaves = VersionedFileStore(self.bzrdir.transport, prefixed=False,
2262
versionedfile_class=WeaveFile)
2263
weave_transport = self.bzrdir.transport.clone('weaves')
2264
weaves = VersionedFileStore(weave_transport, prefixed=False,
2265
versionedfile_class=WeaveFile)
2266
transaction = WriteTransaction()
2270
for file_id, file_weave in self.text_weaves.items():
2271
self.pb.update('writing weave', i, len(self.text_weaves))
2272
weaves._put_weave(file_id, file_weave, transaction)
2274
self.pb.update('inventory', 0, 1)
2275
controlweaves._put_weave('inventory', self.inv_weave, transaction)
2276
self.pb.update('inventory', 1, 1)
2280
def _write_all_revs(self):
2281
"""Write all revisions out in new form."""
2282
self.bzrdir.transport.delete_tree('revision-store')
2283
self.bzrdir.transport.mkdir('revision-store')
2284
revision_transport = self.bzrdir.transport.clone('revision-store')
2286
from bzrlib.xml5 import serializer_v5
2287
from bzrlib.repofmt.weaverepo import RevisionTextStore
2288
revision_store = RevisionTextStore(revision_transport,
2289
serializer_v5, False, versionedfile.PrefixMapper(),
2290
lambda:True, lambda:True)
2292
for i, rev_id in enumerate(self.converted_revs):
2293
self.pb.update('write revision', i, len(self.converted_revs))
2294
text = serializer_v5.write_revision_to_string(
2295
self.revisions[rev_id])
2297
revision_store.add_lines(key, None, osutils.split_lines(text))
2301
def _load_one_rev(self, rev_id):
2302
"""Load a revision object into memory.
2304
Any parents not either loaded or abandoned get queued to be
2306
self.pb.update('loading revision',
2307
len(self.revisions),
2308
len(self.known_revisions))
2309
if not self.branch.repository.has_revision(rev_id):
2311
ui.ui_factory.note('revision {%s} not present in branch; '
2312
'will be converted as a ghost' %
2314
self.absent_revisions.add(rev_id)
2316
rev = self.branch.repository.get_revision(rev_id)
2317
for parent_id in rev.parent_ids:
2318
self.known_revisions.add(parent_id)
2319
self.to_read.append(parent_id)
2320
self.revisions[rev_id] = rev
2322
def _load_old_inventory(self, rev_id):
2323
f = self.branch.repository.inventory_store.get(rev_id)
2325
old_inv_xml = f.read()
2328
inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2329
inv.revision_id = rev_id
2330
rev = self.revisions[rev_id]
2333
def _load_updated_inventory(self, rev_id):
2334
inv_xml = self.inv_weave.get_text(rev_id)
2335
inv = xml5.serializer_v5.read_inventory_from_string(inv_xml, rev_id)
2338
def _convert_one_rev(self, rev_id):
2339
"""Convert revision and all referenced objects to new format."""
2340
rev = self.revisions[rev_id]
2341
inv = self._load_old_inventory(rev_id)
2342
present_parents = [p for p in rev.parent_ids
2343
if p not in self.absent_revisions]
2344
self._convert_revision_contents(rev, inv, present_parents)
2345
self._store_new_inv(rev, inv, present_parents)
2346
self.converted_revs.add(rev_id)
2348
def _store_new_inv(self, rev, inv, present_parents):
2349
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
2350
new_inv_sha1 = sha_string(new_inv_xml)
2351
self.inv_weave.add_lines(rev.revision_id,
2353
new_inv_xml.splitlines(True))
2354
rev.inventory_sha1 = new_inv_sha1
2356
def _convert_revision_contents(self, rev, inv, present_parents):
2357
"""Convert all the files within a revision.
2359
Also upgrade the inventory to refer to the text revision ids."""
2360
rev_id = rev.revision_id
2361
mutter('converting texts of revision {%s}',
2363
parent_invs = map(self._load_updated_inventory, present_parents)
2364
entries = inv.iter_entries()
2366
for path, ie in entries:
2367
self._convert_file_version(rev, ie, parent_invs)
2369
def _convert_file_version(self, rev, ie, parent_invs):
2370
"""Convert one version of one file.
2372
The file needs to be added into the weave if it is a merge
2373
of >=2 parents or if it's changed from its parent.
2375
file_id = ie.file_id
2376
rev_id = rev.revision_id
2377
w = self.text_weaves.get(file_id)
2380
self.text_weaves[file_id] = w
2381
text_changed = False
2382
parent_candiate_entries = ie.parent_candidates(parent_invs)
2383
heads = graph.Graph(self).heads(parent_candiate_entries.keys())
2384
# XXX: Note that this is unordered - and this is tolerable because
2385
# the previous code was also unordered.
2386
previous_entries = dict((head, parent_candiate_entries[head]) for head
2388
self.snapshot_ie(previous_entries, ie, w, rev_id)
2390
def get_parent_map(self, revision_ids):
2391
"""See graph.StackedParentsProvider.get_parent_map"""
2392
return dict((revision_id, self.revisions[revision_id])
2393
for revision_id in revision_ids
2394
if revision_id in self.revisions)
2396
def snapshot_ie(self, previous_revisions, ie, w, rev_id):
2397
# TODO: convert this logic, which is ~= snapshot to
2398
# a call to:. This needs the path figured out. rather than a work_tree
2399
# a v4 revision_tree can be given, or something that looks enough like
2400
# one to give the file content to the entry if it needs it.
2401
# and we need something that looks like a weave store for snapshot to
2403
#ie.snapshot(rev, PATH, previous_revisions, REVISION_TREE, InMemoryWeaveStore(self.text_weaves))
2404
if len(previous_revisions) == 1:
2405
previous_ie = previous_revisions.values()[0]
2406
if ie._unchanged(previous_ie):
2407
ie.revision = previous_ie.revision
2410
f = self.branch.repository._text_store.get(ie.text_id)
2412
file_lines = f.readlines()
2415
w.add_lines(rev_id, previous_revisions, file_lines)
2416
self.text_count += 1
2418
w.add_lines(rev_id, previous_revisions, [])
2419
ie.revision = rev_id
2421
def _make_order(self):
2422
"""Return a suitable order for importing revisions.
2424
The order must be such that an revision is imported after all
2425
its (present) parents.
2427
todo = set(self.revisions.keys())
2428
done = self.absent_revisions.copy()
2431
# scan through looking for a revision whose parents
2433
for rev_id in sorted(list(todo)):
2434
rev = self.revisions[rev_id]
2435
parent_ids = set(rev.parent_ids)
2436
if parent_ids.issubset(done):
2437
# can take this one now
2438
order.append(rev_id)
2444
class ConvertBzrDir5To6(Converter):
2445
"""Converts format 5 bzr dirs to format 6."""
2447
def convert(self, to_convert, pb):
2448
"""See Converter.convert()."""
2449
self.bzrdir = to_convert
2450
pb = ui.ui_factory.nested_progress_bar()
2452
ui.ui_factory.note('starting upgrade from format 5 to 6')
2453
self._convert_to_prefixed()
2454
return BzrDir.open(self.bzrdir.user_url)
2458
def _convert_to_prefixed(self):
2459
from bzrlib.store import TransportStore
2460
self.bzrdir.transport.delete('branch-format')
2461
for store_name in ["weaves", "revision-store"]:
2462
ui.ui_factory.note("adding prefixes to %s" % store_name)
2463
store_transport = self.bzrdir.transport.clone(store_name)
2464
store = TransportStore(store_transport, prefixed=True)
2465
for urlfilename in store_transport.list_dir('.'):
2466
filename = urlutils.unescape(urlfilename)
2467
if (filename.endswith(".weave") or
2468
filename.endswith(".gz") or
2469
filename.endswith(".sig")):
2470
file_id, suffix = os.path.splitext(filename)
2474
new_name = store._mapper.map((file_id,)) + suffix
2475
# FIXME keep track of the dirs made RBC 20060121
2477
store_transport.move(filename, new_name)
2478
except errors.NoSuchFile: # catches missing dirs strangely enough
2479
store_transport.mkdir(osutils.dirname(new_name))
2480
store_transport.move(filename, new_name)
2481
self.bzrdir.transport.put_bytes(
2483
BzrDirFormat6().get_format_string(),
2484
mode=self.bzrdir._get_file_mode())
2487
class ConvertBzrDir6ToMeta(Converter):
2488
"""Converts format 6 bzr dirs to metadirs."""
2490
def convert(self, to_convert, pb):
2491
"""See Converter.convert()."""
2492
from bzrlib.repofmt.weaverepo import RepositoryFormat7
2493
from bzrlib.branch import BzrBranchFormat5
2494
self.bzrdir = to_convert
2495
self.pb = ui.ui_factory.nested_progress_bar()
2497
self.total = 20 # the steps we know about
2498
self.garbage_inventories = []
2499
self.dir_mode = self.bzrdir._get_dir_mode()
2500
self.file_mode = self.bzrdir._get_file_mode()
2502
ui.ui_factory.note('starting upgrade from format 6 to metadir')
2503
self.bzrdir.transport.put_bytes(
2505
"Converting to format 6",
2506
mode=self.file_mode)
2507
# its faster to move specific files around than to open and use the apis...
2508
# first off, nuke ancestry.weave, it was never used.
2510
self.step('Removing ancestry.weave')
2511
self.bzrdir.transport.delete('ancestry.weave')
2512
except errors.NoSuchFile:
2514
# find out whats there
2515
self.step('Finding branch files')
2516
last_revision = self.bzrdir.open_branch().last_revision()
2517
bzrcontents = self.bzrdir.transport.list_dir('.')
2518
for name in bzrcontents:
2519
if name.startswith('basis-inventory.'):
2520
self.garbage_inventories.append(name)
2521
# create new directories for repository, working tree and branch
2522
repository_names = [('inventory.weave', True),
2523
('revision-store', True),
2525
self.step('Upgrading repository ')
2526
self.bzrdir.transport.mkdir('repository', mode=self.dir_mode)
2527
self.make_lock('repository')
2528
# we hard code the formats here because we are converting into
2529
# the meta format. The meta format upgrader can take this to a
2530
# future format within each component.
2531
self.put_format('repository', RepositoryFormat7())
2532
for entry in repository_names:
2533
self.move_entry('repository', entry)
2535
self.step('Upgrading branch ')
2536
self.bzrdir.transport.mkdir('branch', mode=self.dir_mode)
2537
self.make_lock('branch')
2538
self.put_format('branch', BzrBranchFormat5())
2539
branch_files = [('revision-history', True),
2540
('branch-name', True),
2542
for entry in branch_files:
2543
self.move_entry('branch', entry)
2545
checkout_files = [('pending-merges', True),
2546
('inventory', True),
2547
('stat-cache', False)]
2548
# If a mandatory checkout file is not present, the branch does not have
2549
# a functional checkout. Do not create a checkout in the converted
2551
for name, mandatory in checkout_files:
2552
if mandatory and name not in bzrcontents:
2553
has_checkout = False
2557
if not has_checkout:
2558
ui.ui_factory.note('No working tree.')
2559
# If some checkout files are there, we may as well get rid of them.
2560
for name, mandatory in checkout_files:
2561
if name in bzrcontents:
2562
self.bzrdir.transport.delete(name)
2564
from bzrlib.workingtree import WorkingTreeFormat3
2565
self.step('Upgrading working tree')
2566
self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
2567
self.make_lock('checkout')
2569
'checkout', WorkingTreeFormat3())
2570
self.bzrdir.transport.delete_multi(
2571
self.garbage_inventories, self.pb)
2572
for entry in checkout_files:
2573
self.move_entry('checkout', entry)
2574
if last_revision is not None:
2575
self.bzrdir.transport.put_bytes(
2576
'checkout/last-revision', last_revision)
2577
self.bzrdir.transport.put_bytes(
2579
BzrDirMetaFormat1().get_format_string(),
2580
mode=self.file_mode)
2582
return BzrDir.open(self.bzrdir.user_url)
2584
def make_lock(self, name):
2585
"""Make a lock for the new control dir name."""
2586
self.step('Make %s lock' % name)
2587
ld = lockdir.LockDir(self.bzrdir.transport,
2589
file_modebits=self.file_mode,
2590
dir_modebits=self.dir_mode)
2593
def move_entry(self, new_dir, entry):
2594
"""Move then entry name into new_dir."""
2596
mandatory = entry[1]
2597
self.step('Moving %s' % name)
2599
self.bzrdir.transport.move(name, '%s/%s' % (new_dir, name))
2600
except errors.NoSuchFile:
2604
def put_format(self, dirname, format):
2605
self.bzrdir.transport.put_bytes('%s/format' % dirname,
2606
format.get_format_string(),
2610
class ConvertMetaToMeta(Converter):
1835
2611
"""Converts the components of metadirs."""
1837
2613
def __init__(self, target_format):
1909
2686
return to_convert
2689
# This is not in remote.py because it's relatively small, and needs to be
2690
# registered. Putting it in remote.py creates a circular import problem.
2691
# we can make it a lazy object if the control formats is turned into something
2693
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2694
"""Format representing bzrdirs accessed via a smart server"""
2696
supports_workingtrees = False
2699
BzrDirMetaFormat1.__init__(self)
2700
# XXX: It's a bit ugly that the network name is here, because we'd
2701
# like to believe that format objects are stateless or at least
2702
# immutable, However, we do at least avoid mutating the name after
2703
# it's returned. See <https://bugs.launchpad.net/bzr/+bug/504102>
2704
self._network_name = None
2707
return "%s(_network_name=%r)" % (self.__class__.__name__,
2710
def get_format_description(self):
2711
if self._network_name:
2712
real_format = controldir.network_format_registry.get(self._network_name)
2713
return 'Remote: ' + real_format.get_format_description()
2714
return 'bzr remote bzrdir'
2716
def get_format_string(self):
2717
raise NotImplementedError(self.get_format_string)
2719
def network_name(self):
2720
if self._network_name:
2721
return self._network_name
2723
raise AssertionError("No network name set.")
2725
def initialize_on_transport(self, transport):
2727
# hand off the request to the smart server
2728
client_medium = transport.get_smart_medium()
2729
except errors.NoSmartMedium:
2730
# TODO: lookup the local format from a server hint.
2731
local_dir_format = BzrDirMetaFormat1()
2732
return local_dir_format.initialize_on_transport(transport)
2733
client = _SmartClient(client_medium)
2734
path = client.remote_path_from_transport(transport)
2736
response = client.call('BzrDirFormat.initialize', path)
2737
except errors.ErrorFromSmartServer, err:
2738
remote._translate_error(err, path=path)
2739
if response[0] != 'ok':
2740
raise errors.SmartProtocolError('unexpected response code %s' % (response,))
2741
format = RemoteBzrDirFormat()
2742
self._supply_sub_formats_to(format)
2743
return remote.RemoteBzrDir(transport, format)
2745
def parse_NoneTrueFalse(self, arg):
2752
raise AssertionError("invalid arg %r" % arg)
2754
def _serialize_NoneTrueFalse(self, arg):
2761
def _serialize_NoneString(self, arg):
2764
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
2765
create_prefix=False, force_new_repo=False, stacked_on=None,
2766
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
2769
# hand off the request to the smart server
2770
client_medium = transport.get_smart_medium()
2771
except errors.NoSmartMedium:
2774
# Decline to open it if the server doesn't support our required
2775
# version (3) so that the VFS-based transport will do it.
2776
if client_medium.should_probe():
2778
server_version = client_medium.protocol_version()
2779
if server_version != '2':
2783
except errors.SmartProtocolError:
2784
# Apparently there's no usable smart server there, even though
2785
# the medium supports the smart protocol.
2790
client = _SmartClient(client_medium)
2791
path = client.remote_path_from_transport(transport)
2792
if client_medium._is_remote_before((1, 16)):
2795
# TODO: lookup the local format from a server hint.
2796
local_dir_format = BzrDirMetaFormat1()
2797
self._supply_sub_formats_to(local_dir_format)
2798
return local_dir_format.initialize_on_transport_ex(transport,
2799
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2800
force_new_repo=force_new_repo, stacked_on=stacked_on,
2801
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2802
make_working_trees=make_working_trees, shared_repo=shared_repo,
2804
return self._initialize_on_transport_ex_rpc(client, path, transport,
2805
use_existing_dir, create_prefix, force_new_repo, stacked_on,
2806
stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
2808
def _initialize_on_transport_ex_rpc(self, client, path, transport,
2809
use_existing_dir, create_prefix, force_new_repo, stacked_on,
2810
stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
2812
args.append(self._serialize_NoneTrueFalse(use_existing_dir))
2813
args.append(self._serialize_NoneTrueFalse(create_prefix))
2814
args.append(self._serialize_NoneTrueFalse(force_new_repo))
2815
args.append(self._serialize_NoneString(stacked_on))
2816
# stack_on_pwd is often/usually our transport
2819
stack_on_pwd = transport.relpath(stack_on_pwd)
2820
if not stack_on_pwd:
2822
except errors.PathNotChild:
2824
args.append(self._serialize_NoneString(stack_on_pwd))
2825
args.append(self._serialize_NoneString(repo_format_name))
2826
args.append(self._serialize_NoneTrueFalse(make_working_trees))
2827
args.append(self._serialize_NoneTrueFalse(shared_repo))
2828
request_network_name = self._network_name or \
2829
BzrDirFormat.get_default_format().network_name()
2831
response = client.call('BzrDirFormat.initialize_ex_1.16',
2832
request_network_name, path, *args)
2833
except errors.UnknownSmartMethod:
2834
client._medium._remember_remote_is_before((1,16))
2835
local_dir_format = BzrDirMetaFormat1()
2836
self._supply_sub_formats_to(local_dir_format)
2837
return local_dir_format.initialize_on_transport_ex(transport,
2838
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2839
force_new_repo=force_new_repo, stacked_on=stacked_on,
2840
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2841
make_working_trees=make_working_trees, shared_repo=shared_repo,
2843
except errors.ErrorFromSmartServer, err:
2844
remote._translate_error(err, path=path)
2845
repo_path = response[0]
2846
bzrdir_name = response[6]
2847
require_stacking = response[7]
2848
require_stacking = self.parse_NoneTrueFalse(require_stacking)
2849
format = RemoteBzrDirFormat()
2850
format._network_name = bzrdir_name
2851
self._supply_sub_formats_to(format)
2852
bzrdir = remote.RemoteBzrDir(transport, format, _client=client)
2854
repo_format = remote.response_tuple_to_repo_format(response[1:])
2855
if repo_path == '.':
2858
repo_bzrdir_format = RemoteBzrDirFormat()
2859
repo_bzrdir_format._network_name = response[5]
2860
repo_bzr = remote.RemoteBzrDir(transport.clone(repo_path),
2864
final_stack = response[8] or None
2865
final_stack_pwd = response[9] or None
2867
final_stack_pwd = urlutils.join(
2868
transport.base, final_stack_pwd)
2869
remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
2870
if len(response) > 10:
2871
# Updated server verb that locks remotely.
2872
repo_lock_token = response[10] or None
2873
remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
2875
remote_repo.dont_leave_lock_in_place()
2877
remote_repo.lock_write()
2878
policy = UseExistingRepository(remote_repo, final_stack,
2879
final_stack_pwd, require_stacking)
2880
policy.acquire_repository()
2884
bzrdir._format.set_branch_format(self.get_branch_format())
2885
if require_stacking:
2886
# The repo has already been created, but we need to make sure that
2887
# we'll make a stackable branch.
2888
bzrdir._format.require_stacking(_skip_repo=True)
2889
return remote_repo, bzrdir, require_stacking, policy
2891
def _open(self, transport):
2892
return remote.RemoteBzrDir(transport, self)
2894
def __eq__(self, other):
2895
if not isinstance(other, RemoteBzrDirFormat):
2897
return self.get_format_description() == other.get_format_description()
2899
def __return_repository_format(self):
2900
# Always return a RemoteRepositoryFormat object, but if a specific bzr
2901
# repository format has been asked for, tell the RemoteRepositoryFormat
2902
# that it should use that for init() etc.
2903
result = remote.RemoteRepositoryFormat()
2904
custom_format = getattr(self, '_repository_format', None)
2906
if isinstance(custom_format, remote.RemoteRepositoryFormat):
2907
return custom_format
2909
# We will use the custom format to create repositories over the
2910
# wire; expose its details like rich_root_data for code to
2912
result._custom_format = custom_format
2915
def get_branch_format(self):
2916
result = BzrDirMetaFormat1.get_branch_format(self)
2917
if not isinstance(result, remote.RemoteBranchFormat):
2918
new_result = remote.RemoteBranchFormat()
2919
new_result._custom_format = result
2921
self.set_branch_format(new_result)
2925
repository_format = property(__return_repository_format,
2926
BzrDirMetaFormat1._set_repository_format) #.im_func)
1912
2929
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
2152
3185
'network operations. Additionally adds support for versioning nested '
2153
3186
'bzr branches. Incompatible with bzr < 0.15.',
2154
3187
branch_format='bzrlib.branch.BzrBranchFormat6',
2155
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3188
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2156
3189
experimental=True,
2159
3192
register_metadir(controldir.format_registry, 'pack-0.92',
2160
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
3193
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
2161
3194
help='New in 0.92: Pack-based format with data compatible with '
2162
3195
'dirstate-tags format repositories. Interoperates with '
2163
3196
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2165
3198
branch_format='bzrlib.branch.BzrBranchFormat6',
2166
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3199
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2168
3201
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2169
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
3202
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
2170
3203
help='New in 0.92: Pack-based format with data compatible with '
2171
3204
'dirstate-with-subtree format repositories. Interoperates with '
2172
3205
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2174
3207
branch_format='bzrlib.branch.BzrBranchFormat6',
2175
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3208
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2177
3210
experimental=True,
2179
3212
register_metadir(controldir.format_registry, 'rich-root-pack',
2180
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
3213
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
2181
3214
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
2182
3215
'(needed for bzr-svn and bzr-git).',
2183
3216
branch_format='bzrlib.branch.BzrBranchFormat6',
2184
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3217
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2187
3220
register_metadir(controldir.format_registry, '1.6',
2188
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
3221
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
2189
3222
help='A format that allows a branch to indicate that there is another '
2190
3223
'(stacked) repository that should be used to access data that is '
2191
3224
'not present locally.',
2192
3225
branch_format='bzrlib.branch.BzrBranchFormat7',
2193
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3226
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2196
3229
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2197
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
3230
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
2198
3231
help='A variant of 1.6 that supports rich-root data '
2199
3232
'(needed for bzr-svn and bzr-git).',
2200
3233
branch_format='bzrlib.branch.BzrBranchFormat7',
2201
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3234
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2204
3237
register_metadir(controldir.format_registry, '1.9',
2205
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
3238
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
2206
3239
help='A repository format using B+tree indexes. These indexes '
2207
3240
'are smaller in size, have smarter caching and provide faster '
2208
3241
'performance for most operations.',
2209
3242
branch_format='bzrlib.branch.BzrBranchFormat7',
2210
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3243
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2213
3246
register_metadir(controldir.format_registry, '1.9-rich-root',
2214
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
3247
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
2215
3248
help='A variant of 1.9 that supports rich-root data '
2216
3249
'(needed for bzr-svn and bzr-git).',
2217
3250
branch_format='bzrlib.branch.BzrBranchFormat7',
2218
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3251
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2221
3254
register_metadir(controldir.format_registry, '1.14',
2222
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
3255
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
2223
3256
help='A working-tree format that supports content filtering.',
2224
3257
branch_format='bzrlib.branch.BzrBranchFormat7',
2225
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
3258
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2227
3260
register_metadir(controldir.format_registry, '1.14-rich-root',
2228
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
3261
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
2229
3262
help='A variant of 1.14 that supports rich-root data '
2230
3263
'(needed for bzr-svn and bzr-git).',
2231
3264
branch_format='bzrlib.branch.BzrBranchFormat7',
2232
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
3265
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2234
3267
# The following un-numbered 'development' formats should always just be aliases.
2235
3268
register_metadir(controldir.format_registry, 'development-subtree',