388
437
policy = self.determine_repository_policy(force_new_repo)
389
438
return policy.acquire_repository()[0]
391
def _find_source_repo(self, add_cleanup, source_branch):
392
"""Find the source branch and repo for a sprout operation.
394
This is helper intended for use by _sprout.
396
:returns: (source_branch, source_repository). Either or both may be
397
None. If not None, they will be read-locked (and their unlock(s)
398
scheduled via the add_cleanup param).
400
if source_branch is not None:
401
add_cleanup(source_branch.lock_read().unlock)
402
return source_branch, source_branch.repository
404
source_branch = self.open_branch()
405
source_repository = source_branch.repository
406
except errors.NotBranchError:
409
source_repository = self.open_repository()
410
except errors.NoRepositoryPresent:
411
source_repository = None
413
add_cleanup(source_repository.lock_read().unlock)
415
add_cleanup(source_branch.lock_read().unlock)
416
return source_branch, source_repository
418
def sprout(self, url, revision_id=None, force_new_repo=False,
419
recurse='down', possible_transports=None,
420
accelerator_tree=None, hardlink=False, stacked=False,
421
source_branch=None, create_tree_if_local=True):
422
"""Create a copy of this controldir prepared for use as a new line of
425
If url's last component does not exist, it will be created.
427
Attributes related to the identity of the source branch like
428
branch nickname will be cleaned, a working tree is created
429
whether one existed before or not; and a local branch is always
432
if revision_id is not None, then the clone operation may tune
433
itself to download less data.
434
:param accelerator_tree: A tree which can be used for retrieving file
435
contents more quickly than the revision tree, i.e. a workingtree.
436
The revision tree will be used for cases where accelerator_tree's
437
content is different.
438
:param hardlink: If true, hard-link files from accelerator_tree,
440
:param stacked: If true, create a stacked branch referring to the
441
location of this control directory.
442
:param create_tree_if_local: If true, a working-tree will be created
443
when working locally.
445
operation = cleanup.OperationWithCleanups(self._sprout)
446
return operation.run(url, revision_id=revision_id,
447
force_new_repo=force_new_repo, recurse=recurse,
448
possible_transports=possible_transports,
449
accelerator_tree=accelerator_tree, hardlink=hardlink,
450
stacked=stacked, source_branch=source_branch,
451
create_tree_if_local=create_tree_if_local)
453
def _sprout(self, op, url, revision_id=None, force_new_repo=False,
454
recurse='down', possible_transports=None,
455
accelerator_tree=None, hardlink=False, stacked=False,
456
source_branch=None, create_tree_if_local=True):
457
add_cleanup = op.add_cleanup
458
fetch_spec_factory = fetch.FetchSpecFactory()
459
if revision_id is not None:
460
fetch_spec_factory.add_revision_ids([revision_id])
461
fetch_spec_factory.source_branch_stop_revision_id = revision_id
462
target_transport = _mod_transport.get_transport(url,
464
target_transport.ensure_base()
465
cloning_format = self.cloning_metadir(stacked)
466
# Create/update the result branch
467
result = cloning_format.initialize_on_transport(target_transport)
468
source_branch, source_repository = self._find_source_repo(
469
add_cleanup, source_branch)
470
fetch_spec_factory.source_branch = source_branch
471
# if a stacked branch wasn't requested, we don't create one
472
# even if the origin was stacked
473
if stacked and source_branch is not None:
474
stacked_branch_url = self.root_transport.base
476
stacked_branch_url = None
477
repository_policy = result.determine_repository_policy(
478
force_new_repo, stacked_branch_url, require_stacking=stacked)
479
result_repo, is_new_repo = repository_policy.acquire_repository()
480
add_cleanup(result_repo.lock_write().unlock)
481
fetch_spec_factory.source_repo = source_repository
482
fetch_spec_factory.target_repo = result_repo
483
if stacked or (len(result_repo._fallback_repositories) != 0):
484
target_repo_kind = fetch.TargetRepoKinds.STACKED
486
target_repo_kind = fetch.TargetRepoKinds.EMPTY
488
target_repo_kind = fetch.TargetRepoKinds.PREEXISTING
489
fetch_spec_factory.target_repo_kind = target_repo_kind
490
if source_repository is not None:
491
fetch_spec = fetch_spec_factory.make_fetch_spec()
492
result_repo.fetch(source_repository, fetch_spec=fetch_spec)
494
if source_branch is None:
495
# this is for sprouting a controldir without a branch; is that
497
# Not especially, but it's part of the contract.
498
result_branch = result.create_branch()
500
result_branch = source_branch.sprout(result,
501
revision_id=revision_id, repository_policy=repository_policy,
502
repository=result_repo)
503
mutter("created new branch %r" % (result_branch,))
505
# Create/update the result working tree
506
if (create_tree_if_local and
507
isinstance(target_transport, local.LocalTransport) and
508
(result_repo is None or result_repo.make_working_trees())):
509
wt = result.create_workingtree(accelerator_tree=accelerator_tree,
510
hardlink=hardlink, from_branch=result_branch)
513
if wt.path2id('') is None:
515
wt.set_root_id(self.open_workingtree.get_root_id())
516
except errors.NoWorkingTree:
522
if recurse == 'down':
525
basis = wt.basis_tree()
526
elif result_branch is not None:
527
basis = result_branch.basis_tree()
528
elif source_branch is not None:
529
basis = source_branch.basis_tree()
530
if basis is not None:
531
add_cleanup(basis.lock_read().unlock)
532
subtrees = basis.iter_references()
535
for path, file_id in subtrees:
536
target = urlutils.join(url, urlutils.escape(path))
537
sublocation = source_branch.reference_parent(file_id, path)
538
sublocation.bzrdir.sprout(target,
539
basis.get_reference_revision(file_id, path),
540
force_new_repo=force_new_repo, recurse=recurse,
547
441
def create_branch_convenience(base, force_new_repo=False,
548
442
force_new_tree=None, format=None,
988
class BzrDirPreSplitOut(BzrDir):
989
"""A common class for the all-in-one formats."""
991
def __init__(self, _transport, _format):
992
"""See BzrDir.__init__."""
993
super(BzrDirPreSplitOut, self).__init__(_transport, _format)
994
self._control_files = lockable_files.LockableFiles(
995
self.get_branch_transport(None),
996
self._format._lock_file_name,
997
self._format._lock_class)
999
def break_lock(self):
1000
"""Pre-splitout bzrdirs do not suffer from stale locks."""
1001
raise NotImplementedError(self.break_lock)
1003
def cloning_metadir(self, require_stacking=False):
1004
"""Produce a metadir suitable for cloning with."""
1005
if require_stacking:
1006
return controldir.format_registry.make_bzrdir('1.6')
1007
return self._format.__class__()
1009
def clone(self, url, revision_id=None, force_new_repo=False,
1010
preserve_stacking=False):
1011
"""See BzrDir.clone().
1013
force_new_repo has no effect, since this family of formats always
1014
require a new repository.
1015
preserve_stacking has no effect, since no source branch using this
1016
family of formats can be stacked, so there is no stacking to preserve.
1018
self._make_tail(url)
1019
result = self._format._initialize_for_clone(url)
1020
self.open_repository().clone(result, revision_id=revision_id)
1021
from_branch = self.open_branch()
1022
from_branch.clone(result, revision_id=revision_id)
1024
tree = self.open_workingtree()
1025
except errors.NotLocalUrl:
1026
# make a new one, this format always has to have one.
1027
result._init_workingtree()
1032
def create_branch(self, name=None, repository=None):
1033
"""See BzrDir.create_branch."""
1034
if repository is not None:
1035
raise NotImplementedError(
1036
"create_branch(repository=<not None>) on %r" % (self,))
1037
return self._format.get_branch_format().initialize(self, name=name)
1039
def destroy_branch(self, name=None):
1040
"""See BzrDir.destroy_branch."""
1041
raise errors.UnsupportedOperation(self.destroy_branch, self)
1043
def create_repository(self, shared=False):
1044
"""See BzrDir.create_repository."""
1046
raise errors.IncompatibleFormat('shared repository', self._format)
1047
return self.open_repository()
1049
def destroy_repository(self):
1050
"""See BzrDir.destroy_repository."""
1051
raise errors.UnsupportedOperation(self.destroy_repository, self)
1053
def create_workingtree(self, revision_id=None, from_branch=None,
1054
accelerator_tree=None, hardlink=False):
1055
"""See BzrDir.create_workingtree."""
1056
# The workingtree is sometimes created when the bzrdir is created,
1057
# but not when cloning.
1059
# this looks buggy but is not -really-
1060
# because this format creates the workingtree when the bzrdir is
1062
# clone and sprout will have set the revision_id
1063
# and that will have set it for us, its only
1064
# specific uses of create_workingtree in isolation
1065
# that can do wonky stuff here, and that only
1066
# happens for creating checkouts, which cannot be
1067
# done on this format anyway. So - acceptable wart.
1069
warning("can't support hardlinked working trees in %r"
1072
result = self.open_workingtree(recommend_upgrade=False)
1073
except errors.NoSuchFile:
1074
result = self._init_workingtree()
1075
if revision_id is not None:
1076
if revision_id == _mod_revision.NULL_REVISION:
1077
result.set_parent_ids([])
1079
result.set_parent_ids([revision_id])
1082
def _init_workingtree(self):
1083
from bzrlib.workingtree import WorkingTreeFormat2
1085
return WorkingTreeFormat2().initialize(self)
1086
except errors.NotLocalUrl:
1087
# Even though we can't access the working tree, we need to
1088
# create its control files.
1089
return WorkingTreeFormat2()._stub_initialize_on_transport(
1090
self.transport, self._control_files._file_mode)
1092
def destroy_workingtree(self):
1093
"""See BzrDir.destroy_workingtree."""
1094
raise errors.UnsupportedOperation(self.destroy_workingtree, self)
1096
def destroy_workingtree_metadata(self):
1097
"""See BzrDir.destroy_workingtree_metadata."""
1098
raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1101
def get_branch_transport(self, branch_format, name=None):
1102
"""See BzrDir.get_branch_transport()."""
1103
if name is not None:
1104
raise errors.NoColocatedBranchSupport(self)
1105
if branch_format is None:
1106
return self.transport
1108
branch_format.get_format_string()
1109
except NotImplementedError:
1110
return self.transport
1111
raise errors.IncompatibleFormat(branch_format, self._format)
1113
def get_repository_transport(self, repository_format):
1114
"""See BzrDir.get_repository_transport()."""
1115
if repository_format is None:
1116
return self.transport
1118
repository_format.get_format_string()
1119
except NotImplementedError:
1120
return self.transport
1121
raise errors.IncompatibleFormat(repository_format, self._format)
1123
def get_workingtree_transport(self, workingtree_format):
1124
"""See BzrDir.get_workingtree_transport()."""
1125
if workingtree_format is None:
1126
return self.transport
1128
workingtree_format.get_format_string()
1129
except NotImplementedError:
1130
return self.transport
1131
raise errors.IncompatibleFormat(workingtree_format, self._format)
1133
def needs_format_conversion(self, format=None):
1134
"""See BzrDir.needs_format_conversion()."""
1135
# if the format is not the same as the system default,
1136
# an upgrade is needed.
1138
symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
1139
% 'needs_format_conversion(format=None)')
1140
format = BzrDirFormat.get_default_format()
1141
return not isinstance(self._format, format.__class__)
1143
def open_branch(self, name=None, unsupported=False,
1144
ignore_fallbacks=False):
1145
"""See BzrDir.open_branch."""
1146
from bzrlib.branch import BzrBranchFormat4
1147
format = BzrBranchFormat4()
1148
self._check_supported(format, unsupported)
1149
return format.open(self, name, _found=True)
1151
def sprout(self, url, revision_id=None, force_new_repo=False,
1152
possible_transports=None, accelerator_tree=None,
1153
hardlink=False, stacked=False, create_tree_if_local=True,
1154
source_branch=None):
1155
"""See BzrDir.sprout()."""
1156
if source_branch is not None:
1157
my_branch = self.open_branch()
1158
if source_branch.base != my_branch.base:
1159
raise AssertionError(
1160
"source branch %r is not within %r with branch %r" %
1161
(source_branch, self, my_branch))
1163
raise errors.UnstackableBranchFormat(
1164
self._format, self.root_transport.base)
1165
if not create_tree_if_local:
1166
raise errors.MustHaveWorkingTree(
1167
self._format, self.root_transport.base)
1168
from bzrlib.workingtree import WorkingTreeFormat2
1169
self._make_tail(url)
1170
result = self._format._initialize_for_clone(url)
1172
self.open_repository().clone(result, revision_id=revision_id)
1173
except errors.NoRepositoryPresent:
1176
self.open_branch().sprout(result, revision_id=revision_id)
1177
except errors.NotBranchError:
1180
# we always want a working tree
1181
WorkingTreeFormat2().initialize(result,
1182
accelerator_tree=accelerator_tree,
1187
class BzrDir4(BzrDirPreSplitOut):
1188
"""A .bzr version 4 control object.
1190
This is a deprecated format and may be removed after sept 2006.
1193
def create_repository(self, shared=False):
1194
"""See BzrDir.create_repository."""
1195
return self._format.repository_format.initialize(self, shared)
1197
def needs_format_conversion(self, format=None):
1198
"""Format 4 dirs are always in need of conversion."""
1200
symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
1201
% 'needs_format_conversion(format=None)')
1204
def open_repository(self):
1205
"""See BzrDir.open_repository."""
1206
from bzrlib.repofmt.weaverepo import RepositoryFormat4
1207
return RepositoryFormat4().open(self, _found=True)
1210
class BzrDir5(BzrDirPreSplitOut):
1211
"""A .bzr version 5 control object.
1213
This is a deprecated format and may be removed after sept 2006.
1216
def has_workingtree(self):
1217
"""See BzrDir.has_workingtree."""
1220
def open_repository(self):
1221
"""See BzrDir.open_repository."""
1222
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1223
return RepositoryFormat5().open(self, _found=True)
1225
def open_workingtree(self, _unsupported=False,
1226
recommend_upgrade=True):
1227
"""See BzrDir.create_workingtree."""
1228
from bzrlib.workingtree import WorkingTreeFormat2
1229
wt_format = WorkingTreeFormat2()
1230
# we don't warn here about upgrades; that ought to be handled for the
1232
return wt_format.open(self, _found=True)
1235
class BzrDir6(BzrDirPreSplitOut):
1236
"""A .bzr version 6 control object.
1238
This is a deprecated format and may be removed after sept 2006.
1241
def has_workingtree(self):
1242
"""See BzrDir.has_workingtree."""
1245
def open_repository(self):
1246
"""See BzrDir.open_repository."""
1247
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1248
return RepositoryFormat6().open(self, _found=True)
1250
def open_workingtree(self, _unsupported=False,
1251
recommend_upgrade=True):
1252
"""See BzrDir.create_workingtree."""
1253
# we don't warn here about upgrades; that ought to be handled for the
1255
from bzrlib.workingtree import WorkingTreeFormat2
1256
return WorkingTreeFormat2().open(self, _found=True)
1133
1259
class BzrDirMeta1(BzrDir):
1134
1260
"""A .bzr meta version 1 control object.
1732
def unregister_format(klass, format):
1733
BzrProber.unregister_bzrdir_format(format)
1734
controldir.ControlDirFormat.unregister_format(format)
1735
controldir.network_format_registry.remove(format.get_format_string())
1738
class BzrDirFormat4(BzrDirFormat):
1739
"""Bzr dir format 4.
1741
This format is a combined format for working tree, branch and repository.
1743
- Format 1 working trees [always]
1744
- Format 4 branches [always]
1745
- Format 4 repositories [always]
1747
This format is deprecated: it indexes texts using a text it which is
1748
removed in format 5; write support for this format has been removed.
1751
_lock_class = lockable_files.TransportLock
1753
def get_format_string(self):
1754
"""See BzrDirFormat.get_format_string()."""
1755
return "Bazaar-NG branch, format 0.0.4\n"
1757
def get_format_description(self):
1758
"""See BzrDirFormat.get_format_description()."""
1759
return "All-in-one format 4"
1761
def get_converter(self, format=None):
1762
"""See BzrDirFormat.get_converter()."""
1763
# there is one and only one upgrade path here.
1764
return ConvertBzrDir4To5()
1766
def initialize_on_transport(self, transport):
1767
"""Format 4 branches cannot be created."""
1768
raise errors.UninitializableFormat(self)
1770
def is_supported(self):
1771
"""Format 4 is not supported.
1773
It is not supported because the model changed from 4 to 5 and the
1774
conversion logic is expensive - so doing it on the fly was not
1779
def network_name(self):
1780
return self.get_format_string()
1782
def _open(self, transport):
1783
"""See BzrDirFormat._open."""
1784
return BzrDir4(transport, self)
1786
def __return_repository_format(self):
1787
"""Circular import protection."""
1788
from bzrlib.repofmt.weaverepo import RepositoryFormat4
1789
return RepositoryFormat4()
1790
repository_format = property(__return_repository_format)
1793
class BzrDirFormatAllInOne(BzrDirFormat):
1794
"""Common class for formats before meta-dirs."""
1796
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1797
create_prefix=False, force_new_repo=False, stacked_on=None,
1798
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1800
"""See BzrDirFormat.initialize_on_transport_ex."""
1801
require_stacking = (stacked_on is not None)
1802
# Format 5 cannot stack, but we've been asked to - actually init
1804
if require_stacking:
1805
format = BzrDirMetaFormat1()
1806
return format.initialize_on_transport_ex(transport,
1807
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1808
force_new_repo=force_new_repo, stacked_on=stacked_on,
1809
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1810
make_working_trees=make_working_trees, shared_repo=shared_repo)
1811
return BzrDirFormat.initialize_on_transport_ex(self, transport,
1812
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1813
force_new_repo=force_new_repo, stacked_on=stacked_on,
1814
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1815
make_working_trees=make_working_trees, shared_repo=shared_repo)
1818
class BzrDirFormat5(BzrDirFormatAllInOne):
1819
"""Bzr control format 5.
1821
This format is a combined format for working tree, branch and repository.
1823
- Format 2 working trees [always]
1824
- Format 4 branches [always]
1825
- Format 5 repositories [always]
1826
Unhashed stores in the repository.
1829
_lock_class = lockable_files.TransportLock
1831
def get_format_string(self):
1832
"""See BzrDirFormat.get_format_string()."""
1833
return "Bazaar-NG branch, format 5\n"
1835
def get_branch_format(self):
1836
from bzrlib import branch
1837
return branch.BzrBranchFormat4()
1839
def get_format_description(self):
1840
"""See BzrDirFormat.get_format_description()."""
1841
return "All-in-one format 5"
1843
def get_converter(self, format=None):
1844
"""See BzrDirFormat.get_converter()."""
1845
# there is one and only one upgrade path here.
1846
return ConvertBzrDir5To6()
1848
def _initialize_for_clone(self, url):
1849
return self.initialize_on_transport(
1850
_mod_transport.get_transport(url), _cloning=True)
1852
def initialize_on_transport(self, transport, _cloning=False):
1853
"""Format 5 dirs always have working tree, branch and repository.
1855
Except when they are being cloned.
1857
from bzrlib.branch import BzrBranchFormat4
1858
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1859
result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
1860
RepositoryFormat5().initialize(result, _internal=True)
1862
branch = BzrBranchFormat4().initialize(result)
1863
result._init_workingtree()
1866
def network_name(self):
1867
return self.get_format_string()
1869
def _open(self, transport):
1870
"""See BzrDirFormat._open."""
1871
return BzrDir5(transport, self)
1873
def __return_repository_format(self):
1874
"""Circular import protection."""
1875
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1876
return RepositoryFormat5()
1877
repository_format = property(__return_repository_format)
1880
class BzrDirFormat6(BzrDirFormatAllInOne):
1881
"""Bzr control format 6.
1883
This format is a combined format for working tree, branch and repository.
1885
- Format 2 working trees [always]
1886
- Format 4 branches [always]
1887
- Format 6 repositories [always]
1890
_lock_class = lockable_files.TransportLock
1892
def get_format_string(self):
1893
"""See BzrDirFormat.get_format_string()."""
1894
return "Bazaar-NG branch, format 6\n"
1896
def get_format_description(self):
1897
"""See BzrDirFormat.get_format_description()."""
1898
return "All-in-one format 6"
1900
def get_branch_format(self):
1901
from bzrlib import branch
1902
return branch.BzrBranchFormat4()
1904
def get_converter(self, format=None):
1905
"""See BzrDirFormat.get_converter()."""
1906
# there is one and only one upgrade path here.
1907
return ConvertBzrDir6ToMeta()
1909
def _initialize_for_clone(self, url):
1910
return self.initialize_on_transport(
1911
_mod_transport.get_transport(url), _cloning=True)
1913
def initialize_on_transport(self, transport, _cloning=False):
1914
"""Format 6 dirs always have working tree, branch and repository.
1916
Except when they are being cloned.
1918
from bzrlib.branch import BzrBranchFormat4
1919
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1920
result = super(BzrDirFormat6, self).initialize_on_transport(transport)
1921
RepositoryFormat6().initialize(result, _internal=True)
1923
branch = BzrBranchFormat4().initialize(result)
1924
result._init_workingtree()
1927
def network_name(self):
1928
return self.get_format_string()
1930
def _open(self, transport):
1931
"""See BzrDirFormat._open."""
1932
return BzrDir6(transport, self)
1934
def __return_repository_format(self):
1935
"""Circular import protection."""
1936
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1937
return RepositoryFormat6()
1938
repository_format = property(__return_repository_format)
1610
1941
class BzrDirMetaFormat1(BzrDirFormat):
1611
1942
"""Bzr meta control format 1
1821
2146
# Register bzr formats
1822
BzrProber.formats.register(BzrDirMetaFormat1.get_format_string(),
1824
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1827
class ConvertMetaToMeta(controldir.Converter):
2147
BzrDirFormat.register_format(BzrDirFormat4())
2148
BzrDirFormat.register_format(BzrDirFormat5())
2149
BzrDirFormat.register_format(BzrDirFormat6())
2150
__default_format = BzrDirMetaFormat1()
2151
BzrDirFormat.register_format(__default_format)
2152
controldir.ControlDirFormat._default_format = __default_format
2155
class Converter(object):
2156
"""Converts a disk format object from one format to another."""
2158
def convert(self, to_convert, pb):
2159
"""Perform the conversion of to_convert, giving feedback via pb.
2161
:param to_convert: The disk object to convert.
2162
:param pb: a progress bar to use for progress information.
2165
def step(self, message):
2166
"""Update the pb by a step."""
2168
self.pb.update(message, self.count, self.total)
2171
class ConvertBzrDir4To5(Converter):
2172
"""Converts format 4 bzr dirs to format 5."""
2175
super(ConvertBzrDir4To5, self).__init__()
2176
self.converted_revs = set()
2177
self.absent_revisions = set()
2181
def convert(self, to_convert, pb):
2182
"""See Converter.convert()."""
2183
self.bzrdir = to_convert
2185
warnings.warn("pb parameter to convert() is deprecated")
2186
self.pb = ui.ui_factory.nested_progress_bar()
2188
ui.ui_factory.note('starting upgrade from format 4 to 5')
2189
if isinstance(self.bzrdir.transport, local.LocalTransport):
2190
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2191
self._convert_to_weaves()
2192
return BzrDir.open(self.bzrdir.user_url)
2196
def _convert_to_weaves(self):
2197
ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2200
stat = self.bzrdir.transport.stat('weaves')
2201
if not S_ISDIR(stat.st_mode):
2202
self.bzrdir.transport.delete('weaves')
2203
self.bzrdir.transport.mkdir('weaves')
2204
except errors.NoSuchFile:
2205
self.bzrdir.transport.mkdir('weaves')
2206
# deliberately not a WeaveFile as we want to build it up slowly.
2207
self.inv_weave = Weave('inventory')
2208
# holds in-memory weaves for all files
2209
self.text_weaves = {}
2210
self.bzrdir.transport.delete('branch-format')
2211
self.branch = self.bzrdir.open_branch()
2212
self._convert_working_inv()
2213
rev_history = self.branch.revision_history()
2214
# to_read is a stack holding the revisions we still need to process;
2215
# appending to it adds new highest-priority revisions
2216
self.known_revisions = set(rev_history)
2217
self.to_read = rev_history[-1:]
2219
rev_id = self.to_read.pop()
2220
if (rev_id not in self.revisions
2221
and rev_id not in self.absent_revisions):
2222
self._load_one_rev(rev_id)
2224
to_import = self._make_order()
2225
for i, rev_id in enumerate(to_import):
2226
self.pb.update('converting revision', i, len(to_import))
2227
self._convert_one_rev(rev_id)
2229
self._write_all_weaves()
2230
self._write_all_revs()
2231
ui.ui_factory.note('upgraded to weaves:')
2232
ui.ui_factory.note(' %6d revisions and inventories' % len(self.revisions))
2233
ui.ui_factory.note(' %6d revisions not present' % len(self.absent_revisions))
2234
ui.ui_factory.note(' %6d texts' % self.text_count)
2235
self._cleanup_spare_files_after_format4()
2236
self.branch._transport.put_bytes(
2238
BzrDirFormat5().get_format_string(),
2239
mode=self.bzrdir._get_file_mode())
2241
def _cleanup_spare_files_after_format4(self):
2242
# FIXME working tree upgrade foo.
2243
for n in 'merged-patches', 'pending-merged-patches':
2245
## assert os.path.getsize(p) == 0
2246
self.bzrdir.transport.delete(n)
2247
except errors.NoSuchFile:
2249
self.bzrdir.transport.delete_tree('inventory-store')
2250
self.bzrdir.transport.delete_tree('text-store')
2252
def _convert_working_inv(self):
2253
inv = xml4.serializer_v4.read_inventory(
2254
self.branch._transport.get('inventory'))
2255
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv, working=True)
2256
self.branch._transport.put_bytes('inventory', new_inv_xml,
2257
mode=self.bzrdir._get_file_mode())
2259
def _write_all_weaves(self):
2260
controlweaves = VersionedFileStore(self.bzrdir.transport, prefixed=False,
2261
versionedfile_class=WeaveFile)
2262
weave_transport = self.bzrdir.transport.clone('weaves')
2263
weaves = VersionedFileStore(weave_transport, prefixed=False,
2264
versionedfile_class=WeaveFile)
2265
transaction = WriteTransaction()
2269
for file_id, file_weave in self.text_weaves.items():
2270
self.pb.update('writing weave', i, len(self.text_weaves))
2271
weaves._put_weave(file_id, file_weave, transaction)
2273
self.pb.update('inventory', 0, 1)
2274
controlweaves._put_weave('inventory', self.inv_weave, transaction)
2275
self.pb.update('inventory', 1, 1)
2279
def _write_all_revs(self):
2280
"""Write all revisions out in new form."""
2281
self.bzrdir.transport.delete_tree('revision-store')
2282
self.bzrdir.transport.mkdir('revision-store')
2283
revision_transport = self.bzrdir.transport.clone('revision-store')
2285
from bzrlib.xml5 import serializer_v5
2286
from bzrlib.repofmt.weaverepo import RevisionTextStore
2287
revision_store = RevisionTextStore(revision_transport,
2288
serializer_v5, False, versionedfile.PrefixMapper(),
2289
lambda:True, lambda:True)
2291
for i, rev_id in enumerate(self.converted_revs):
2292
self.pb.update('write revision', i, len(self.converted_revs))
2293
text = serializer_v5.write_revision_to_string(
2294
self.revisions[rev_id])
2296
revision_store.add_lines(key, None, osutils.split_lines(text))
2300
def _load_one_rev(self, rev_id):
2301
"""Load a revision object into memory.
2303
Any parents not either loaded or abandoned get queued to be
2305
self.pb.update('loading revision',
2306
len(self.revisions),
2307
len(self.known_revisions))
2308
if not self.branch.repository.has_revision(rev_id):
2310
ui.ui_factory.note('revision {%s} not present in branch; '
2311
'will be converted as a ghost' %
2313
self.absent_revisions.add(rev_id)
2315
rev = self.branch.repository.get_revision(rev_id)
2316
for parent_id in rev.parent_ids:
2317
self.known_revisions.add(parent_id)
2318
self.to_read.append(parent_id)
2319
self.revisions[rev_id] = rev
2321
def _load_old_inventory(self, rev_id):
2322
f = self.branch.repository.inventory_store.get(rev_id)
2324
old_inv_xml = f.read()
2327
inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2328
inv.revision_id = rev_id
2329
rev = self.revisions[rev_id]
2332
def _load_updated_inventory(self, rev_id):
2333
inv_xml = self.inv_weave.get_text(rev_id)
2334
inv = xml5.serializer_v5.read_inventory_from_string(inv_xml, rev_id)
2337
def _convert_one_rev(self, rev_id):
2338
"""Convert revision and all referenced objects to new format."""
2339
rev = self.revisions[rev_id]
2340
inv = self._load_old_inventory(rev_id)
2341
present_parents = [p for p in rev.parent_ids
2342
if p not in self.absent_revisions]
2343
self._convert_revision_contents(rev, inv, present_parents)
2344
self._store_new_inv(rev, inv, present_parents)
2345
self.converted_revs.add(rev_id)
2347
def _store_new_inv(self, rev, inv, present_parents):
2348
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
2349
new_inv_sha1 = sha_string(new_inv_xml)
2350
self.inv_weave.add_lines(rev.revision_id,
2352
new_inv_xml.splitlines(True))
2353
rev.inventory_sha1 = new_inv_sha1
2355
def _convert_revision_contents(self, rev, inv, present_parents):
2356
"""Convert all the files within a revision.
2358
Also upgrade the inventory to refer to the text revision ids."""
2359
rev_id = rev.revision_id
2360
mutter('converting texts of revision {%s}',
2362
parent_invs = map(self._load_updated_inventory, present_parents)
2363
entries = inv.iter_entries()
2365
for path, ie in entries:
2366
self._convert_file_version(rev, ie, parent_invs)
2368
def _convert_file_version(self, rev, ie, parent_invs):
2369
"""Convert one version of one file.
2371
The file needs to be added into the weave if it is a merge
2372
of >=2 parents or if it's changed from its parent.
2374
file_id = ie.file_id
2375
rev_id = rev.revision_id
2376
w = self.text_weaves.get(file_id)
2379
self.text_weaves[file_id] = w
2380
text_changed = False
2381
parent_candiate_entries = ie.parent_candidates(parent_invs)
2382
heads = graph.Graph(self).heads(parent_candiate_entries.keys())
2383
# XXX: Note that this is unordered - and this is tolerable because
2384
# the previous code was also unordered.
2385
previous_entries = dict((head, parent_candiate_entries[head]) for head
2387
self.snapshot_ie(previous_entries, ie, w, rev_id)
2389
def get_parent_map(self, revision_ids):
2390
"""See graph.StackedParentsProvider.get_parent_map"""
2391
return dict((revision_id, self.revisions[revision_id])
2392
for revision_id in revision_ids
2393
if revision_id in self.revisions)
2395
def snapshot_ie(self, previous_revisions, ie, w, rev_id):
2396
# TODO: convert this logic, which is ~= snapshot to
2397
# a call to:. This needs the path figured out. rather than a work_tree
2398
# a v4 revision_tree can be given, or something that looks enough like
2399
# one to give the file content to the entry if it needs it.
2400
# and we need something that looks like a weave store for snapshot to
2402
#ie.snapshot(rev, PATH, previous_revisions, REVISION_TREE, InMemoryWeaveStore(self.text_weaves))
2403
if len(previous_revisions) == 1:
2404
previous_ie = previous_revisions.values()[0]
2405
if ie._unchanged(previous_ie):
2406
ie.revision = previous_ie.revision
2409
f = self.branch.repository._text_store.get(ie.text_id)
2411
file_lines = f.readlines()
2414
w.add_lines(rev_id, previous_revisions, file_lines)
2415
self.text_count += 1
2417
w.add_lines(rev_id, previous_revisions, [])
2418
ie.revision = rev_id
2420
def _make_order(self):
2421
"""Return a suitable order for importing revisions.
2423
The order must be such that an revision is imported after all
2424
its (present) parents.
2426
todo = set(self.revisions.keys())
2427
done = self.absent_revisions.copy()
2430
# scan through looking for a revision whose parents
2432
for rev_id in sorted(list(todo)):
2433
rev = self.revisions[rev_id]
2434
parent_ids = set(rev.parent_ids)
2435
if parent_ids.issubset(done):
2436
# can take this one now
2437
order.append(rev_id)
2443
class ConvertBzrDir5To6(Converter):
2444
"""Converts format 5 bzr dirs to format 6."""
2446
def convert(self, to_convert, pb):
2447
"""See Converter.convert()."""
2448
self.bzrdir = to_convert
2449
pb = ui.ui_factory.nested_progress_bar()
2451
ui.ui_factory.note('starting upgrade from format 5 to 6')
2452
self._convert_to_prefixed()
2453
return BzrDir.open(self.bzrdir.user_url)
2457
def _convert_to_prefixed(self):
2458
from bzrlib.store import TransportStore
2459
self.bzrdir.transport.delete('branch-format')
2460
for store_name in ["weaves", "revision-store"]:
2461
ui.ui_factory.note("adding prefixes to %s" % store_name)
2462
store_transport = self.bzrdir.transport.clone(store_name)
2463
store = TransportStore(store_transport, prefixed=True)
2464
for urlfilename in store_transport.list_dir('.'):
2465
filename = urlutils.unescape(urlfilename)
2466
if (filename.endswith(".weave") or
2467
filename.endswith(".gz") or
2468
filename.endswith(".sig")):
2469
file_id, suffix = os.path.splitext(filename)
2473
new_name = store._mapper.map((file_id,)) + suffix
2474
# FIXME keep track of the dirs made RBC 20060121
2476
store_transport.move(filename, new_name)
2477
except errors.NoSuchFile: # catches missing dirs strangely enough
2478
store_transport.mkdir(osutils.dirname(new_name))
2479
store_transport.move(filename, new_name)
2480
self.bzrdir.transport.put_bytes(
2482
BzrDirFormat6().get_format_string(),
2483
mode=self.bzrdir._get_file_mode())
2486
class ConvertBzrDir6ToMeta(Converter):
2487
"""Converts format 6 bzr dirs to metadirs."""
2489
def convert(self, to_convert, pb):
2490
"""See Converter.convert()."""
2491
from bzrlib.repofmt.weaverepo import RepositoryFormat7
2492
from bzrlib.branch import BzrBranchFormat5
2493
self.bzrdir = to_convert
2494
self.pb = ui.ui_factory.nested_progress_bar()
2496
self.total = 20 # the steps we know about
2497
self.garbage_inventories = []
2498
self.dir_mode = self.bzrdir._get_dir_mode()
2499
self.file_mode = self.bzrdir._get_file_mode()
2501
ui.ui_factory.note('starting upgrade from format 6 to metadir')
2502
self.bzrdir.transport.put_bytes(
2504
"Converting to format 6",
2505
mode=self.file_mode)
2506
# its faster to move specific files around than to open and use the apis...
2507
# first off, nuke ancestry.weave, it was never used.
2509
self.step('Removing ancestry.weave')
2510
self.bzrdir.transport.delete('ancestry.weave')
2511
except errors.NoSuchFile:
2513
# find out whats there
2514
self.step('Finding branch files')
2515
last_revision = self.bzrdir.open_branch().last_revision()
2516
bzrcontents = self.bzrdir.transport.list_dir('.')
2517
for name in bzrcontents:
2518
if name.startswith('basis-inventory.'):
2519
self.garbage_inventories.append(name)
2520
# create new directories for repository, working tree and branch
2521
repository_names = [('inventory.weave', True),
2522
('revision-store', True),
2524
self.step('Upgrading repository ')
2525
self.bzrdir.transport.mkdir('repository', mode=self.dir_mode)
2526
self.make_lock('repository')
2527
# we hard code the formats here because we are converting into
2528
# the meta format. The meta format upgrader can take this to a
2529
# future format within each component.
2530
self.put_format('repository', RepositoryFormat7())
2531
for entry in repository_names:
2532
self.move_entry('repository', entry)
2534
self.step('Upgrading branch ')
2535
self.bzrdir.transport.mkdir('branch', mode=self.dir_mode)
2536
self.make_lock('branch')
2537
self.put_format('branch', BzrBranchFormat5())
2538
branch_files = [('revision-history', True),
2539
('branch-name', True),
2541
for entry in branch_files:
2542
self.move_entry('branch', entry)
2544
checkout_files = [('pending-merges', True),
2545
('inventory', True),
2546
('stat-cache', False)]
2547
# If a mandatory checkout file is not present, the branch does not have
2548
# a functional checkout. Do not create a checkout in the converted
2550
for name, mandatory in checkout_files:
2551
if mandatory and name not in bzrcontents:
2552
has_checkout = False
2556
if not has_checkout:
2557
ui.ui_factory.note('No working tree.')
2558
# If some checkout files are there, we may as well get rid of them.
2559
for name, mandatory in checkout_files:
2560
if name in bzrcontents:
2561
self.bzrdir.transport.delete(name)
2563
from bzrlib.workingtree import WorkingTreeFormat3
2564
self.step('Upgrading working tree')
2565
self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
2566
self.make_lock('checkout')
2568
'checkout', WorkingTreeFormat3())
2569
self.bzrdir.transport.delete_multi(
2570
self.garbage_inventories, self.pb)
2571
for entry in checkout_files:
2572
self.move_entry('checkout', entry)
2573
if last_revision is not None:
2574
self.bzrdir.transport.put_bytes(
2575
'checkout/last-revision', last_revision)
2576
self.bzrdir.transport.put_bytes(
2578
BzrDirMetaFormat1().get_format_string(),
2579
mode=self.file_mode)
2581
return BzrDir.open(self.bzrdir.user_url)
2583
def make_lock(self, name):
2584
"""Make a lock for the new control dir name."""
2585
self.step('Make %s lock' % name)
2586
ld = lockdir.LockDir(self.bzrdir.transport,
2588
file_modebits=self.file_mode,
2589
dir_modebits=self.dir_mode)
2592
def move_entry(self, new_dir, entry):
2593
"""Move then entry name into new_dir."""
2595
mandatory = entry[1]
2596
self.step('Moving %s' % name)
2598
self.bzrdir.transport.move(name, '%s/%s' % (new_dir, name))
2599
except errors.NoSuchFile:
2603
def put_format(self, dirname, format):
2604
self.bzrdir.transport.put_bytes('%s/format' % dirname,
2605
format.get_format_string(),
2609
class ConvertMetaToMeta(Converter):
1828
2610
"""Converts the components of metadirs."""
1830
2612
def __init__(self, target_format):
1902
2685
return to_convert
2688
# This is not in remote.py because it's relatively small, and needs to be
2689
# registered. Putting it in remote.py creates a circular import problem.
2690
# we can make it a lazy object if the control formats is turned into something
2692
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2693
"""Format representing bzrdirs accessed via a smart server"""
2695
supports_workingtrees = False
2698
BzrDirMetaFormat1.__init__(self)
2699
# XXX: It's a bit ugly that the network name is here, because we'd
2700
# like to believe that format objects are stateless or at least
2701
# immutable, However, we do at least avoid mutating the name after
2702
# it's returned. See <https://bugs.launchpad.net/bzr/+bug/504102>
2703
self._network_name = None
2706
return "%s(_network_name=%r)" % (self.__class__.__name__,
2709
def get_format_description(self):
2710
if self._network_name:
2711
real_format = controldir.network_format_registry.get(self._network_name)
2712
return 'Remote: ' + real_format.get_format_description()
2713
return 'bzr remote bzrdir'
2715
def get_format_string(self):
2716
raise NotImplementedError(self.get_format_string)
2718
def network_name(self):
2719
if self._network_name:
2720
return self._network_name
2722
raise AssertionError("No network name set.")
2724
def initialize_on_transport(self, transport):
2726
# hand off the request to the smart server
2727
client_medium = transport.get_smart_medium()
2728
except errors.NoSmartMedium:
2729
# TODO: lookup the local format from a server hint.
2730
local_dir_format = BzrDirMetaFormat1()
2731
return local_dir_format.initialize_on_transport(transport)
2732
client = _SmartClient(client_medium)
2733
path = client.remote_path_from_transport(transport)
2735
response = client.call('BzrDirFormat.initialize', path)
2736
except errors.ErrorFromSmartServer, err:
2737
remote._translate_error(err, path=path)
2738
if response[0] != 'ok':
2739
raise errors.SmartProtocolError('unexpected response code %s' % (response,))
2740
format = RemoteBzrDirFormat()
2741
self._supply_sub_formats_to(format)
2742
return remote.RemoteBzrDir(transport, format)
2744
def parse_NoneTrueFalse(self, arg):
2751
raise AssertionError("invalid arg %r" % arg)
2753
def _serialize_NoneTrueFalse(self, arg):
2760
def _serialize_NoneString(self, arg):
2763
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
2764
create_prefix=False, force_new_repo=False, stacked_on=None,
2765
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
2768
# hand off the request to the smart server
2769
client_medium = transport.get_smart_medium()
2770
except errors.NoSmartMedium:
2773
# Decline to open it if the server doesn't support our required
2774
# version (3) so that the VFS-based transport will do it.
2775
if client_medium.should_probe():
2777
server_version = client_medium.protocol_version()
2778
if server_version != '2':
2782
except errors.SmartProtocolError:
2783
# Apparently there's no usable smart server there, even though
2784
# the medium supports the smart protocol.
2789
client = _SmartClient(client_medium)
2790
path = client.remote_path_from_transport(transport)
2791
if client_medium._is_remote_before((1, 16)):
2794
# TODO: lookup the local format from a server hint.
2795
local_dir_format = BzrDirMetaFormat1()
2796
self._supply_sub_formats_to(local_dir_format)
2797
return local_dir_format.initialize_on_transport_ex(transport,
2798
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2799
force_new_repo=force_new_repo, stacked_on=stacked_on,
2800
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2801
make_working_trees=make_working_trees, shared_repo=shared_repo,
2803
return self._initialize_on_transport_ex_rpc(client, path, transport,
2804
use_existing_dir, create_prefix, force_new_repo, stacked_on,
2805
stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
2807
def _initialize_on_transport_ex_rpc(self, client, path, transport,
2808
use_existing_dir, create_prefix, force_new_repo, stacked_on,
2809
stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
2811
args.append(self._serialize_NoneTrueFalse(use_existing_dir))
2812
args.append(self._serialize_NoneTrueFalse(create_prefix))
2813
args.append(self._serialize_NoneTrueFalse(force_new_repo))
2814
args.append(self._serialize_NoneString(stacked_on))
2815
# stack_on_pwd is often/usually our transport
2818
stack_on_pwd = transport.relpath(stack_on_pwd)
2819
if not stack_on_pwd:
2821
except errors.PathNotChild:
2823
args.append(self._serialize_NoneString(stack_on_pwd))
2824
args.append(self._serialize_NoneString(repo_format_name))
2825
args.append(self._serialize_NoneTrueFalse(make_working_trees))
2826
args.append(self._serialize_NoneTrueFalse(shared_repo))
2827
request_network_name = self._network_name or \
2828
BzrDirFormat.get_default_format().network_name()
2830
response = client.call('BzrDirFormat.initialize_ex_1.16',
2831
request_network_name, path, *args)
2832
except errors.UnknownSmartMethod:
2833
client._medium._remember_remote_is_before((1,16))
2834
local_dir_format = BzrDirMetaFormat1()
2835
self._supply_sub_formats_to(local_dir_format)
2836
return local_dir_format.initialize_on_transport_ex(transport,
2837
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2838
force_new_repo=force_new_repo, stacked_on=stacked_on,
2839
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2840
make_working_trees=make_working_trees, shared_repo=shared_repo,
2842
except errors.ErrorFromSmartServer, err:
2843
remote._translate_error(err, path=path)
2844
repo_path = response[0]
2845
bzrdir_name = response[6]
2846
require_stacking = response[7]
2847
require_stacking = self.parse_NoneTrueFalse(require_stacking)
2848
format = RemoteBzrDirFormat()
2849
format._network_name = bzrdir_name
2850
self._supply_sub_formats_to(format)
2851
bzrdir = remote.RemoteBzrDir(transport, format, _client=client)
2853
repo_format = remote.response_tuple_to_repo_format(response[1:])
2854
if repo_path == '.':
2857
repo_bzrdir_format = RemoteBzrDirFormat()
2858
repo_bzrdir_format._network_name = response[5]
2859
repo_bzr = remote.RemoteBzrDir(transport.clone(repo_path),
2863
final_stack = response[8] or None
2864
final_stack_pwd = response[9] or None
2866
final_stack_pwd = urlutils.join(
2867
transport.base, final_stack_pwd)
2868
remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
2869
if len(response) > 10:
2870
# Updated server verb that locks remotely.
2871
repo_lock_token = response[10] or None
2872
remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
2874
remote_repo.dont_leave_lock_in_place()
2876
remote_repo.lock_write()
2877
policy = UseExistingRepository(remote_repo, final_stack,
2878
final_stack_pwd, require_stacking)
2879
policy.acquire_repository()
2883
bzrdir._format.set_branch_format(self.get_branch_format())
2884
if require_stacking:
2885
# The repo has already been created, but we need to make sure that
2886
# we'll make a stackable branch.
2887
bzrdir._format.require_stacking(_skip_repo=True)
2888
return remote_repo, bzrdir, require_stacking, policy
2890
def _open(self, transport):
2891
return remote.RemoteBzrDir(transport, self)
2893
def __eq__(self, other):
2894
if not isinstance(other, RemoteBzrDirFormat):
2896
return self.get_format_description() == other.get_format_description()
2898
def __return_repository_format(self):
2899
# Always return a RemoteRepositoryFormat object, but if a specific bzr
2900
# repository format has been asked for, tell the RemoteRepositoryFormat
2901
# that it should use that for init() etc.
2902
result = remote.RemoteRepositoryFormat()
2903
custom_format = getattr(self, '_repository_format', None)
2905
if isinstance(custom_format, remote.RemoteRepositoryFormat):
2906
return custom_format
2908
# We will use the custom format to create repositories over the
2909
# wire; expose its details like rich_root_data for code to
2911
result._custom_format = custom_format
2914
def get_branch_format(self):
2915
result = BzrDirMetaFormat1.get_branch_format(self)
2916
if not isinstance(result, remote.RemoteBranchFormat):
2917
new_result = remote.RemoteBranchFormat()
2918
new_result._custom_format = result
2920
self.set_branch_format(new_result)
2924
repository_format = property(__return_repository_format,
2925
BzrDirMetaFormat1._set_repository_format) #.im_func)
1905
2928
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
2144
3184
'network operations. Additionally adds support for versioning nested '
2145
3185
'bzr branches. Incompatible with bzr < 0.15.',
2146
3186
branch_format='bzrlib.branch.BzrBranchFormat6',
2147
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3187
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2148
3188
experimental=True,
2151
3191
register_metadir(controldir.format_registry, 'pack-0.92',
2152
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
3192
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
2153
3193
help='New in 0.92: Pack-based format with data compatible with '
2154
3194
'dirstate-tags format repositories. Interoperates with '
2155
3195
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2157
3197
branch_format='bzrlib.branch.BzrBranchFormat6',
2158
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3198
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2160
3200
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2161
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
3201
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
2162
3202
help='New in 0.92: Pack-based format with data compatible with '
2163
3203
'dirstate-with-subtree format repositories. Interoperates with '
2164
3204
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2166
3206
branch_format='bzrlib.branch.BzrBranchFormat6',
2167
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3207
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2169
3209
experimental=True,
2171
3211
register_metadir(controldir.format_registry, 'rich-root-pack',
2172
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
3212
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
2173
3213
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
2174
3214
'(needed for bzr-svn and bzr-git).',
2175
3215
branch_format='bzrlib.branch.BzrBranchFormat6',
2176
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3216
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2179
3219
register_metadir(controldir.format_registry, '1.6',
2180
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
3220
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
2181
3221
help='A format that allows a branch to indicate that there is another '
2182
3222
'(stacked) repository that should be used to access data that is '
2183
3223
'not present locally.',
2184
3224
branch_format='bzrlib.branch.BzrBranchFormat7',
2185
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3225
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2188
3228
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2189
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
3229
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
2190
3230
help='A variant of 1.6 that supports rich-root data '
2191
3231
'(needed for bzr-svn and bzr-git).',
2192
3232
branch_format='bzrlib.branch.BzrBranchFormat7',
2193
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3233
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2196
3236
register_metadir(controldir.format_registry, '1.9',
2197
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
3237
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
2198
3238
help='A repository format using B+tree indexes. These indexes '
2199
3239
'are smaller in size, have smarter caching and provide faster '
2200
3240
'performance for most operations.',
2201
3241
branch_format='bzrlib.branch.BzrBranchFormat7',
2202
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3242
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2205
3245
register_metadir(controldir.format_registry, '1.9-rich-root',
2206
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
3246
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
2207
3247
help='A variant of 1.9 that supports rich-root data '
2208
3248
'(needed for bzr-svn and bzr-git).',
2209
3249
branch_format='bzrlib.branch.BzrBranchFormat7',
2210
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3250
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2213
3253
register_metadir(controldir.format_registry, '1.14',
2214
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
3254
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
2215
3255
help='A working-tree format that supports content filtering.',
2216
3256
branch_format='bzrlib.branch.BzrBranchFormat7',
2217
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
3257
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2219
3259
register_metadir(controldir.format_registry, '1.14-rich-root',
2220
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
3260
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
2221
3261
help='A variant of 1.14 that supports rich-root data '
2222
3262
'(needed for bzr-svn and bzr-git).',
2223
3263
branch_format='bzrlib.branch.BzrBranchFormat7',
2224
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
3264
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2226
3266
# The following un-numbered 'development' formats should always just be aliases.
2227
3267
register_metadir(controldir.format_registry, 'development-subtree',