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()
615
656
# XXX FIXME RBC 20060214 need tests for this when the basis
617
658
result_repo.fetch(basis_repo, revision_id=revision_id)
618
result_repo.fetch(source_repository, revision_id=revision_id)
659
if source_repository is not None:
660
result_repo.fetch(source_repository, revision_id=revision_id)
619
661
if source_branch is not None:
620
662
source_branch.sprout(result, revision_id=revision_id)
623
665
# TODO: jam 20060426 we probably need a test in here in the
624
666
# case that the newly sprouted branch is a remote one
625
667
if result_repo is None or result_repo.make_working_trees():
626
result.create_workingtree()
668
wt = result.create_workingtree()
669
if wt.inventory.root is None:
671
wt.set_root_id(self.open_workingtree.get_root_id())
672
except errors.NoWorkingTree:
685
732
# done on this format anyway. So - acceptable wart.
686
733
result = self.open_workingtree()
687
734
if revision_id is not None:
688
result.set_last_revision(revision_id)
735
if revision_id == bzrlib.revision.NULL_REVISION:
736
result.set_parent_ids([])
738
result.set_parent_ids([revision_id])
691
741
def get_branch_transport(self, branch_format):
733
783
self._check_supported(format, unsupported)
734
784
return format.open(self, _found=True)
736
def sprout(self, url, revision_id=None, basis=None):
786
def sprout(self, url, revision_id=None, basis=None, force_new_repo=False):
737
787
"""See BzrDir.sprout()."""
738
788
from bzrlib.workingtree import WorkingTreeFormat2
739
789
self._make_tail(url)
1173
1227
def __return_repository_format(self):
1174
1228
"""Circular import protection."""
1175
1229
from bzrlib.repository import RepositoryFormat4
1176
return RepositoryFormat4(self)
1230
return RepositoryFormat4()
1177
1231
repository_format = property(__return_repository_format)
1217
1271
result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
1218
1272
RepositoryFormat5().initialize(result, _internal=True)
1219
1273
if not _cloning:
1220
BzrBranchFormat4().initialize(result)
1221
WorkingTreeFormat2().initialize(result)
1274
branch = BzrBranchFormat4().initialize(result)
1276
WorkingTreeFormat2().initialize(result)
1277
except errors.NotLocalUrl:
1278
# Even though we can't access the working tree, we need to
1279
# create its control files.
1280
WorkingTreeFormat2().stub_initialize_remote(branch.control_files)
1224
1283
def _open(self, transport):
1228
1287
def __return_repository_format(self):
1229
1288
"""Circular import protection."""
1230
1289
from bzrlib.repository import RepositoryFormat5
1231
return RepositoryFormat5(self)
1290
return RepositoryFormat5()
1232
1291
repository_format = property(__return_repository_format)
1271
1330
result = super(BzrDirFormat6, self).initialize_on_transport(transport)
1272
1331
RepositoryFormat6().initialize(result, _internal=True)
1273
1332
if not _cloning:
1274
BzrBranchFormat4().initialize(result)
1333
branch = BzrBranchFormat4().initialize(result)
1276
1335
WorkingTreeFormat2().initialize(result)
1277
1336
except errors.NotLocalUrl:
1278
# emulate pre-check behaviour for working tree and silently
1337
# Even though we can't access the working tree, we need to
1338
# create its control files.
1339
WorkingTreeFormat2().stub_initialize_remote(branch.control_files)
1283
1342
def _open(self, transport):
1287
1346
def __return_repository_format(self):
1288
1347
"""Circular import protection."""
1289
1348
from bzrlib.repository import RepositoryFormat6
1290
return RepositoryFormat6(self)
1349
return RepositoryFormat6()
1291
1350
repository_format = property(__return_repository_format)
1469
1528
inv = serializer_v4.read_inventory(self.branch.control_files.get('inventory'))
1470
1529
new_inv_xml = bzrlib.xml5.serializer_v5.write_inventory_to_string(inv)
1471
1530
# FIXME inventory is a working tree change.
1472
self.branch.control_files.put('inventory', new_inv_xml)
1531
self.branch.control_files.put('inventory', StringIO(new_inv_xml))
1474
1533
def _write_all_weaves(self):
1475
1534
controlweaves = WeaveStore(self.bzrdir.transport, prefixed=False)
1560
1620
entries = inv.iter_entries()
1562
1622
for path, ie in entries:
1563
assert hasattr(ie, 'revision'), \
1623
if inv.is_root(ie.file_id):
1625
assert getattr(ie, 'revision', None) is not None, \
1564
1626
'no revision on {%s} in {%s}' % \
1565
1627
(file_id, rev.revision_id)
1566
1628
new_inv_xml = bzrlib.xml5.serializer_v5.write_inventory_to_string(inv)
1578
1640
mutter('converting texts of revision {%s}',
1580
1642
parent_invs = map(self._load_updated_inventory, present_parents)
1581
entries = inv.iter_entries()
1583
for path, ie in entries:
1644
if inv.is_root(file_id):
1584
1647
self._convert_file_version(rev, ie, parent_invs)
1586
1649
def _convert_file_version(self, rev, ie, parent_invs):
1603
1666
for old_revision in previous_entries:
1604
1667
# if this fails, its a ghost ?
1605
assert old_revision in self.converted_revs
1668
assert old_revision in self.converted_revs, \
1669
"Revision {%s} not in converted_revs" % old_revision
1606
1670
self.snapshot_ie(previous_entries, ie, w, rev_id)
1608
1672
assert getattr(ie, 'revision', None) is not None
1743
1807
for entry in branch_files:
1744
1808
self.move_entry('branch', entry)
1746
self.step('Upgrading working tree')
1747
self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
1748
self.make_lock('checkout')
1749
self.put_format('checkout', bzrlib.workingtree.WorkingTreeFormat3())
1750
self.bzrdir.transport.delete_multi(self.garbage_inventories, self.pb)
1751
1810
checkout_files = [('pending-merges', True),
1752
1811
('inventory', True),
1753
1812
('stat-cache', False)]
1754
for entry in checkout_files:
1755
self.move_entry('checkout', entry)
1756
if last_revision is not None:
1757
self.bzrdir._control_files.put_utf8('checkout/last-revision',
1759
self.bzrdir._control_files.put_utf8('branch-format', BzrDirMetaFormat1().get_format_string())
1813
# If a mandatory checkout file is not present, the branch does not have
1814
# a functional checkout. Do not create a checkout in the converted
1816
for name, mandatory in checkout_files:
1817
if mandatory and name not in bzrcontents:
1818
has_checkout = False
1822
if not has_checkout:
1823
self.pb.note('No working tree.')
1824
# If some checkout files are there, we may as well get rid of them.
1825
for name, mandatory in checkout_files:
1826
if name in bzrcontents:
1827
self.bzrdir.transport.delete(name)
1829
self.step('Upgrading working tree')
1830
self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
1831
self.make_lock('checkout')
1833
'checkout', bzrlib.workingtree.WorkingTreeFormat3())
1834
self.bzrdir.transport.delete_multi(
1835
self.garbage_inventories, self.pb)
1836
for entry in checkout_files:
1837
self.move_entry('checkout', entry)
1838
if last_revision is not None:
1839
self.bzrdir._control_files.put_utf8(
1840
'checkout/last-revision', last_revision)
1841
self.bzrdir._control_files.put_utf8(
1842
'branch-format', BzrDirMetaFormat1().get_format_string())
1760
1843
return BzrDir.open(self.bzrdir.root_transport.base)
1762
1845
def make_lock(self, name):