390
437
policy = self.determine_repository_policy(force_new_repo)
391
438
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
441
def create_branch_convenience(base, force_new_repo=False,
549
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)
1136
1259
class BzrDirMeta1(BzrDir):
1137
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(get_transport(url), _cloning=True)
1851
def initialize_on_transport(self, transport, _cloning=False):
1852
"""Format 5 dirs always have working tree, branch and repository.
1854
Except when they are being cloned.
1856
from bzrlib.branch import BzrBranchFormat4
1857
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1858
result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
1859
RepositoryFormat5().initialize(result, _internal=True)
1861
branch = BzrBranchFormat4().initialize(result)
1862
result._init_workingtree()
1865
def network_name(self):
1866
return self.get_format_string()
1868
def _open(self, transport):
1869
"""See BzrDirFormat._open."""
1870
return BzrDir5(transport, self)
1872
def __return_repository_format(self):
1873
"""Circular import protection."""
1874
from bzrlib.repofmt.weaverepo import RepositoryFormat5
1875
return RepositoryFormat5()
1876
repository_format = property(__return_repository_format)
1879
class BzrDirFormat6(BzrDirFormatAllInOne):
1880
"""Bzr control format 6.
1882
This format is a combined format for working tree, branch and repository.
1884
- Format 2 working trees [always]
1885
- Format 4 branches [always]
1886
- Format 6 repositories [always]
1889
_lock_class = lockable_files.TransportLock
1891
def get_format_string(self):
1892
"""See BzrDirFormat.get_format_string()."""
1893
return "Bazaar-NG branch, format 6\n"
1895
def get_format_description(self):
1896
"""See BzrDirFormat.get_format_description()."""
1897
return "All-in-one format 6"
1899
def get_branch_format(self):
1900
from bzrlib import branch
1901
return branch.BzrBranchFormat4()
1903
def get_converter(self, format=None):
1904
"""See BzrDirFormat.get_converter()."""
1905
# there is one and only one upgrade path here.
1906
return ConvertBzrDir6ToMeta()
1908
def _initialize_for_clone(self, url):
1909
return self.initialize_on_transport(get_transport(url), _cloning=True)
1911
def initialize_on_transport(self, transport, _cloning=False):
1912
"""Format 6 dirs always have working tree, branch and repository.
1914
Except when they are being cloned.
1916
from bzrlib.branch import BzrBranchFormat4
1917
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1918
result = super(BzrDirFormat6, self).initialize_on_transport(transport)
1919
RepositoryFormat6().initialize(result, _internal=True)
1921
branch = BzrBranchFormat4().initialize(result)
1922
result._init_workingtree()
1925
def network_name(self):
1926
return self.get_format_string()
1928
def _open(self, transport):
1929
"""See BzrDirFormat._open."""
1930
return BzrDir6(transport, self)
1932
def __return_repository_format(self):
1933
"""Circular import protection."""
1934
from bzrlib.repofmt.weaverepo import RepositoryFormat6
1935
return RepositoryFormat6()
1936
repository_format = property(__return_repository_format)
1615
1939
class BzrDirMetaFormat1(BzrDirFormat):
1616
1940
"""Bzr meta control format 1
1618
1942
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]
1945
- Format 3 working trees [optional]
1946
- Format 5 branches [optional]
1947
- Format 7 repositories [optional]
1628
1950
_lock_class = lockdir.LockDir
1630
fixed_components = False
1632
1952
def __init__(self):
1633
1953
self._workingtree_format = None
1634
1954
self._branch_format = None
1828
2144
# Register bzr formats
1829
BzrProber.formats.register(BzrDirMetaFormat1.get_format_string(),
1831
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1834
class ConvertMetaToMeta(controldir.Converter):
2145
BzrDirFormat.register_format(BzrDirFormat4())
2146
BzrDirFormat.register_format(BzrDirFormat5())
2147
BzrDirFormat.register_format(BzrDirFormat6())
2148
__default_format = BzrDirMetaFormat1()
2149
BzrDirFormat.register_format(__default_format)
2150
controldir.ControlDirFormat._default_format = __default_format
2153
class Converter(object):
2154
"""Converts a disk format object from one format to another."""
2156
def convert(self, to_convert, pb):
2157
"""Perform the conversion of to_convert, giving feedback via pb.
2159
:param to_convert: The disk object to convert.
2160
:param pb: a progress bar to use for progress information.
2163
def step(self, message):
2164
"""Update the pb by a step."""
2166
self.pb.update(message, self.count, self.total)
2169
class ConvertBzrDir4To5(Converter):
2170
"""Converts format 4 bzr dirs to format 5."""
2173
super(ConvertBzrDir4To5, self).__init__()
2174
self.converted_revs = set()
2175
self.absent_revisions = set()
2179
def convert(self, to_convert, pb):
2180
"""See Converter.convert()."""
2181
self.bzrdir = to_convert
2183
warnings.warn("pb parameter to convert() is deprecated")
2184
self.pb = ui.ui_factory.nested_progress_bar()
2186
ui.ui_factory.note('starting upgrade from format 4 to 5')
2187
if isinstance(self.bzrdir.transport, local.LocalTransport):
2188
self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2189
self._convert_to_weaves()
2190
return BzrDir.open(self.bzrdir.user_url)
2194
def _convert_to_weaves(self):
2195
ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
2198
stat = self.bzrdir.transport.stat('weaves')
2199
if not S_ISDIR(stat.st_mode):
2200
self.bzrdir.transport.delete('weaves')
2201
self.bzrdir.transport.mkdir('weaves')
2202
except errors.NoSuchFile:
2203
self.bzrdir.transport.mkdir('weaves')
2204
# deliberately not a WeaveFile as we want to build it up slowly.
2205
self.inv_weave = Weave('inventory')
2206
# holds in-memory weaves for all files
2207
self.text_weaves = {}
2208
self.bzrdir.transport.delete('branch-format')
2209
self.branch = self.bzrdir.open_branch()
2210
self._convert_working_inv()
2211
rev_history = self.branch.revision_history()
2212
# to_read is a stack holding the revisions we still need to process;
2213
# appending to it adds new highest-priority revisions
2214
self.known_revisions = set(rev_history)
2215
self.to_read = rev_history[-1:]
2217
rev_id = self.to_read.pop()
2218
if (rev_id not in self.revisions
2219
and rev_id not in self.absent_revisions):
2220
self._load_one_rev(rev_id)
2222
to_import = self._make_order()
2223
for i, rev_id in enumerate(to_import):
2224
self.pb.update('converting revision', i, len(to_import))
2225
self._convert_one_rev(rev_id)
2227
self._write_all_weaves()
2228
self._write_all_revs()
2229
ui.ui_factory.note('upgraded to weaves:')
2230
ui.ui_factory.note(' %6d revisions and inventories' % len(self.revisions))
2231
ui.ui_factory.note(' %6d revisions not present' % len(self.absent_revisions))
2232
ui.ui_factory.note(' %6d texts' % self.text_count)
2233
self._cleanup_spare_files_after_format4()
2234
self.branch._transport.put_bytes(
2236
BzrDirFormat5().get_format_string(),
2237
mode=self.bzrdir._get_file_mode())
2239
def _cleanup_spare_files_after_format4(self):
2240
# FIXME working tree upgrade foo.
2241
for n in 'merged-patches', 'pending-merged-patches':
2243
## assert os.path.getsize(p) == 0
2244
self.bzrdir.transport.delete(n)
2245
except errors.NoSuchFile:
2247
self.bzrdir.transport.delete_tree('inventory-store')
2248
self.bzrdir.transport.delete_tree('text-store')
2250
def _convert_working_inv(self):
2251
inv = xml4.serializer_v4.read_inventory(
2252
self.branch._transport.get('inventory'))
2253
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv, working=True)
2254
self.branch._transport.put_bytes('inventory', new_inv_xml,
2255
mode=self.bzrdir._get_file_mode())
2257
def _write_all_weaves(self):
2258
controlweaves = VersionedFileStore(self.bzrdir.transport, prefixed=False,
2259
versionedfile_class=WeaveFile)
2260
weave_transport = self.bzrdir.transport.clone('weaves')
2261
weaves = VersionedFileStore(weave_transport, prefixed=False,
2262
versionedfile_class=WeaveFile)
2263
transaction = WriteTransaction()
2267
for file_id, file_weave in self.text_weaves.items():
2268
self.pb.update('writing weave', i, len(self.text_weaves))
2269
weaves._put_weave(file_id, file_weave, transaction)
2271
self.pb.update('inventory', 0, 1)
2272
controlweaves._put_weave('inventory', self.inv_weave, transaction)
2273
self.pb.update('inventory', 1, 1)
2277
def _write_all_revs(self):
2278
"""Write all revisions out in new form."""
2279
self.bzrdir.transport.delete_tree('revision-store')
2280
self.bzrdir.transport.mkdir('revision-store')
2281
revision_transport = self.bzrdir.transport.clone('revision-store')
2283
from bzrlib.xml5 import serializer_v5
2284
from bzrlib.repofmt.weaverepo import RevisionTextStore
2285
revision_store = RevisionTextStore(revision_transport,
2286
serializer_v5, False, versionedfile.PrefixMapper(),
2287
lambda:True, lambda:True)
2289
for i, rev_id in enumerate(self.converted_revs):
2290
self.pb.update('write revision', i, len(self.converted_revs))
2291
text = serializer_v5.write_revision_to_string(
2292
self.revisions[rev_id])
2294
revision_store.add_lines(key, None, osutils.split_lines(text))
2298
def _load_one_rev(self, rev_id):
2299
"""Load a revision object into memory.
2301
Any parents not either loaded or abandoned get queued to be
2303
self.pb.update('loading revision',
2304
len(self.revisions),
2305
len(self.known_revisions))
2306
if not self.branch.repository.has_revision(rev_id):
2308
ui.ui_factory.note('revision {%s} not present in branch; '
2309
'will be converted as a ghost' %
2311
self.absent_revisions.add(rev_id)
2313
rev = self.branch.repository.get_revision(rev_id)
2314
for parent_id in rev.parent_ids:
2315
self.known_revisions.add(parent_id)
2316
self.to_read.append(parent_id)
2317
self.revisions[rev_id] = rev
2319
def _load_old_inventory(self, rev_id):
2320
f = self.branch.repository.inventory_store.get(rev_id)
2322
old_inv_xml = f.read()
2325
inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
2326
inv.revision_id = rev_id
2327
rev = self.revisions[rev_id]
2330
def _load_updated_inventory(self, rev_id):
2331
inv_xml = self.inv_weave.get_text(rev_id)
2332
inv = xml5.serializer_v5.read_inventory_from_string(inv_xml, rev_id)
2335
def _convert_one_rev(self, rev_id):
2336
"""Convert revision and all referenced objects to new format."""
2337
rev = self.revisions[rev_id]
2338
inv = self._load_old_inventory(rev_id)
2339
present_parents = [p for p in rev.parent_ids
2340
if p not in self.absent_revisions]
2341
self._convert_revision_contents(rev, inv, present_parents)
2342
self._store_new_inv(rev, inv, present_parents)
2343
self.converted_revs.add(rev_id)
2345
def _store_new_inv(self, rev, inv, present_parents):
2346
new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
2347
new_inv_sha1 = sha_string(new_inv_xml)
2348
self.inv_weave.add_lines(rev.revision_id,
2350
new_inv_xml.splitlines(True))
2351
rev.inventory_sha1 = new_inv_sha1
2353
def _convert_revision_contents(self, rev, inv, present_parents):
2354
"""Convert all the files within a revision.
2356
Also upgrade the inventory to refer to the text revision ids."""
2357
rev_id = rev.revision_id
2358
mutter('converting texts of revision {%s}',
2360
parent_invs = map(self._load_updated_inventory, present_parents)
2361
entries = inv.iter_entries()
2363
for path, ie in entries:
2364
self._convert_file_version(rev, ie, parent_invs)
2366
def _convert_file_version(self, rev, ie, parent_invs):
2367
"""Convert one version of one file.
2369
The file needs to be added into the weave if it is a merge
2370
of >=2 parents or if it's changed from its parent.
2372
file_id = ie.file_id
2373
rev_id = rev.revision_id
2374
w = self.text_weaves.get(file_id)
2377
self.text_weaves[file_id] = w
2378
text_changed = False
2379
parent_candiate_entries = ie.parent_candidates(parent_invs)
2380
heads = graph.Graph(self).heads(parent_candiate_entries.keys())
2381
# XXX: Note that this is unordered - and this is tolerable because
2382
# the previous code was also unordered.
2383
previous_entries = dict((head, parent_candiate_entries[head]) for head
2385
self.snapshot_ie(previous_entries, ie, w, rev_id)
2387
def get_parent_map(self, revision_ids):
2388
"""See graph.StackedParentsProvider.get_parent_map"""
2389
return dict((revision_id, self.revisions[revision_id])
2390
for revision_id in revision_ids
2391
if revision_id in self.revisions)
2393
def snapshot_ie(self, previous_revisions, ie, w, rev_id):
2394
# TODO: convert this logic, which is ~= snapshot to
2395
# a call to:. This needs the path figured out. rather than a work_tree
2396
# a v4 revision_tree can be given, or something that looks enough like
2397
# one to give the file content to the entry if it needs it.
2398
# and we need something that looks like a weave store for snapshot to
2400
#ie.snapshot(rev, PATH, previous_revisions, REVISION_TREE, InMemoryWeaveStore(self.text_weaves))
2401
if len(previous_revisions) == 1:
2402
previous_ie = previous_revisions.values()[0]
2403
if ie._unchanged(previous_ie):
2404
ie.revision = previous_ie.revision
2407
f = self.branch.repository._text_store.get(ie.text_id)
2409
file_lines = f.readlines()
2412
w.add_lines(rev_id, previous_revisions, file_lines)
2413
self.text_count += 1
2415
w.add_lines(rev_id, previous_revisions, [])
2416
ie.revision = rev_id
2418
def _make_order(self):
2419
"""Return a suitable order for importing revisions.
2421
The order must be such that an revision is imported after all
2422
its (present) parents.
2424
todo = set(self.revisions.keys())
2425
done = self.absent_revisions.copy()
2428
# scan through looking for a revision whose parents
2430
for rev_id in sorted(list(todo)):
2431
rev = self.revisions[rev_id]
2432
parent_ids = set(rev.parent_ids)
2433
if parent_ids.issubset(done):
2434
# can take this one now
2435
order.append(rev_id)
2441
class ConvertBzrDir5To6(Converter):
2442
"""Converts format 5 bzr dirs to format 6."""
2444
def convert(self, to_convert, pb):
2445
"""See Converter.convert()."""
2446
self.bzrdir = to_convert
2447
pb = ui.ui_factory.nested_progress_bar()
2449
ui.ui_factory.note('starting upgrade from format 5 to 6')
2450
self._convert_to_prefixed()
2451
return BzrDir.open(self.bzrdir.user_url)
2455
def _convert_to_prefixed(self):
2456
from bzrlib.store import TransportStore
2457
self.bzrdir.transport.delete('branch-format')
2458
for store_name in ["weaves", "revision-store"]:
2459
ui.ui_factory.note("adding prefixes to %s" % store_name)
2460
store_transport = self.bzrdir.transport.clone(store_name)
2461
store = TransportStore(store_transport, prefixed=True)
2462
for urlfilename in store_transport.list_dir('.'):
2463
filename = urlutils.unescape(urlfilename)
2464
if (filename.endswith(".weave") or
2465
filename.endswith(".gz") or
2466
filename.endswith(".sig")):
2467
file_id, suffix = os.path.splitext(filename)
2471
new_name = store._mapper.map((file_id,)) + suffix
2472
# FIXME keep track of the dirs made RBC 20060121
2474
store_transport.move(filename, new_name)
2475
except errors.NoSuchFile: # catches missing dirs strangely enough
2476
store_transport.mkdir(osutils.dirname(new_name))
2477
store_transport.move(filename, new_name)
2478
self.bzrdir.transport.put_bytes(
2480
BzrDirFormat6().get_format_string(),
2481
mode=self.bzrdir._get_file_mode())
2484
class ConvertBzrDir6ToMeta(Converter):
2485
"""Converts format 6 bzr dirs to metadirs."""
2487
def convert(self, to_convert, pb):
2488
"""See Converter.convert()."""
2489
from bzrlib.repofmt.weaverepo import RepositoryFormat7
2490
from bzrlib.branch import BzrBranchFormat5
2491
self.bzrdir = to_convert
2492
self.pb = ui.ui_factory.nested_progress_bar()
2494
self.total = 20 # the steps we know about
2495
self.garbage_inventories = []
2496
self.dir_mode = self.bzrdir._get_dir_mode()
2497
self.file_mode = self.bzrdir._get_file_mode()
2499
ui.ui_factory.note('starting upgrade from format 6 to metadir')
2500
self.bzrdir.transport.put_bytes(
2502
"Converting to format 6",
2503
mode=self.file_mode)
2504
# its faster to move specific files around than to open and use the apis...
2505
# first off, nuke ancestry.weave, it was never used.
2507
self.step('Removing ancestry.weave')
2508
self.bzrdir.transport.delete('ancestry.weave')
2509
except errors.NoSuchFile:
2511
# find out whats there
2512
self.step('Finding branch files')
2513
last_revision = self.bzrdir.open_branch().last_revision()
2514
bzrcontents = self.bzrdir.transport.list_dir('.')
2515
for name in bzrcontents:
2516
if name.startswith('basis-inventory.'):
2517
self.garbage_inventories.append(name)
2518
# create new directories for repository, working tree and branch
2519
repository_names = [('inventory.weave', True),
2520
('revision-store', True),
2522
self.step('Upgrading repository ')
2523
self.bzrdir.transport.mkdir('repository', mode=self.dir_mode)
2524
self.make_lock('repository')
2525
# we hard code the formats here because we are converting into
2526
# the meta format. The meta format upgrader can take this to a
2527
# future format within each component.
2528
self.put_format('repository', RepositoryFormat7())
2529
for entry in repository_names:
2530
self.move_entry('repository', entry)
2532
self.step('Upgrading branch ')
2533
self.bzrdir.transport.mkdir('branch', mode=self.dir_mode)
2534
self.make_lock('branch')
2535
self.put_format('branch', BzrBranchFormat5())
2536
branch_files = [('revision-history', True),
2537
('branch-name', True),
2539
for entry in branch_files:
2540
self.move_entry('branch', entry)
2542
checkout_files = [('pending-merges', True),
2543
('inventory', True),
2544
('stat-cache', False)]
2545
# If a mandatory checkout file is not present, the branch does not have
2546
# a functional checkout. Do not create a checkout in the converted
2548
for name, mandatory in checkout_files:
2549
if mandatory and name not in bzrcontents:
2550
has_checkout = False
2554
if not has_checkout:
2555
ui.ui_factory.note('No working tree.')
2556
# If some checkout files are there, we may as well get rid of them.
2557
for name, mandatory in checkout_files:
2558
if name in bzrcontents:
2559
self.bzrdir.transport.delete(name)
2561
from bzrlib.workingtree import WorkingTreeFormat3
2562
self.step('Upgrading working tree')
2563
self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
2564
self.make_lock('checkout')
2566
'checkout', WorkingTreeFormat3())
2567
self.bzrdir.transport.delete_multi(
2568
self.garbage_inventories, self.pb)
2569
for entry in checkout_files:
2570
self.move_entry('checkout', entry)
2571
if last_revision is not None:
2572
self.bzrdir.transport.put_bytes(
2573
'checkout/last-revision', last_revision)
2574
self.bzrdir.transport.put_bytes(
2576
BzrDirMetaFormat1().get_format_string(),
2577
mode=self.file_mode)
2579
return BzrDir.open(self.bzrdir.user_url)
2581
def make_lock(self, name):
2582
"""Make a lock for the new control dir name."""
2583
self.step('Make %s lock' % name)
2584
ld = lockdir.LockDir(self.bzrdir.transport,
2586
file_modebits=self.file_mode,
2587
dir_modebits=self.dir_mode)
2590
def move_entry(self, new_dir, entry):
2591
"""Move then entry name into new_dir."""
2593
mandatory = entry[1]
2594
self.step('Moving %s' % name)
2596
self.bzrdir.transport.move(name, '%s/%s' % (new_dir, name))
2597
except errors.NoSuchFile:
2601
def put_format(self, dirname, format):
2602
self.bzrdir.transport.put_bytes('%s/format' % dirname,
2603
format.get_format_string(),
2607
class ConvertMetaToMeta(Converter):
1835
2608
"""Converts the components of metadirs."""
1837
2610
def __init__(self, target_format):
1909
2683
return to_convert
2686
# This is not in remote.py because it's relatively small, and needs to be
2687
# registered. Putting it in remote.py creates a circular import problem.
2688
# we can make it a lazy object if the control formats is turned into something
2690
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2691
"""Format representing bzrdirs accessed via a smart server"""
2693
supports_workingtrees = False
2696
BzrDirMetaFormat1.__init__(self)
2697
# XXX: It's a bit ugly that the network name is here, because we'd
2698
# like to believe that format objects are stateless or at least
2699
# immutable, However, we do at least avoid mutating the name after
2700
# it's returned. See <https://bugs.launchpad.net/bzr/+bug/504102>
2701
self._network_name = None
2704
return "%s(_network_name=%r)" % (self.__class__.__name__,
2707
def get_format_description(self):
2708
if self._network_name:
2709
real_format = controldir.network_format_registry.get(self._network_name)
2710
return 'Remote: ' + real_format.get_format_description()
2711
return 'bzr remote bzrdir'
2713
def get_format_string(self):
2714
raise NotImplementedError(self.get_format_string)
2716
def network_name(self):
2717
if self._network_name:
2718
return self._network_name
2720
raise AssertionError("No network name set.")
2722
def initialize_on_transport(self, transport):
2724
# hand off the request to the smart server
2725
client_medium = transport.get_smart_medium()
2726
except errors.NoSmartMedium:
2727
# TODO: lookup the local format from a server hint.
2728
local_dir_format = BzrDirMetaFormat1()
2729
return local_dir_format.initialize_on_transport(transport)
2730
client = _SmartClient(client_medium)
2731
path = client.remote_path_from_transport(transport)
2733
response = client.call('BzrDirFormat.initialize', path)
2734
except errors.ErrorFromSmartServer, err:
2735
remote._translate_error(err, path=path)
2736
if response[0] != 'ok':
2737
raise errors.SmartProtocolError('unexpected response code %s' % (response,))
2738
format = RemoteBzrDirFormat()
2739
self._supply_sub_formats_to(format)
2740
return remote.RemoteBzrDir(transport, format)
2742
def parse_NoneTrueFalse(self, arg):
2749
raise AssertionError("invalid arg %r" % arg)
2751
def _serialize_NoneTrueFalse(self, arg):
2758
def _serialize_NoneString(self, arg):
2761
def initialize_on_transport_ex(self, transport, use_existing_dir=False,
2762
create_prefix=False, force_new_repo=False, stacked_on=None,
2763
stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
2766
# hand off the request to the smart server
2767
client_medium = transport.get_smart_medium()
2768
except errors.NoSmartMedium:
2771
# Decline to open it if the server doesn't support our required
2772
# version (3) so that the VFS-based transport will do it.
2773
if client_medium.should_probe():
2775
server_version = client_medium.protocol_version()
2776
if server_version != '2':
2780
except errors.SmartProtocolError:
2781
# Apparently there's no usable smart server there, even though
2782
# the medium supports the smart protocol.
2787
client = _SmartClient(client_medium)
2788
path = client.remote_path_from_transport(transport)
2789
if client_medium._is_remote_before((1, 16)):
2792
# TODO: lookup the local format from a server hint.
2793
local_dir_format = BzrDirMetaFormat1()
2794
self._supply_sub_formats_to(local_dir_format)
2795
return local_dir_format.initialize_on_transport_ex(transport,
2796
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2797
force_new_repo=force_new_repo, stacked_on=stacked_on,
2798
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2799
make_working_trees=make_working_trees, shared_repo=shared_repo,
2801
return self._initialize_on_transport_ex_rpc(client, path, transport,
2802
use_existing_dir, create_prefix, force_new_repo, stacked_on,
2803
stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
2805
def _initialize_on_transport_ex_rpc(self, client, path, transport,
2806
use_existing_dir, create_prefix, force_new_repo, stacked_on,
2807
stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
2809
args.append(self._serialize_NoneTrueFalse(use_existing_dir))
2810
args.append(self._serialize_NoneTrueFalse(create_prefix))
2811
args.append(self._serialize_NoneTrueFalse(force_new_repo))
2812
args.append(self._serialize_NoneString(stacked_on))
2813
# stack_on_pwd is often/usually our transport
2816
stack_on_pwd = transport.relpath(stack_on_pwd)
2817
if not stack_on_pwd:
2819
except errors.PathNotChild:
2821
args.append(self._serialize_NoneString(stack_on_pwd))
2822
args.append(self._serialize_NoneString(repo_format_name))
2823
args.append(self._serialize_NoneTrueFalse(make_working_trees))
2824
args.append(self._serialize_NoneTrueFalse(shared_repo))
2825
request_network_name = self._network_name or \
2826
BzrDirFormat.get_default_format().network_name()
2828
response = client.call('BzrDirFormat.initialize_ex_1.16',
2829
request_network_name, path, *args)
2830
except errors.UnknownSmartMethod:
2831
client._medium._remember_remote_is_before((1,16))
2832
local_dir_format = BzrDirMetaFormat1()
2833
self._supply_sub_formats_to(local_dir_format)
2834
return local_dir_format.initialize_on_transport_ex(transport,
2835
use_existing_dir=use_existing_dir, create_prefix=create_prefix,
2836
force_new_repo=force_new_repo, stacked_on=stacked_on,
2837
stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
2838
make_working_trees=make_working_trees, shared_repo=shared_repo,
2840
except errors.ErrorFromSmartServer, err:
2841
remote._translate_error(err, path=path)
2842
repo_path = response[0]
2843
bzrdir_name = response[6]
2844
require_stacking = response[7]
2845
require_stacking = self.parse_NoneTrueFalse(require_stacking)
2846
format = RemoteBzrDirFormat()
2847
format._network_name = bzrdir_name
2848
self._supply_sub_formats_to(format)
2849
bzrdir = remote.RemoteBzrDir(transport, format, _client=client)
2851
repo_format = remote.response_tuple_to_repo_format(response[1:])
2852
if repo_path == '.':
2855
repo_bzrdir_format = RemoteBzrDirFormat()
2856
repo_bzrdir_format._network_name = response[5]
2857
repo_bzr = remote.RemoteBzrDir(transport.clone(repo_path),
2861
final_stack = response[8] or None
2862
final_stack_pwd = response[9] or None
2864
final_stack_pwd = urlutils.join(
2865
transport.base, final_stack_pwd)
2866
remote_repo = remote.RemoteRepository(repo_bzr, repo_format)
2867
if len(response) > 10:
2868
# Updated server verb that locks remotely.
2869
repo_lock_token = response[10] or None
2870
remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
2872
remote_repo.dont_leave_lock_in_place()
2874
remote_repo.lock_write()
2875
policy = UseExistingRepository(remote_repo, final_stack,
2876
final_stack_pwd, require_stacking)
2877
policy.acquire_repository()
2881
bzrdir._format.set_branch_format(self.get_branch_format())
2882
if require_stacking:
2883
# The repo has already been created, but we need to make sure that
2884
# we'll make a stackable branch.
2885
bzrdir._format.require_stacking(_skip_repo=True)
2886
return remote_repo, bzrdir, require_stacking, policy
2888
def _open(self, transport):
2889
return remote.RemoteBzrDir(transport, self)
2891
def __eq__(self, other):
2892
if not isinstance(other, RemoteBzrDirFormat):
2894
return self.get_format_description() == other.get_format_description()
2896
def __return_repository_format(self):
2897
# Always return a RemoteRepositoryFormat object, but if a specific bzr
2898
# repository format has been asked for, tell the RemoteRepositoryFormat
2899
# that it should use that for init() etc.
2900
result = remote.RemoteRepositoryFormat()
2901
custom_format = getattr(self, '_repository_format', None)
2903
if isinstance(custom_format, remote.RemoteRepositoryFormat):
2904
return custom_format
2906
# We will use the custom format to create repositories over the
2907
# wire; expose its details like rich_root_data for code to
2909
result._custom_format = custom_format
2912
def get_branch_format(self):
2913
result = BzrDirMetaFormat1.get_branch_format(self)
2914
if not isinstance(result, remote.RemoteBranchFormat):
2915
new_result = remote.RemoteBranchFormat()
2916
new_result._custom_format = result
2918
self.set_branch_format(new_result)
2922
repository_format = property(__return_repository_format,
2923
BzrDirMetaFormat1._set_repository_format) #.im_func)
1912
2926
controldir.ControlDirFormat.register_server_prober(RemoteBzrProber)
2152
3182
'network operations. Additionally adds support for versioning nested '
2153
3183
'bzr branches. Incompatible with bzr < 0.15.',
2154
3184
branch_format='bzrlib.branch.BzrBranchFormat6',
2155
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3185
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2156
3186
experimental=True,
2159
3189
register_metadir(controldir.format_registry, 'pack-0.92',
2160
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack1',
3190
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
2161
3191
help='New in 0.92: Pack-based format with data compatible with '
2162
3192
'dirstate-tags format repositories. Interoperates with '
2163
3193
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2165
3195
branch_format='bzrlib.branch.BzrBranchFormat6',
2166
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3196
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2168
3198
register_metadir(controldir.format_registry, 'pack-0.92-subtree',
2169
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack3',
3199
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
2170
3200
help='New in 0.92: Pack-based format with data compatible with '
2171
3201
'dirstate-with-subtree format repositories. Interoperates with '
2172
3202
'bzr repositories before 0.92 but cannot be read by bzr < 0.92. '
2174
3204
branch_format='bzrlib.branch.BzrBranchFormat6',
2175
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3205
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2177
3207
experimental=True,
2179
3209
register_metadir(controldir.format_registry, 'rich-root-pack',
2180
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack4',
3210
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
2181
3211
help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
2182
3212
'(needed for bzr-svn and bzr-git).',
2183
3213
branch_format='bzrlib.branch.BzrBranchFormat6',
2184
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3214
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2187
3217
register_metadir(controldir.format_registry, '1.6',
2188
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5',
3218
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
2189
3219
help='A format that allows a branch to indicate that there is another '
2190
3220
'(stacked) repository that should be used to access data that is '
2191
3221
'not present locally.',
2192
3222
branch_format='bzrlib.branch.BzrBranchFormat7',
2193
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3223
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2196
3226
register_metadir(controldir.format_registry, '1.6.1-rich-root',
2197
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack5RichRoot',
3227
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
2198
3228
help='A variant of 1.6 that supports rich-root data '
2199
3229
'(needed for bzr-svn and bzr-git).',
2200
3230
branch_format='bzrlib.branch.BzrBranchFormat7',
2201
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3231
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2204
3234
register_metadir(controldir.format_registry, '1.9',
2205
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
3235
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
2206
3236
help='A repository format using B+tree indexes. These indexes '
2207
3237
'are smaller in size, have smarter caching and provide faster '
2208
3238
'performance for most operations.',
2209
3239
branch_format='bzrlib.branch.BzrBranchFormat7',
2210
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3240
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2213
3243
register_metadir(controldir.format_registry, '1.9-rich-root',
2214
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
3244
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
2215
3245
help='A variant of 1.9 that supports rich-root data '
2216
3246
'(needed for bzr-svn and bzr-git).',
2217
3247
branch_format='bzrlib.branch.BzrBranchFormat7',
2218
tree_format='bzrlib.workingtree_4.WorkingTreeFormat4',
3248
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2221
3251
register_metadir(controldir.format_registry, '1.14',
2222
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6',
3252
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
2223
3253
help='A working-tree format that supports content filtering.',
2224
3254
branch_format='bzrlib.branch.BzrBranchFormat7',
2225
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
3255
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2227
3257
register_metadir(controldir.format_registry, '1.14-rich-root',
2228
'bzrlib.repofmt.knitpack_repo.RepositoryFormatKnitPack6RichRoot',
3258
'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
2229
3259
help='A variant of 1.14 that supports rich-root data '
2230
3260
'(needed for bzr-svn and bzr-git).',
2231
3261
branch_format='bzrlib.branch.BzrBranchFormat7',
2232
tree_format='bzrlib.workingtree_4.WorkingTreeFormat5',
3262
tree_format='bzrlib.workingtree.WorkingTreeFormat5',
2234
3264
# The following un-numbered 'development' formats should always just be aliases.
2235
3265
register_metadir(controldir.format_registry, 'development-subtree',