/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
# TODO: remove unittest dependency; put that stuff inside the test suite
24
24
 
25
 
from copy import deepcopy
 
25
# TODO: The Format probe_transport seems a bit redundant with just trying to
 
26
# open the bzrdir. -- mbp
 
27
#
 
28
# TODO: Can we move specific formats into separate modules to make this file
 
29
# smaller?
 
30
 
26
31
from cStringIO import StringIO
27
32
import os
 
33
 
 
34
from bzrlib.lazy_import import lazy_import
 
35
lazy_import(globals(), """
 
36
from copy import deepcopy
28
37
from stat import S_ISDIR
29
 
from unittest import TestSuite
 
38
import unittest
30
39
 
31
40
import bzrlib
32
 
import bzrlib.errors as errors
33
 
from bzrlib.lockable_files import LockableFiles, TransportLock
34
 
from bzrlib.lockdir import LockDir
 
41
from bzrlib import (
 
42
    errors,
 
43
    lockable_files,
 
44
    lockdir,
 
45
    revision as _mod_revision,
 
46
    urlutils,
 
47
    xml4,
 
48
    xml5,
 
49
    )
35
50
from bzrlib.osutils import (
36
 
                            abspath,
37
 
                            pathjoin,
38
 
                            safe_unicode,
39
 
                            sha_strings,
40
 
                            sha_string,
41
 
                            )
42
 
import bzrlib.revision
 
51
    safe_unicode,
 
52
    sha_strings,
 
53
    sha_string,
 
54
    )
43
55
from bzrlib.store.revision.text import TextRevisionStore
44
56
from bzrlib.store.text import TextStore
45
57
from bzrlib.store.versioned import WeaveStore
46
 
from bzrlib.trace import mutter
47
58
from bzrlib.transactions import WriteTransaction
48
59
from bzrlib.transport import get_transport
 
60
from bzrlib.weave import Weave
 
61
""")
 
62
 
 
63
from bzrlib.trace import mutter
49
64
from bzrlib.transport.local import LocalTransport
50
 
import bzrlib.urlutils as urlutils
51
 
from bzrlib.weave import Weave
52
 
from bzrlib.xml4 import serializer_v4
53
 
import bzrlib.xml5
54
65
 
55
66
 
56
67
class BzrDir(object):
87
98
        """Return true if this bzrdir is one whose format we can convert from."""
88
99
        return True
89
100
 
 
101
    def check_conversion_target(self, target_format):
 
102
        target_repo_format = target_format.repository_format
 
103
        source_repo_format = self._format.repository_format
 
104
        source_repo_format.check_conversion_target(target_repo_format)
 
105
 
90
106
    @staticmethod
91
107
    def _check_supported(format, allow_unsupported):
92
108
        """Check whether format is a supported format.
177
193
    def _make_tail(self, url):
178
194
        head, tail = urlutils.split(url)
179
195
        if tail and tail != '.':
180
 
            t = bzrlib.transport.get_transport(head)
 
196
            t = get_transport(head)
181
197
            try:
182
198
                t.mkdir(tail)
183
199
            except errors.FileExists:
199
215
                    "not one of %r" % cls)
200
216
        head, tail = urlutils.split(base)
201
217
        if tail and tail != '.':
202
 
            t = bzrlib.transport.get_transport(head)
 
218
            t = get_transport(head)
203
219
            try:
204
220
                t.mkdir(tail)
205
221
            except errors.FileExists:
293
309
        This will use the current default BzrDirFormat, and use whatever 
294
310
        repository format that that uses for bzrdirformat.create_repository.
295
311
 
296
 
        ;param shared: Create a shared repository rather than a standalone
 
312
        :param shared: Create a shared repository rather than a standalone
297
313
                       repository.
298
314
        The Repository object is returned.
299
315
 
314
330
        repository format that that uses for bzrdirformat.create_workingtree,
315
331
        create_branch and create_repository.
316
332
 
317
 
        The WorkingTree object is returned.
 
333
        :return: The WorkingTree object.
318
334
        """
319
335
        t = get_transport(safe_unicode(base))
320
336
        if not isinstance(t, LocalTransport):
330
346
        """
331
347
        raise NotImplementedError(self.create_workingtree)
332
348
 
 
349
    def destroy_workingtree(self):
 
350
        """Destroy the working tree at this BzrDir.
 
351
 
 
352
        Formats that do not support this may raise UnsupportedOperation.
 
353
        """
 
354
        raise NotImplementedError(self.destroy_workingtree)
 
355
 
 
356
    def destroy_workingtree_metadata(self):
 
357
        """Destroy the control files for the working tree at this BzrDir.
 
358
 
 
359
        The contents of working tree files are not affected.
 
360
        Formats that do not support this may raise UnsupportedOperation.
 
361
        """
 
362
        raise NotImplementedError(self.destroy_workingtree_metadata)
 
363
 
333
364
    def find_repository(self):
334
365
        """Find the repository that should be used for a_bzrdir.
335
366
 
461
492
        _unsupported is a private parameter to the BzrDir class.
462
493
        """
463
494
        t = get_transport(base)
464
 
        # mutter("trying to open %r with transport %r", base, t)
465
 
        format = BzrDirFormat.find_format(t)
 
495
        return BzrDir.open_from_transport(t, _unsupported=_unsupported)
 
496
 
 
497
    @staticmethod
 
498
    def open_from_transport(transport, _unsupported=False):
 
499
        """Open a bzrdir within a particular directory.
 
500
 
 
501
        :param transport: Transport containing the bzrdir.
 
502
        :param _unsupported: private.
 
503
        """
 
504
        format = BzrDirFormat.find_format(transport)
466
505
        BzrDir._check_supported(format, _unsupported)
467
 
        return format.open(t, _found=True)
 
506
        return format.open(transport, _found=True)
468
507
 
469
508
    def open_branch(self, unsupported=False):
470
509
        """Open the branch object at this BzrDir if one is present.
504
543
        url = a_transport.base
505
544
        while True:
506
545
            try:
507
 
                format = BzrDirFormat.find_format(a_transport)
508
 
                BzrDir._check_supported(format, False)
509
 
                return format.open(a_transport), urlutils.unescape(a_transport.relpath(url))
 
546
                result = BzrDir.open_from_transport(a_transport)
 
547
                return result, urlutils.unescape(a_transport.relpath(url))
510
548
            except errors.NotBranchError, e:
511
 
                ## mutter('not a branch in: %r %s', a_transport.base, e)
512
549
                pass
513
550
            new_t = a_transport.clone('..')
514
551
            if new_t.base == a_transport.base:
564
601
        except errors.NoWorkingTree:
565
602
            return False
566
603
 
 
604
    def cloning_metadir(self, basis=None):
 
605
        """Produce a metadir suitable for cloning with"""
 
606
        def related_repository(bzrdir):
 
607
            try:
 
608
                branch = bzrdir.open_branch()
 
609
                return branch.repository
 
610
            except errors.NotBranchError:
 
611
                source_branch = None
 
612
                return bzrdir.open_repository()
 
613
        result_format = self._format.__class__()
 
614
        try:
 
615
            try:
 
616
                source_repository = related_repository(self)
 
617
            except errors.NoRepositoryPresent:
 
618
                if basis is None:
 
619
                    raise
 
620
                source_repository = related_repository(self)
 
621
            result_format.repository_format = source_repository._format
 
622
        except errors.NoRepositoryPresent:
 
623
            pass
 
624
        return result_format
 
625
 
567
626
    def sprout(self, url, revision_id=None, basis=None, force_new_repo=False):
568
627
        """Create a copy of this bzrdir prepared for use as a new line of
569
628
        development.
579
638
            itself to download less data.
580
639
        """
581
640
        self._make_tail(url)
582
 
        result = self._format.initialize(url)
 
641
        cloning_format = self.cloning_metadir(basis)
 
642
        result = cloning_format.initialize(url)
583
643
        basis_repo, basis_branch, basis_tree = self._get_basis_components(basis)
584
644
        try:
585
645
            source_branch = self.open_branch()
625
685
        # TODO: jam 20060426 we probably need a test in here in the
626
686
        #       case that the newly sprouted branch is a remote one
627
687
        if result_repo is None or result_repo.make_working_trees():
628
 
            result.create_workingtree()
 
688
            wt = result.create_workingtree()
 
689
            if wt.inventory.root is None:
 
690
                try:
 
691
                    wt.set_root_id(self.open_workingtree.get_root_id())
 
692
                except errors.NoWorkingTree:
 
693
                    pass
629
694
        return result
630
695
 
631
696
 
635
700
    def __init__(self, _transport, _format):
636
701
        """See BzrDir.__init__."""
637
702
        super(BzrDirPreSplitOut, self).__init__(_transport, _format)
638
 
        assert self._format._lock_class == TransportLock
 
703
        assert self._format._lock_class == lockable_files.TransportLock
639
704
        assert self._format._lock_file_name == 'branch-lock'
640
 
        self._control_files = LockableFiles(self.get_branch_transport(None),
 
705
        self._control_files = lockable_files.LockableFiles(
 
706
                                            self.get_branch_transport(None),
641
707
                                            self._format._lock_file_name,
642
708
                                            self._format._lock_class)
643
709
 
687
753
        # done on this format anyway. So - acceptable wart.
688
754
        result = self.open_workingtree()
689
755
        if revision_id is not None:
690
 
            if revision_id == bzrlib.revision.NULL_REVISION:
 
756
            if revision_id == _mod_revision.NULL_REVISION:
691
757
                result.set_parent_ids([])
692
758
            else:
693
759
                result.set_parent_ids([revision_id])
694
760
        return result
695
761
 
 
762
    def destroy_workingtree(self):
 
763
        """See BzrDir.destroy_workingtree."""
 
764
        raise errors.UnsupportedOperation(self.destroy_workingtree, self)
 
765
 
 
766
    def destroy_workingtree_metadata(self):
 
767
        """See BzrDir.destroy_workingtree_metadata."""
 
768
        raise errors.UnsupportedOperation(self.destroy_workingtree_metadata, 
 
769
                                          self)
 
770
 
696
771
    def get_branch_transport(self, branch_format):
697
772
        """See BzrDir.get_branch_transport()."""
698
773
        if branch_format is None:
838
913
        from bzrlib.workingtree import WorkingTreeFormat
839
914
        return WorkingTreeFormat.get_default_format().initialize(self, revision_id)
840
915
 
 
916
    def destroy_workingtree(self):
 
917
        """See BzrDir.destroy_workingtree."""
 
918
        wt = self.open_workingtree()
 
919
        repository = wt.branch.repository
 
920
        empty = repository.revision_tree(bzrlib.revision.NULL_REVISION)
 
921
        wt.revert([], old_tree=empty)
 
922
        self.destroy_workingtree_metadata()
 
923
 
 
924
    def destroy_workingtree_metadata(self):
 
925
        self.transport.delete_tree('checkout')
 
926
 
841
927
    def _get_mkdir_mode(self):
842
928
        """Figure out the mode to use when creating a bzrdir subdir."""
843
 
        temp_control = LockableFiles(self.transport, '', TransportLock)
 
929
        temp_control = lockable_files.LockableFiles(self.transport, '',
 
930
                                     lockable_files.TransportLock)
844
931
        return temp_control._dir_mode
845
932
 
846
933
    def get_branch_transport(self, branch_format):
1022
1109
        """Initialize a new bzrdir in the base directory of a Transport."""
1023
1110
        # Since we don't have a .bzr directory, inherit the
1024
1111
        # mode from the root directory
1025
 
        temp_control = LockableFiles(transport, '', TransportLock)
 
1112
        temp_control = lockable_files.LockableFiles(transport,
 
1113
                            '', lockable_files.TransportLock)
1026
1114
        temp_control._transport.mkdir('.bzr',
1027
1115
                                      # FIXME: RBC 20060121 don't peek under
1028
1116
                                      # the covers
1037
1125
                      ('branch-format', self.get_format_string()),
1038
1126
                      ]
1039
1127
        # NB: no need to escape relative paths that are url safe.
1040
 
        control_files = LockableFiles(control, self._lock_file_name, 
1041
 
                                      self._lock_class)
 
1128
        control_files = lockable_files.LockableFiles(control,
 
1129
                            self._lock_file_name, self._lock_class)
1042
1130
        control_files.create_lock()
1043
1131
        control_files.lock_write()
1044
1132
        try:
1057
1145
        """
1058
1146
        return True
1059
1147
 
 
1148
    def same_model(self, target_format):
 
1149
        return (self.repository_format.rich_root_data == 
 
1150
            target_format.rich_root_data)
 
1151
 
1060
1152
    @classmethod
1061
1153
    def known_formats(klass):
1062
1154
        """Return all the known formats.
1143
1235
    removed in format 5; write support for this format has been removed.
1144
1236
    """
1145
1237
 
1146
 
    _lock_class = TransportLock
 
1238
    _lock_class = lockable_files.TransportLock
1147
1239
 
1148
1240
    def get_format_string(self):
1149
1241
        """See BzrDirFormat.get_format_string()."""
1178
1270
    def __return_repository_format(self):
1179
1271
        """Circular import protection."""
1180
1272
        from bzrlib.repository import RepositoryFormat4
1181
 
        return RepositoryFormat4(self)
 
1273
        return RepositoryFormat4()
1182
1274
    repository_format = property(__return_repository_format)
1183
1275
 
1184
1276
 
1193
1285
       Unhashed stores in the repository.
1194
1286
    """
1195
1287
 
1196
 
    _lock_class = TransportLock
 
1288
    _lock_class = lockable_files.TransportLock
1197
1289
 
1198
1290
    def get_format_string(self):
1199
1291
        """See BzrDirFormat.get_format_string()."""
1238
1330
    def __return_repository_format(self):
1239
1331
        """Circular import protection."""
1240
1332
        from bzrlib.repository import RepositoryFormat5
1241
 
        return RepositoryFormat5(self)
 
1333
        return RepositoryFormat5()
1242
1334
    repository_format = property(__return_repository_format)
1243
1335
 
1244
1336
 
1252
1344
     - Format 6 repositories [always]
1253
1345
    """
1254
1346
 
1255
 
    _lock_class = TransportLock
 
1347
    _lock_class = lockable_files.TransportLock
1256
1348
 
1257
1349
    def get_format_string(self):
1258
1350
        """See BzrDirFormat.get_format_string()."""
1297
1389
    def __return_repository_format(self):
1298
1390
        """Circular import protection."""
1299
1391
        from bzrlib.repository import RepositoryFormat6
1300
 
        return RepositoryFormat6(self)
 
1392
        return RepositoryFormat6()
1301
1393
    repository_format = property(__return_repository_format)
1302
1394
 
1303
1395
 
1312
1404
     - Format 7 repositories [optional]
1313
1405
    """
1314
1406
 
1315
 
    _lock_class = LockDir
 
1407
    _lock_class = lockdir.LockDir
1316
1408
 
1317
1409
    def get_converter(self, format=None):
1318
1410
        """See BzrDirFormat.get_converter()."""
1372
1464
        self._formats = formats
1373
1465
    
1374
1466
    def adapt(self, test):
1375
 
        result = TestSuite()
 
1467
        result = unittest.TestSuite()
1376
1468
        for format in self._formats:
1377
1469
            new_test = deepcopy(test)
1378
1470
            new_test.transport_server = self._transport_server
1476
1568
        self.bzrdir.transport.delete_tree('text-store')
1477
1569
 
1478
1570
    def _convert_working_inv(self):
1479
 
        inv = serializer_v4.read_inventory(self.branch.control_files.get('inventory'))
1480
 
        new_inv_xml = bzrlib.xml5.serializer_v5.write_inventory_to_string(inv)
 
1571
        inv = xml4.serializer_v4.read_inventory(
 
1572
                    self.branch.control_files.get('inventory'))
 
1573
        new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
1481
1574
        # FIXME inventory is a working tree change.
1482
1575
        self.branch.control_files.put('inventory', StringIO(new_inv_xml))
1483
1576
 
1509
1602
                                                      prefixed=False,
1510
1603
                                                      compressed=True))
1511
1604
        try:
1512
 
            transaction = bzrlib.transactions.WriteTransaction()
 
1605
            transaction = WriteTransaction()
1513
1606
            for i, rev_id in enumerate(self.converted_revs):
1514
1607
                self.pb.update('write revision', i, len(self.converted_revs))
1515
1608
                _revision_store.add_revision(self.revisions[rev_id], transaction)
1541
1634
    def _load_old_inventory(self, rev_id):
1542
1635
        assert rev_id not in self.converted_revs
1543
1636
        old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
1544
 
        inv = serializer_v4.read_inventory_from_string(old_inv_xml)
 
1637
        inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
 
1638
        inv.revision_id = rev_id
1545
1639
        rev = self.revisions[rev_id]
1546
1640
        if rev.inventory_sha1:
1547
1641
            assert rev.inventory_sha1 == sha_string(old_inv_xml), \
1551
1645
    def _load_updated_inventory(self, rev_id):
1552
1646
        assert rev_id in self.converted_revs
1553
1647
        inv_xml = self.inv_weave.get_text(rev_id)
1554
 
        inv = bzrlib.xml5.serializer_v5.read_inventory_from_string(inv_xml)
 
1648
        inv = xml5.serializer_v5.read_inventory_from_string(inv_xml)
1555
1649
        return inv
1556
1650
 
1557
1651
    def _convert_one_rev(self, rev_id):
1570
1664
            entries = inv.iter_entries()
1571
1665
            entries.next()
1572
1666
            for path, ie in entries:
1573
 
                assert hasattr(ie, 'revision'), \
 
1667
                assert getattr(ie, 'revision', None) is not None, \
1574
1668
                    'no revision on {%s} in {%s}' % \
1575
1669
                    (file_id, rev.revision_id)
1576
 
        new_inv_xml = bzrlib.xml5.serializer_v5.write_inventory_to_string(inv)
 
1670
        new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
1577
1671
        new_inv_sha1 = sha_string(new_inv_xml)
1578
1672
        self.inv_weave.add_lines(rev.revision_id, 
1579
1673
                                 present_parents,
1612
1706
                                                  entry_vf=w)
1613
1707
        for old_revision in previous_entries:
1614
1708
                # if this fails, its a ghost ?
1615
 
                assert old_revision in self.converted_revs 
 
1709
                assert old_revision in self.converted_revs, \
 
1710
                    "Revision {%s} not in converted_revs" % old_revision
1616
1711
        self.snapshot_ie(previous_entries, ie, w, rev_id)
1617
1712
        del ie.text_id
1618
1713
        assert getattr(ie, 'revision', None) is not None
1791
1886
    def make_lock(self, name):
1792
1887
        """Make a lock for the new control dir name."""
1793
1888
        self.step('Make %s lock' % name)
1794
 
        ld = LockDir(self.bzrdir.transport, 
1795
 
                     '%s/lock' % name,
1796
 
                     file_modebits=self.file_mode,
1797
 
                     dir_modebits=self.dir_mode)
 
1889
        ld = lockdir.LockDir(self.bzrdir.transport,
 
1890
                             '%s/lock' % name,
 
1891
                             file_modebits=self.file_mode,
 
1892
                             dir_modebits=self.dir_mode)
1798
1893
        ld.create()
1799
1894
 
1800
1895
    def move_entry(self, new_dir, entry):