597
687
workingtree and discards it, and that's somewhat expensive.)
600
self.open_workingtree()
690
self.open_workingtree(recommend_upgrade=False)
602
692
except errors.NoWorkingTree:
605
def cloning_metadir(self, basis=None):
695
def _cloning_metadir(self):
606
696
"""Produce a metadir suitable for cloning with"""
607
def related_repository(bzrdir):
697
result_format = self._format.__class__()
609
branch = bzrdir.open_branch()
610
return branch.repository
700
branch = self.open_branch()
701
source_repository = branch.repository
611
702
except errors.NotBranchError:
612
703
source_branch = None
613
return bzrdir.open_repository()
614
result_format = self._format.__class__()
704
source_repository = self.open_repository()
705
except errors.NoRepositoryPresent:
706
source_repository = None
708
# XXX TODO: This isinstance is here because we have not implemented
709
# the fix recommended in bug # 103195 - to delegate this choice the
711
repo_format = source_repository._format
712
if not isinstance(repo_format, remote.RemoteRepositoryFormat):
713
result_format.repository_format = repo_format
617
source_repository = related_repository(self)
618
except errors.NoRepositoryPresent:
621
source_repository = related_repository(self)
622
result_format.repository_format = source_repository._format
623
except errors.NoRepositoryPresent:
627
def sprout(self, url, revision_id=None, basis=None, force_new_repo=False):
715
# TODO: Couldn't we just probe for the format in these cases,
716
# rather than opening the whole tree? It would be a little
717
# faster. mbp 20070401
718
tree = self.open_workingtree(recommend_upgrade=False)
719
except (errors.NoWorkingTree, errors.NotLocalUrl):
720
result_format.workingtree_format = None
722
result_format.workingtree_format = tree._format.__class__()
723
return result_format, source_repository
725
def cloning_metadir(self):
726
"""Produce a metadir suitable for cloning or sprouting with.
728
These operations may produce workingtrees (yes, even though they're
729
"cloning" something that doesn't have a tree, so a viable workingtree
730
format must be selected.
732
format, repository = self._cloning_metadir()
733
if format._workingtree_format is None:
734
if repository is None:
736
tree_format = repository._format._matchingbzrdir.workingtree_format
737
format.workingtree_format = tree_format.__class__()
740
def checkout_metadir(self):
741
return self.cloning_metadir()
743
def sprout(self, url, revision_id=None, force_new_repo=False,
628
745
"""Create a copy of this bzrdir prepared for use as a new line of
1940
2189
self.pb.note('starting repository conversion')
1941
2190
converter = CopyConverter(self.target_format.repository_format)
1942
2191
converter.convert(repo, pb)
2193
branch = self.bzrdir.open_branch()
2194
except errors.NotBranchError:
2197
# TODO: conversions of Branch and Tree should be done by
2198
# InterXFormat lookups
2199
# Avoid circular imports
2200
from bzrlib import branch as _mod_branch
2201
if (branch._format.__class__ is _mod_branch.BzrBranchFormat5 and
2202
self.target_format.get_branch_format().__class__ is
2203
_mod_branch.BzrBranchFormat6):
2204
branch_converter = _mod_branch.Converter5to6()
2205
branch_converter.convert(branch)
2207
tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
2208
except (errors.NoWorkingTree, errors.NotLocalUrl):
2211
# TODO: conversions of Branch and Tree should be done by
2212
# InterXFormat lookups
2213
if (isinstance(tree, workingtree.WorkingTree3) and
2214
not isinstance(tree, workingtree_4.WorkingTree4) and
2215
isinstance(self.target_format.workingtree_format,
2216
workingtree_4.WorkingTreeFormat4)):
2217
workingtree_4.Converter3to4().convert(tree)
1943
2218
return to_convert
2221
# This is not in remote.py because it's small, and needs to be registered.
2222
# Putting it in remote.py creates a circular import problem.
2223
# we can make it a lazy object if the control formats is turned into something
2225
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2226
"""Format representing bzrdirs accessed via a smart server"""
2228
def get_format_description(self):
2229
return 'bzr remote bzrdir'
2232
def probe_transport(klass, transport):
2233
"""Return a RemoteBzrDirFormat object if it looks possible."""
2235
transport.get_smart_client()
2236
except (NotImplementedError, AttributeError,
2237
errors.TransportNotPossible):
2238
# no smart server, so not a branch for this format type.
2239
raise errors.NotBranchError(path=transport.base)
2243
def initialize_on_transport(self, transport):
2245
# hand off the request to the smart server
2246
medium = transport.get_smart_medium()
2247
except errors.NoSmartMedium:
2248
# TODO: lookup the local format from a server hint.
2249
local_dir_format = BzrDirMetaFormat1()
2250
return local_dir_format.initialize_on_transport(transport)
2251
client = _SmartClient(medium)
2252
path = client.remote_path_from_transport(transport)
2253
response = _SmartClient(medium).call('BzrDirFormat.initialize', path)
2254
assert response[0] in ('ok', ), 'unexpected response code %s' % (response,)
2255
return remote.RemoteBzrDir(transport)
2257
def _open(self, transport):
2258
return remote.RemoteBzrDir(transport)
2260
def __eq__(self, other):
2261
if not isinstance(other, RemoteBzrDirFormat):
2263
return self.get_format_description() == other.get_format_description()
2266
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
2269
class BzrDirFormatInfo(object):
2271
def __init__(self, native, deprecated, hidden):
2272
self.deprecated = deprecated
2273
self.native = native
2274
self.hidden = hidden
2277
class BzrDirFormatRegistry(registry.Registry):
2278
"""Registry of user-selectable BzrDir subformats.
2280
Differs from BzrDirFormat._control_formats in that it provides sub-formats,
2281
e.g. BzrDirMeta1 with weave repository. Also, it's more user-oriented.
2284
def register_metadir(self, key,
2285
repository_format, help, native=True, deprecated=False,
2289
"""Register a metadir subformat.
2291
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
2292
by the Repository format.
2294
:param repository_format: The fully-qualified repository format class
2296
:param branch_format: Fully-qualified branch format class name as
2298
:param tree_format: Fully-qualified tree format class name as
2301
# This should be expanded to support setting WorkingTree and Branch
2302
# formats, once BzrDirMetaFormat1 supports that.
2303
def _load(full_name):
2304
mod_name, factory_name = full_name.rsplit('.', 1)
2306
mod = __import__(mod_name, globals(), locals(),
2308
except ImportError, e:
2309
raise ImportError('failed to load %s: %s' % (full_name, e))
2311
factory = getattr(mod, factory_name)
2312
except AttributeError:
2313
raise AttributeError('no factory %s in module %r'
2318
bd = BzrDirMetaFormat1()
2319
if branch_format is not None:
2320
bd.set_branch_format(_load(branch_format))
2321
if tree_format is not None:
2322
bd.workingtree_format = _load(tree_format)
2323
if repository_format is not None:
2324
bd.repository_format = _load(repository_format)
2326
self.register(key, helper, help, native, deprecated, hidden)
2328
def register(self, key, factory, help, native=True, deprecated=False,
2330
"""Register a BzrDirFormat factory.
2332
The factory must be a callable that takes one parameter: the key.
2333
It must produce an instance of the BzrDirFormat when called.
2335
This function mainly exists to prevent the info object from being
2338
registry.Registry.register(self, key, factory, help,
2339
BzrDirFormatInfo(native, deprecated, hidden))
2341
def register_lazy(self, key, module_name, member_name, help, native=True,
2342
deprecated=False, hidden=False):
2343
registry.Registry.register_lazy(self, key, module_name, member_name,
2344
help, BzrDirFormatInfo(native, deprecated, hidden))
2346
def set_default(self, key):
2347
"""Set the 'default' key to be a clone of the supplied key.
2349
This method must be called once and only once.
2351
registry.Registry.register(self, 'default', self.get(key),
2352
self.get_help(key), info=self.get_info(key))
2354
def set_default_repository(self, key):
2355
"""Set the FormatRegistry default and Repository default.
2357
This is a transitional method while Repository.set_default_format
2360
if 'default' in self:
2361
self.remove('default')
2362
self.set_default(key)
2363
format = self.get('default')()
2364
assert isinstance(format, BzrDirMetaFormat1)
2366
def make_bzrdir(self, key):
2367
return self.get(key)()
2369
def help_topic(self, topic):
2370
output = textwrap.dedent("""\
2371
Bazaar directory formats
2372
------------------------
2374
These formats can be used for creating branches, working trees, and
2378
default_help = self.get_help('default')
2380
for key in self.keys():
2381
if key == 'default':
2383
help = self.get_help(key)
2384
if help == default_help:
2385
default_realkey = key
2387
help_pairs.append((key, help))
2389
def wrapped(key, help, info):
2391
help = '(native) ' + help
2392
return ' %s:\n%s\n\n' % (key,
2393
textwrap.fill(help, initial_indent=' ',
2394
subsequent_indent=' '))
2395
output += wrapped('%s/default' % default_realkey, default_help,
2396
self.get_info('default'))
2397
deprecated_pairs = []
2398
for key, help in help_pairs:
2399
info = self.get_info(key)
2402
elif info.deprecated:
2403
deprecated_pairs.append((key, help))
2405
output += wrapped(key, help, info)
2406
if len(deprecated_pairs) > 0:
2407
output += "Deprecated formats\n------------------\n\n"
2408
for key, help in deprecated_pairs:
2409
info = self.get_info(key)
2410
output += wrapped(key, help, info)
2415
format_registry = BzrDirFormatRegistry()
2416
format_registry.register('weave', BzrDirFormat6,
2417
'Pre-0.8 format. Slower than knit and does not'
2418
' support checkouts or shared repositories.',
2420
format_registry.register_metadir('knit',
2421
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2422
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
2423
branch_format='bzrlib.branch.BzrBranchFormat5',
2424
tree_format='bzrlib.workingtree.WorkingTreeFormat3')
2425
format_registry.register_metadir('metaweave',
2426
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
2427
'Transitional format in 0.8. Slower than knit.',
2428
branch_format='bzrlib.branch.BzrBranchFormat5',
2429
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
2431
format_registry.register_metadir('dirstate',
2432
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2433
help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
2434
'above when accessed over the network.',
2435
branch_format='bzrlib.branch.BzrBranchFormat5',
2436
# this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
2437
# directly from workingtree_4 triggers a circular import.
2438
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2440
format_registry.register_metadir('dirstate-tags',
2441
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2442
help='New in 0.15: Fast local operations and improved scaling for '
2443
'network operations. Additionally adds support for tags.'
2444
' Incompatible with bzr < 0.15.',
2445
branch_format='bzrlib.branch.BzrBranchFormat6',
2446
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2448
format_registry.register_metadir('dirstate-with-subtree',
2449
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2450
help='New in 0.15: Fast local operations and improved scaling for '
2451
'network operations. Additionally adds support for versioning nested '
2452
'bzr branches. Incompatible with bzr < 0.15.',
2453
branch_format='bzrlib.branch.BzrBranchFormat6',
2454
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2457
format_registry.set_default('dirstate')