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
25
31
from copy import deepcopy
26
32
from cStringIO import StringIO
86
93
"""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)
90
102
def _check_supported(format, allow_unsupported):
91
103
"""Check whether format is a supported format.
292
304
This will use the current default BzrDirFormat, and use whatever
293
305
repository format that that uses for bzrdirformat.create_repository.
295
;param shared: Create a shared repository rather than a standalone
307
:param shared: Create a shared repository rather than a standalone
297
309
The Repository object is returned.
313
325
repository format that that uses for bzrdirformat.create_workingtree,
314
326
create_branch and create_repository.
316
The WorkingTree object is returned.
328
:return: The WorkingTree object.
318
330
t = get_transport(safe_unicode(base))
319
331
if not isinstance(t, LocalTransport):
460
472
_unsupported is a private parameter to the BzrDir class.
462
474
t = get_transport(base)
463
# mutter("trying to open %r with transport %r", base, t)
464
format = BzrDirFormat.find_format(t)
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)
465
485
BzrDir._check_supported(format, _unsupported)
466
return format.open(t, _found=True)
486
return format.open(transport, _found=True)
468
488
def open_branch(self, unsupported=False):
469
489
"""Open the branch object at this BzrDir if one is present.
503
523
url = a_transport.base
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))
526
result = BzrDir.open_from_transport(a_transport)
527
return result, urlutils.unescape(a_transport.relpath(url))
509
528
except errors.NotBranchError, e:
510
## mutter('not a branch in: %r %s', a_transport.base, e)
512
530
new_t = a_transport.clone('..')
513
531
if new_t.base == a_transport.base:
563
581
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:
566
606
def sprout(self, url, revision_id=None, basis=None, force_new_repo=False):
567
607
"""Create a copy of this bzrdir prepared for use as a new line of
578
618
itself to download less data.
580
620
self._make_tail(url)
581
result = self._format.initialize(url)
621
cloning_format = self.cloning_metadir(basis)
622
result = cloning_format.initialize(url)
582
623
basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
584
625
source_branch = self.open_branch()
686
727
# done on this format anyway. So - acceptable wart.
687
728
result = self.open_workingtree()
688
729
if revision_id is not None:
689
result.set_last_revision(revision_id)
730
if revision_id == bzrlib.revision.NULL_REVISION:
731
result.set_parent_ids([])
733
result.set_parent_ids([revision_id])
692
736
def get_branch_transport(self, branch_format):
1174
1222
def __return_repository_format(self):
1175
1223
"""Circular import protection."""
1176
1224
from bzrlib.repository import RepositoryFormat4
1177
return RepositoryFormat4(self)
1225
return RepositoryFormat4()
1178
1226
repository_format = property(__return_repository_format)
1234
1282
def __return_repository_format(self):
1235
1283
"""Circular import protection."""
1236
1284
from bzrlib.repository import RepositoryFormat5
1237
return RepositoryFormat5(self)
1285
return RepositoryFormat5()
1238
1286
repository_format = property(__return_repository_format)
1293
1341
def __return_repository_format(self):
1294
1342
"""Circular import protection."""
1295
1343
from bzrlib.repository import RepositoryFormat6
1296
return RepositoryFormat6(self)
1344
return RepositoryFormat6()
1297
1345
repository_format = property(__return_repository_format)
1475
1523
inv = serializer_v4.read_inventory(self.branch.control_files.get('inventory'))
1476
1524
new_inv_xml = bzrlib.xml5.serializer_v5.write_inventory_to_string(inv)
1477
1525
# FIXME inventory is a working tree change.
1478
self.branch.control_files.put('inventory', new_inv_xml)
1526
self.branch.control_files.put('inventory', StringIO(new_inv_xml))
1480
1528
def _write_all_weaves(self):
1481
1529
controlweaves = WeaveStore(self.bzrdir.transport, prefixed=False)
1566
1615
entries = inv.iter_entries()
1568
1617
for path, ie in entries:
1569
assert hasattr(ie, 'revision'), \
1618
assert getattr(ie, 'revision', None) is not None, \
1570
1619
'no revision on {%s} in {%s}' % \
1571
1620
(file_id, rev.revision_id)
1572
1621
new_inv_xml = bzrlib.xml5.serializer_v5.write_inventory_to_string(inv)
1749
1798
for entry in branch_files:
1750
1799
self.move_entry('branch', entry)
1752
self.step('Upgrading working tree')
1753
self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
1754
self.make_lock('checkout')
1755
self.put_format('checkout', bzrlib.workingtree.WorkingTreeFormat3())
1756
self.bzrdir.transport.delete_multi(self.garbage_inventories, self.pb)
1757
1801
checkout_files = [('pending-merges', True),
1758
1802
('inventory', True),
1759
1803
('stat-cache', False)]
1760
for entry in checkout_files:
1761
self.move_entry('checkout', entry)
1762
if last_revision is not None:
1763
self.bzrdir._control_files.put_utf8('checkout/last-revision',
1765
self.bzrdir._control_files.put_utf8('branch-format', BzrDirMetaFormat1().get_format_string())
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())
1766
1834
return BzrDir.open(self.bzrdir.root_transport.base)
1768
1836
def make_lock(self, name):