23
23
# TODO: remove unittest dependency; put that stuff inside the test suite
25
# TODO: The Format probe_transport seems a bit redundant with just trying to
26
# open the bzrdir. -- mbp
28
# TODO: Can we move specific formats into separate modules to make this file
31
25
from copy import deepcopy
32
26
from cStringIO import StringIO
93
86
"""Return true if this bzrdir is one whose format we can convert from."""
96
def check_conversion_target(self, target_format):
97
target_repo_format = target_format.repository_format
98
source_repo_format = self._format.repository_format
99
source_repo_format.check_conversion_target(target_repo_format)
102
90
def _check_supported(format, allow_unsupported):
103
91
"""Check whether format is a supported format.
304
292
This will use the current default BzrDirFormat, and use whatever
305
293
repository format that that uses for bzrdirformat.create_repository.
307
:param shared: Create a shared repository rather than a standalone
295
;param shared: Create a shared repository rather than a standalone
309
297
The Repository object is returned.
325
313
repository format that that uses for bzrdirformat.create_workingtree,
326
314
create_branch and create_repository.
328
:return: The WorkingTree object.
316
The WorkingTree object is returned.
330
318
t = get_transport(safe_unicode(base))
331
319
if not isinstance(t, LocalTransport):
472
460
_unsupported is a private parameter to the BzrDir class.
474
462
t = get_transport(base)
475
return BzrDir.open_from_transport(t, _unsupported=_unsupported)
478
def open_from_transport(transport, _unsupported=False):
479
"""Open a bzrdir within a particular directory.
481
:param transport: Transport containing the bzrdir.
482
:param _unsupported: private.
484
format = BzrDirFormat.find_format(transport)
463
mutter("trying to open %r with transport %r", base, t)
464
format = BzrDirFormat.find_format(t)
485
465
BzrDir._check_supported(format, _unsupported)
486
return format.open(transport, _found=True)
466
return format.open(t, _found=True)
488
468
def open_branch(self, unsupported=False):
489
469
"""Open the branch object at this BzrDir if one is present.
523
503
url = a_transport.base
526
result = BzrDir.open_from_transport(a_transport)
527
return result, urlutils.unescape(a_transport.relpath(url))
506
format = BzrDirFormat.find_format(a_transport)
507
BzrDir._check_supported(format, False)
508
return format.open(a_transport), urlutils.unescape(a_transport.relpath(url))
528
509
except errors.NotBranchError, e:
510
## mutter('not a branch in: %r %s', a_transport.base, e)
530
512
new_t = a_transport.clone('..')
531
513
if new_t.base == a_transport.base:
581
563
except errors.NoWorkingTree:
584
def cloning_metadir(self, basis=None):
585
"""Produce a metadir suitable for cloning with"""
586
def related_repository(bzrdir):
588
branch = bzrdir.open_branch()
589
return branch.repository
590
except errors.NotBranchError:
592
return bzrdir.open_repository()
593
result_format = self._format.__class__()
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
566
def sprout(self, url, revision_id=None, basis=None, force_new_repo=False):
607
567
"""Create a copy of this bzrdir prepared for use as a new line of
618
578
itself to download less data.
620
580
self._make_tail(url)
621
cloning_format = self.cloning_metadir(basis)
622
result = cloning_format.initialize(url)
581
result = self._format.initialize(url)
623
582
basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
625
584
source_branch = self.open_branch()
656
615
# XXX FIXME RBC 20060214 need tests for this when the basis
658
617
result_repo.fetch(basis_repo, revision_id=revision_id)
659
if source_repository is not None:
660
result_repo.fetch(source_repository, revision_id=revision_id)
618
result_repo.fetch(source_repository, revision_id=revision_id)
661
619
if source_branch is not None:
662
620
source_branch.sprout(result, revision_id=revision_id)
727
685
# done on this format anyway. So - acceptable wart.
728
686
result = self.open_workingtree()
729
687
if revision_id is not None:
730
if revision_id == bzrlib.revision.NULL_REVISION:
731
result.set_parent_ids([])
733
result.set_parent_ids([revision_id])
688
result.set_last_revision(revision_id)
736
691
def get_branch_transport(self, branch_format):
778
733
self._check_supported(format, unsupported)
779
734
return format.open(self, _found=True)
781
def sprout(self, url, revision_id=None, basis=None, force_new_repo=False):
736
def sprout(self, url, revision_id=None, basis=None):
782
737
"""See BzrDir.sprout()."""
783
738
from bzrlib.workingtree import WorkingTreeFormat2
784
739
self._make_tail(url)
1222
1173
def __return_repository_format(self):
1223
1174
"""Circular import protection."""
1224
1175
from bzrlib.repository import RepositoryFormat4
1225
return RepositoryFormat4()
1176
return RepositoryFormat4(self)
1226
1177
repository_format = property(__return_repository_format)
1266
1217
result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
1267
1218
RepositoryFormat5().initialize(result, _internal=True)
1268
1219
if not _cloning:
1269
branch = BzrBranchFormat4().initialize(result)
1271
WorkingTreeFormat2().initialize(result)
1272
except errors.NotLocalUrl:
1273
# Even though we can't access the working tree, we need to
1274
# create its control files.
1275
WorkingTreeFormat2().stub_initialize_remote(branch.control_files)
1220
BzrBranchFormat4().initialize(result)
1221
WorkingTreeFormat2().initialize(result)
1278
1224
def _open(self, transport):
1282
1228
def __return_repository_format(self):
1283
1229
"""Circular import protection."""
1284
1230
from bzrlib.repository import RepositoryFormat5
1285
return RepositoryFormat5()
1231
return RepositoryFormat5(self)
1286
1232
repository_format = property(__return_repository_format)
1325
1271
result = super(BzrDirFormat6, self).initialize_on_transport(transport)
1326
1272
RepositoryFormat6().initialize(result, _internal=True)
1327
1273
if not _cloning:
1328
branch = BzrBranchFormat4().initialize(result)
1274
BzrBranchFormat4().initialize(result)
1330
1276
WorkingTreeFormat2().initialize(result)
1331
1277
except errors.NotLocalUrl:
1332
# Even though we can't access the working tree, we need to
1333
# create its control files.
1334
WorkingTreeFormat2().stub_initialize_remote(branch.control_files)
1278
# emulate pre-check behaviour for working tree and silently
1337
1283
def _open(self, transport):
1341
1287
def __return_repository_format(self):
1342
1288
"""Circular import protection."""
1343
1289
from bzrlib.repository import RepositoryFormat6
1344
return RepositoryFormat6()
1290
return RepositoryFormat6(self)
1345
1291
repository_format = property(__return_repository_format)
1523
1469
inv = serializer_v4.read_inventory(self.branch.control_files.get('inventory'))
1524
1470
new_inv_xml = bzrlib.xml5.serializer_v5.write_inventory_to_string(inv)
1525
1471
# FIXME inventory is a working tree change.
1526
self.branch.control_files.put('inventory', StringIO(new_inv_xml))
1472
self.branch.control_files.put('inventory', new_inv_xml)
1528
1474
def _write_all_weaves(self):
1529
1475
controlweaves = WeaveStore(self.bzrdir.transport, prefixed=False)
1612
1557
def _store_new_weave(self, rev, inv, present_parents):
1613
1558
# the XML is now updated with text versions
1615
entries = inv.iter_entries()
1617
for path, ie in entries:
1618
assert getattr(ie, 'revision', None) is not None, \
1562
if ie.kind == 'root_directory':
1564
assert hasattr(ie, 'revision'), \
1619
1565
'no revision on {%s} in {%s}' % \
1620
1566
(file_id, rev.revision_id)
1621
1567
new_inv_xml = bzrlib.xml5.serializer_v5.write_inventory_to_string(inv)
1633
1579
mutter('converting texts of revision {%s}',
1635
1581
parent_invs = map(self._load_updated_inventory, present_parents)
1636
entries = inv.iter_entries()
1638
for path, ie in entries:
1639
1584
self._convert_file_version(rev, ie, parent_invs)
1641
1586
def _convert_file_version(self, rev, ie, parent_invs):
1798
1745
for entry in branch_files:
1799
1746
self.move_entry('branch', entry)
1748
self.step('Upgrading working tree')
1749
self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
1750
self.make_lock('checkout')
1751
self.put_format('checkout', bzrlib.workingtree.WorkingTreeFormat3())
1752
self.bzrdir.transport.delete_multi(self.garbage_inventories, self.pb)
1801
1753
checkout_files = [('pending-merges', True),
1802
1754
('inventory', True),
1803
1755
('stat-cache', False)]
1804
# If a mandatory checkout file is not present, the branch does not have
1805
# a functional checkout. Do not create a checkout in the converted
1807
for name, mandatory in checkout_files:
1808
if mandatory and name not in bzrcontents:
1809
has_checkout = False
1813
if not has_checkout:
1814
self.pb.note('No working tree.')
1815
# If some checkout files are there, we may as well get rid of them.
1816
for name, mandatory in checkout_files:
1817
if name in bzrcontents:
1818
self.bzrdir.transport.delete(name)
1820
self.step('Upgrading working tree')
1821
self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
1822
self.make_lock('checkout')
1824
'checkout', bzrlib.workingtree.WorkingTreeFormat3())
1825
self.bzrdir.transport.delete_multi(
1826
self.garbage_inventories, self.pb)
1827
for entry in checkout_files:
1828
self.move_entry('checkout', entry)
1829
if last_revision is not None:
1830
self.bzrdir._control_files.put_utf8(
1831
'checkout/last-revision', last_revision)
1832
self.bzrdir._control_files.put_utf8(
1833
'branch-format', BzrDirMetaFormat1().get_format_string())
1756
for entry in checkout_files:
1757
self.move_entry('checkout', entry)
1758
if last_revision is not None:
1759
self.bzrdir._control_files.put_utf8('checkout/last-revision',
1761
self.bzrdir._control_files.put_utf8('branch-format', BzrDirMetaFormat1().get_format_string())
1834
1762
return BzrDir.open(self.bzrdir.root_transport.base)
1836
1764
def make_lock(self, name):