157
198
except errors.NotBranchError:
160
self.open_workingtree().clone(result, basis=basis_tree)
201
self.open_workingtree().clone(result)
161
202
except (errors.NoWorkingTree, errors.NotLocalUrl):
165
def _get_basis_components(self, basis):
166
"""Retrieve the basis components that are available at basis."""
168
return None, None, None
170
basis_tree = basis.open_workingtree()
171
basis_branch = basis_tree.branch
172
basis_repo = basis_branch.repository
173
except (errors.NoWorkingTree, errors.NotLocalUrl):
176
basis_branch = basis.open_branch()
177
basis_repo = basis_branch.repository
178
except errors.NotBranchError:
181
basis_repo = basis.open_repository()
182
except errors.NoRepositoryPresent:
184
return basis_repo, basis_branch, basis_tree
186
206
# TODO: This should be given a Transport, and should chdir up; otherwise
187
207
# this will open a new connection.
188
208
def _make_tail(self, url):
189
head, tail = urlutils.split(url)
190
if tail and tail != '.':
191
t = bzrlib.transport.get_transport(head)
194
except errors.FileExists:
209
t = get_transport(url)
197
212
# TODO: Should take a Transport
199
def create(cls, base):
214
def create(cls, base, format=None):
200
215
"""Create a new BzrDir at the url 'base'.
202
217
This will call the current default formats initialize with base
203
218
as the only parameter.
205
If you need a specific format, consider creating an instance
206
of that and calling initialize().
220
:param format: If supplied, the format of branch to create. If not
221
supplied, the default is used.
208
223
if cls is not BzrDir:
209
raise AssertionError("BzrDir.create always creates the default format, "
210
"not one of %r" % cls)
211
head, tail = urlutils.split(base)
212
if tail and tail != '.':
213
t = bzrlib.transport.get_transport(head)
216
except errors.FileExists:
218
return BzrDirFormat.get_default_format().initialize(safe_unicode(base))
224
raise AssertionError("BzrDir.create always creates the default"
225
" format, not one of %r" % cls)
226
t = get_transport(base)
229
format = BzrDirFormat.get_default_format()
230
return format.initialize(safe_unicode(base))
220
232
def create_branch(self):
221
233
"""Create a branch in this BzrDir.
576
689
workingtree and discards it, and that's somewhat expensive.)
579
self.open_workingtree()
692
self.open_workingtree(recommend_upgrade=False)
581
694
except errors.NoWorkingTree:
584
def cloning_metadir(self, basis=None):
697
def _cloning_metadir(self):
585
698
"""Produce a metadir suitable for cloning with"""
586
def related_repository(bzrdir):
699
result_format = self._format.__class__()
588
branch = bzrdir.open_branch()
589
return branch.repository
702
branch = self.open_branch()
703
source_repository = branch.repository
590
704
except errors.NotBranchError:
591
705
source_branch = None
592
return bzrdir.open_repository()
593
result_format = self._format.__class__()
706
source_repository = self.open_repository()
707
except errors.NoRepositoryPresent:
708
source_repository = None
710
# XXX TODO: This isinstance is here because we have not implemented
711
# the fix recommended in bug # 103195 - to delegate this choice the
713
repo_format = source_repository._format
714
if not isinstance(repo_format, remote.RemoteRepositoryFormat):
715
result_format.repository_format = repo_format
596
source_repository = related_repository(self)
597
except errors.NoRepositoryPresent:
600
source_repository = related_repository(self)
601
result_format.repository_format = source_repository._format
602
except errors.NoRepositoryPresent:
606
def sprout(self, url, revision_id=None, basis=None, force_new_repo=False):
717
# TODO: Couldn't we just probe for the format in these cases,
718
# rather than opening the whole tree? It would be a little
719
# faster. mbp 20070401
720
tree = self.open_workingtree(recommend_upgrade=False)
721
except (errors.NoWorkingTree, errors.NotLocalUrl):
722
result_format.workingtree_format = None
724
result_format.workingtree_format = tree._format.__class__()
725
return result_format, source_repository
727
def cloning_metadir(self):
728
"""Produce a metadir suitable for cloning or sprouting with.
730
These operations may produce workingtrees (yes, even though they're
731
"cloning" something that doesn't have a tree, so a viable workingtree
732
format must be selected.
734
format, repository = self._cloning_metadir()
735
if format._workingtree_format is None:
736
if repository is None:
738
tree_format = repository._format._matchingbzrdir.workingtree_format
739
format.workingtree_format = tree_format.__class__()
742
def checkout_metadir(self):
743
return self.cloning_metadir()
745
def sprout(self, url, revision_id=None, force_new_repo=False,
607
747
"""Create a copy of this bzrdir prepared for use as a new line of
1884
2155
self.pb.note('starting repository conversion')
1885
2156
converter = CopyConverter(self.target_format.repository_format)
1886
2157
converter.convert(repo, pb)
2159
branch = self.bzrdir.open_branch()
2160
except errors.NotBranchError:
2163
# TODO: conversions of Branch and Tree should be done by
2164
# InterXFormat lookups
2165
# Avoid circular imports
2166
from bzrlib import branch as _mod_branch
2167
if (branch._format.__class__ is _mod_branch.BzrBranchFormat5 and
2168
self.target_format.get_branch_format().__class__ is
2169
_mod_branch.BzrBranchFormat6):
2170
branch_converter = _mod_branch.Converter5to6()
2171
branch_converter.convert(branch)
2173
tree = self.bzrdir.open_workingtree(recommend_upgrade=False)
2174
except (errors.NoWorkingTree, errors.NotLocalUrl):
2177
# TODO: conversions of Branch and Tree should be done by
2178
# InterXFormat lookups
2179
if (isinstance(tree, workingtree.WorkingTree3) and
2180
not isinstance(tree, workingtree_4.WorkingTree4) and
2181
isinstance(self.target_format.workingtree_format,
2182
workingtree_4.WorkingTreeFormat4)):
2183
workingtree_4.Converter3to4().convert(tree)
1887
2184
return to_convert
2187
# This is not in remote.py because it's small, and needs to be registered.
2188
# Putting it in remote.py creates a circular import problem.
2189
# we can make it a lazy object if the control formats is turned into something
2191
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2192
"""Format representing bzrdirs accessed via a smart server"""
2194
def get_format_description(self):
2195
return 'bzr remote bzrdir'
2198
def probe_transport(klass, transport):
2199
"""Return a RemoteBzrDirFormat object if it looks possible."""
2201
client = transport.get_smart_client()
2202
except (NotImplementedError, AttributeError,
2203
errors.TransportNotPossible):
2204
# no smart server, so not a branch for this format type.
2205
raise errors.NotBranchError(path=transport.base)
2207
# Send a 'hello' request in protocol version one, and decline to
2208
# open it if the server doesn't support our required version (2) so
2209
# that the VFS-based transport will do it.
2210
request = client.get_request()
2211
smart_protocol = protocol.SmartClientRequestProtocolOne(request)
2212
server_version = smart_protocol.query_version()
2213
if server_version != 2:
2214
raise errors.NotBranchError(path=transport.base)
2217
def initialize_on_transport(self, transport):
2219
# hand off the request to the smart server
2220
medium = transport.get_smart_medium()
2221
except errors.NoSmartMedium:
2222
# TODO: lookup the local format from a server hint.
2223
local_dir_format = BzrDirMetaFormat1()
2224
return local_dir_format.initialize_on_transport(transport)
2225
client = _SmartClient(medium)
2226
path = client.remote_path_from_transport(transport)
2227
response = _SmartClient(medium).call('BzrDirFormat.initialize', path)
2228
assert response[0] in ('ok', ), 'unexpected response code %s' % (response,)
2229
return remote.RemoteBzrDir(transport)
2231
def _open(self, transport):
2232
return remote.RemoteBzrDir(transport)
2234
def __eq__(self, other):
2235
if not isinstance(other, RemoteBzrDirFormat):
2237
return self.get_format_description() == other.get_format_description()
2240
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
2243
class BzrDirFormatInfo(object):
2245
def __init__(self, native, deprecated, hidden):
2246
self.deprecated = deprecated
2247
self.native = native
2248
self.hidden = hidden
2251
class BzrDirFormatRegistry(registry.Registry):
2252
"""Registry of user-selectable BzrDir subformats.
2254
Differs from BzrDirFormat._control_formats in that it provides sub-formats,
2255
e.g. BzrDirMeta1 with weave repository. Also, it's more user-oriented.
2258
def register_metadir(self, key,
2259
repository_format, help, native=True, deprecated=False,
2263
"""Register a metadir subformat.
2265
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
2266
by the Repository format.
2268
:param repository_format: The fully-qualified repository format class
2270
:param branch_format: Fully-qualified branch format class name as
2272
:param tree_format: Fully-qualified tree format class name as
2275
# This should be expanded to support setting WorkingTree and Branch
2276
# formats, once BzrDirMetaFormat1 supports that.
2277
def _load(full_name):
2278
mod_name, factory_name = full_name.rsplit('.', 1)
2280
mod = __import__(mod_name, globals(), locals(),
2282
except ImportError, e:
2283
raise ImportError('failed to load %s: %s' % (full_name, e))
2285
factory = getattr(mod, factory_name)
2286
except AttributeError:
2287
raise AttributeError('no factory %s in module %r'
2292
bd = BzrDirMetaFormat1()
2293
if branch_format is not None:
2294
bd.set_branch_format(_load(branch_format))
2295
if tree_format is not None:
2296
bd.workingtree_format = _load(tree_format)
2297
if repository_format is not None:
2298
bd.repository_format = _load(repository_format)
2300
self.register(key, helper, help, native, deprecated, hidden)
2302
def register(self, key, factory, help, native=True, deprecated=False,
2304
"""Register a BzrDirFormat factory.
2306
The factory must be a callable that takes one parameter: the key.
2307
It must produce an instance of the BzrDirFormat when called.
2309
This function mainly exists to prevent the info object from being
2312
registry.Registry.register(self, key, factory, help,
2313
BzrDirFormatInfo(native, deprecated, hidden))
2315
def register_lazy(self, key, module_name, member_name, help, native=True,
2316
deprecated=False, hidden=False):
2317
registry.Registry.register_lazy(self, key, module_name, member_name,
2318
help, BzrDirFormatInfo(native, deprecated, hidden))
2320
def set_default(self, key):
2321
"""Set the 'default' key to be a clone of the supplied key.
2323
This method must be called once and only once.
2325
registry.Registry.register(self, 'default', self.get(key),
2326
self.get_help(key), info=self.get_info(key))
2328
def set_default_repository(self, key):
2329
"""Set the FormatRegistry default and Repository default.
2331
This is a transitional method while Repository.set_default_format
2334
if 'default' in self:
2335
self.remove('default')
2336
self.set_default(key)
2337
format = self.get('default')()
2338
assert isinstance(format, BzrDirMetaFormat1)
2340
def make_bzrdir(self, key):
2341
return self.get(key)()
2343
def help_topic(self, topic):
2344
output = textwrap.dedent("""\
2345
Bazaar directory formats
2346
------------------------
2348
These formats can be used for creating branches, working trees, and
2352
default_help = self.get_help('default')
2354
for key in self.keys():
2355
if key == 'default':
2357
help = self.get_help(key)
2358
if help == default_help:
2359
default_realkey = key
2361
help_pairs.append((key, help))
2363
def wrapped(key, help, info):
2365
help = '(native) ' + help
2366
return ' %s:\n%s\n\n' % (key,
2367
textwrap.fill(help, initial_indent=' ',
2368
subsequent_indent=' '))
2369
output += wrapped('%s/default' % default_realkey, default_help,
2370
self.get_info('default'))
2371
deprecated_pairs = []
2372
for key, help in help_pairs:
2373
info = self.get_info(key)
2376
elif info.deprecated:
2377
deprecated_pairs.append((key, help))
2379
output += wrapped(key, help, info)
2380
if len(deprecated_pairs) > 0:
2381
output += "Deprecated formats\n------------------\n\n"
2382
for key, help in deprecated_pairs:
2383
info = self.get_info(key)
2384
output += wrapped(key, help, info)
2389
format_registry = BzrDirFormatRegistry()
2390
format_registry.register('weave', BzrDirFormat6,
2391
'Pre-0.8 format. Slower than knit and does not'
2392
' support checkouts or shared repositories.',
2394
format_registry.register_metadir('knit',
2395
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2396
'Format using knits. Recommended for interoperation with bzr <= 0.14.',
2397
branch_format='bzrlib.branch.BzrBranchFormat5',
2398
tree_format='bzrlib.workingtree.WorkingTreeFormat3')
2399
format_registry.register_metadir('metaweave',
2400
'bzrlib.repofmt.weaverepo.RepositoryFormat7',
2401
'Transitional format in 0.8. Slower than knit.',
2402
branch_format='bzrlib.branch.BzrBranchFormat5',
2403
tree_format='bzrlib.workingtree.WorkingTreeFormat3',
2405
format_registry.register_metadir('dirstate',
2406
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2407
help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
2408
'above when accessed over the network.',
2409
branch_format='bzrlib.branch.BzrBranchFormat5',
2410
# this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
2411
# directly from workingtree_4 triggers a circular import.
2412
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2414
format_registry.register_metadir('dirstate-tags',
2415
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2416
help='New in 0.15: Fast local operations and improved scaling for '
2417
'network operations. Additionally adds support for tags.'
2418
' Incompatible with bzr < 0.15.',
2419
branch_format='bzrlib.branch.BzrBranchFormat6',
2420
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2422
format_registry.register_metadir('dirstate-with-subtree',
2423
'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2424
help='New in 0.15: Fast local operations and improved scaling for '
2425
'network operations. Additionally adds support for versioning nested '
2426
'bzr branches. Incompatible with bzr < 0.15.',
2427
branch_format='bzrlib.branch.BzrBranchFormat6',
2428
tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2431
format_registry.set_default('dirstate')