~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Martin Pool
  • Date: 2006-11-02 10:20:19 UTC
  • mfrom: (2114 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2119.
  • Revision ID: mbp@sourcefrog.net-20061102102019-9a5a02f485dff6f6
merge bzr.dev and reconcile several changes, also some test fixes

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
 
17
from cStringIO import StringIO
 
18
 
 
19
from bzrlib.lazy_import import lazy_import
 
20
lazy_import(globals(), """
17
21
from binascii import hexlify
18
22
from copy import deepcopy
19
 
from cStringIO import StringIO
20
23
import re
21
24
import time
22
 
from unittest import TestSuite
 
25
import unittest
23
26
 
24
27
from bzrlib import (
25
 
    bzrdir, 
26
 
    check, 
27
 
    delta, 
28
 
    gpg, 
29
 
    errors, 
 
28
    bzrdir,
 
29
    check,
 
30
    delta,
 
31
    errors,
 
32
    gpg,
 
33
    graph,
 
34
    knit,
 
35
    lockable_files,
 
36
    lockdir,
30
37
    osutils,
 
38
    revision as _mod_revision,
 
39
    symbol_versioning,
31
40
    transactions,
32
 
    ui, 
33
 
    xml5, 
 
41
    ui,
 
42
    weave,
 
43
    weavefile,
 
44
    xml5,
34
45
    xml6,
35
46
    )
 
47
from bzrlib.osutils import (
 
48
    rand_bytes,
 
49
    compact_date, 
 
50
    local_time_offset,
 
51
    )
 
52
from bzrlib.revisiontree import RevisionTree
 
53
from bzrlib.store.versioned import VersionedFileStore
 
54
from bzrlib.store.text import TextStore
 
55
from bzrlib.testament import Testament
 
56
""")
 
57
 
36
58
from bzrlib.decorators import needs_read_lock, needs_write_lock
37
 
from bzrlib.errors import InvalidRevisionId
38
 
from bzrlib.graph import Graph
39
59
from bzrlib.inter import InterObject
40
60
from bzrlib.inventory import Inventory, InventoryDirectory, ROOT_ID
41
 
from bzrlib.knit import KnitVersionedFile, KnitPlainFactory
42
 
from bzrlib.lockable_files import LockableFiles, TransportLock
43
 
from bzrlib.lockdir import LockDir
44
 
from bzrlib.osutils import (safe_unicode, rand_bytes, compact_date, 
45
 
                            local_time_offset)
46
 
from bzrlib.revision import NULL_REVISION, Revision
47
 
from bzrlib.revisiontree import RevisionTree
48
 
from bzrlib.store.versioned import VersionedFileStore, WeaveStore
49
 
from bzrlib.store.text import TextStore
50
 
from bzrlib import symbol_versioning
51
 
from bzrlib.symbol_versioning import (deprecated_method,
52
 
        zero_nine, 
 
61
from bzrlib.symbol_versioning import (
 
62
        deprecated_method,
 
63
        zero_nine,
53
64
        )
54
 
from bzrlib.testament import Testament
55
65
from bzrlib.trace import mutter, note, warning
56
 
from bzrlib.tsort import topo_sort
57
 
from bzrlib.weave import WeaveFile
58
66
 
59
67
 
60
68
# Old formats display a warning, but only once
317
325
        or testing the revision graph.
318
326
        """
319
327
        if not revision_id or not isinstance(revision_id, basestring):
320
 
            raise InvalidRevisionId(revision_id=revision_id, branch=self)
 
328
            raise errors.InvalidRevisionId(revision_id=revision_id,
 
329
                                           branch=self)
321
330
        return self._revision_store.get_revisions([revision_id],
322
331
                                                  self.get_transaction())[0]
323
332
    @needs_read_lock
497
506
        :return: a dictionary of revision_id->revision_parents_list.
498
507
        """
499
508
        # special case NULL_REVISION
500
 
        if revision_id == NULL_REVISION:
 
509
        if revision_id == _mod_revision.NULL_REVISION:
501
510
            return {}
502
 
        weave = self.get_inventory_weave()
503
 
        all_revisions = self._eliminate_revisions_not_present(weave.versions())
504
 
        entire_graph = dict([(node, weave.get_parents(node)) for 
 
511
        a_weave = self.get_inventory_weave()
 
512
        all_revisions = self._eliminate_revisions_not_present(
 
513
                                a_weave.versions())
 
514
        entire_graph = dict([(node, a_weave.get_parents(node)) for 
505
515
                             node in all_revisions])
506
516
        if revision_id is None:
507
517
            return entire_graph
526
536
        :param revision_ids: an iterable of revisions to graph or None for all.
527
537
        :return: a Graph object with the graph reachable from revision_ids.
528
538
        """
529
 
        result = Graph()
 
539
        result = graph.Graph()
530
540
        if not revision_ids:
531
541
            pending = set(self.all_revision_ids())
532
542
            required = set([])
533
543
        else:
534
544
            pending = set(revision_ids)
535
545
            # special case NULL_REVISION
536
 
            if NULL_REVISION in pending:
537
 
                pending.remove(NULL_REVISION)
 
546
            if _mod_revision.NULL_REVISION in pending:
 
547
                pending.remove(_mod_revision.NULL_REVISION)
538
548
            required = set(pending)
539
549
        done = set([])
540
550
        while len(pending):
594
604
        """
595
605
        # TODO: refactor this to use an existing revision object
596
606
        # so we don't need to read it in twice.
597
 
        if revision_id is None or revision_id == NULL_REVISION:
598
 
            return RevisionTree(self, Inventory(), NULL_REVISION)
 
607
        if revision_id is None or revision_id == _mod_revision.NULL_REVISION:
 
608
            return RevisionTree(self, Inventory(root_id=None), 
 
609
                                _mod_revision.NULL_REVISION)
599
610
        else:
600
611
            inv = self.get_revision_inventory(revision_id)
601
612
            return RevisionTree(self, inv, revision_id)
606
617
 
607
618
        `revision_id` may not be None or 'null:'"""
608
619
        assert None not in revision_ids
609
 
        assert NULL_REVISION not in revision_ids
 
620
        assert _mod_revision.NULL_REVISION not in revision_ids
610
621
        texts = self.get_inventory_weave().get_texts(revision_ids)
611
622
        for text, revision_id in zip(texts, revision_ids):
612
623
            inv = self.deserialise_inventory(revision_id, text)
933
944
        :return: a dictionary of revision_id->revision_parents_list.
934
945
        """
935
946
        # special case NULL_REVISION
936
 
        if revision_id == NULL_REVISION:
 
947
        if revision_id == _mod_revision.NULL_REVISION:
937
948
            return {}
938
 
        weave = self._get_revision_vf()
939
 
        entire_graph = weave.get_graph()
 
949
        a_weave = self._get_revision_vf()
 
950
        entire_graph = a_weave.get_graph()
940
951
        if revision_id is None:
941
 
            return weave.get_graph()
942
 
        elif revision_id not in weave:
 
952
            return a_weave.get_graph()
 
953
        elif revision_id not in a_weave:
943
954
            raise errors.NoSuchRevision(self, revision_id)
944
955
        else:
945
956
            # add what can be reached from revision_id
947
958
            pending = set([revision_id])
948
959
            while len(pending) > 0:
949
960
                node = pending.pop()
950
 
                result[node] = weave.get_parents(node)
 
961
                result[node] = a_weave.get_parents(node)
951
962
                for revision_id in result[node]:
952
963
                    if revision_id not in result:
953
964
                        pending.add(revision_id)
960
971
        :param revision_ids: an iterable of revisions to graph or None for all.
961
972
        :return: a Graph object with the graph reachable from revision_ids.
962
973
        """
963
 
        result = Graph()
 
974
        result = graph.Graph()
964
975
        vf = self._get_revision_vf()
965
976
        versions = set(vf.versions())
966
977
        if not revision_ids:
969
980
        else:
970
981
            pending = set(revision_ids)
971
982
            # special case NULL_REVISION
972
 
            if NULL_REVISION in pending:
973
 
                pending.remove(NULL_REVISION)
 
983
            if _mod_revision.NULL_REVISION in pending:
 
984
                pending.remove(_mod_revision.NULL_REVISION)
974
985
            required = set(pending)
975
986
        done = set([])
976
987
        while len(pending):
1155
1166
                                  transport,
1156
1167
                                  control_files,
1157
1168
                                  prefixed=True,
1158
 
                                  versionedfile_class=WeaveFile,
 
1169
                                  versionedfile_class=weave.WeaveFile,
1159
1170
                                  versionedfile_kwargs={},
1160
1171
                                  escaped=False):
1161
1172
        weave_transport = control_files._transport.clone(name)
1222
1233
        TODO: when creating split out bzr branch formats, move this to a common
1223
1234
        base for Format5, Format6. or something like that.
1224
1235
        """
1225
 
        from bzrlib.weavefile import write_weave_v5
1226
 
        from bzrlib.weave import Weave
1227
 
 
1228
1236
        if shared:
1229
1237
            raise errors.IncompatibleFormat(self, a_bzrdir._format)
1230
1238
 
1234
1242
        
1235
1243
        # Create an empty weave
1236
1244
        sio = StringIO()
1237
 
        write_weave_v5(Weave(), sio)
 
1245
        weavefile.write_weave_v5(weave.Weave(), sio)
1238
1246
        empty_weave = sio.getvalue()
1239
1247
 
1240
1248
        mutter('creating repository in %s.', a_bzrdir.transport.base)
1244
1252
        
1245
1253
        # FIXME: RBC 20060125 don't peek under the covers
1246
1254
        # NB: no need to escape relative paths that are url safe.
1247
 
        control_files = LockableFiles(a_bzrdir.transport, 'branch-lock',
1248
 
                                      TransportLock)
 
1255
        control_files = lockable_files.LockableFiles(a_bzrdir.transport,
 
1256
                                'branch-lock', lockable_files.TransportLock)
1249
1257
        control_files.create_lock()
1250
1258
        control_files.lock_write()
1251
1259
        control_files._transport.mkdir_multi(dirs,
1415
1423
        # FIXME: RBC 20060125 don't peek under the covers
1416
1424
        # NB: no need to escape relative paths that are url safe.
1417
1425
        repository_transport = a_bzrdir.get_repository_transport(self)
1418
 
        control_files = LockableFiles(repository_transport, 'lock', LockDir)
 
1426
        control_files = lockable_files.LockableFiles(repository_transport,
 
1427
                                'lock', lockdir.LockDir)
1419
1428
        control_files.create_lock()
1420
1429
        return control_files
1421
1430
 
1487
1496
        :param shared: If true the repository will be initialized as a shared
1488
1497
                       repository.
1489
1498
        """
1490
 
        from bzrlib.weavefile import write_weave_v5
1491
 
        from bzrlib.weave import Weave
1492
 
 
1493
1499
        # Create an empty weave
1494
1500
        sio = StringIO()
1495
 
        write_weave_v5(Weave(), sio)
 
1501
        weavefile.write_weave_v5(weave.Weave(), sio)
1496
1502
        empty_weave = sio.getvalue()
1497
1503
 
1498
1504
        mutter('creating repository in %s.', a_bzrdir.transport.base)
1518
1524
            repo_transport = _override_transport
1519
1525
        else:
1520
1526
            repo_transport = a_bzrdir.get_repository_transport(None)
1521
 
        control_files = LockableFiles(repo_transport, 'lock', LockDir)
 
1527
        control_files = lockable_files.LockableFiles(repo_transport,
 
1528
                                'lock', lockdir.LockDir)
1522
1529
        text_store = self._get_text_store(repo_transport, control_files)
1523
1530
        control_store = self._get_control_store(repo_transport, control_files)
1524
1531
        _revision_store = self._get_revision_store(repo_transport, control_files)
1550
1557
            repo_transport,
1551
1558
            prefixed=False,
1552
1559
            file_mode=control_files._file_mode,
1553
 
            versionedfile_class=KnitVersionedFile,
1554
 
            versionedfile_kwargs={'factory':KnitPlainFactory()},
 
1560
            versionedfile_class=knit.KnitVersionedFile,
 
1561
            versionedfile_kwargs={'factory':knit.KnitPlainFactory()},
1555
1562
            )
1556
1563
 
1557
1564
    def _get_revision_store(self, repo_transport, control_files):
1562
1569
            file_mode=control_files._file_mode,
1563
1570
            prefixed=False,
1564
1571
            precious=True,
1565
 
            versionedfile_class=KnitVersionedFile,
1566
 
            versionedfile_kwargs={'delta':False, 'factory':KnitPlainFactory(),},
 
1572
            versionedfile_class=knit.KnitVersionedFile,
 
1573
            versionedfile_kwargs={'delta':False,
 
1574
                                  'factory':knit.KnitPlainFactory(),
 
1575
                                 },
1567
1576
            escaped=True,
1568
1577
            )
1569
1578
        return KnitRevisionStore(versioned_file_store)
1571
1580
    def _get_text_store(self, transport, control_files):
1572
1581
        """See RepositoryFormat._get_text_store()."""
1573
1582
        return self._get_versioned_file_store('knits',
1574
 
                                              transport,
1575
 
                                              control_files,
1576
 
                                              versionedfile_class=KnitVersionedFile,
1577
 
                                              versionedfile_kwargs={
1578
 
                                                  'create_parent_dir':True,
1579
 
                                                  'delay_create':True,
1580
 
                                                  'dir_mode':control_files._dir_mode,
1581
 
                                              },
1582
 
                                              escaped=True)
 
1583
                                  transport,
 
1584
                                  control_files,
 
1585
                                  versionedfile_class=knit.KnitVersionedFile,
 
1586
                                  versionedfile_kwargs={
 
1587
                                      'create_parent_dir':True,
 
1588
                                      'delay_create':True,
 
1589
                                      'dir_mode':control_files._dir_mode,
 
1590
                                  },
 
1591
                                  escaped=True)
1583
1592
 
1584
1593
    def initialize(self, a_bzrdir, shared=False):
1585
1594
        """Create a knit format 1 repository.
1596
1605
        
1597
1606
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
1598
1607
        repo_transport = a_bzrdir.get_repository_transport(None)
1599
 
        control_files = LockableFiles(repo_transport, 'lock', LockDir)
 
1608
        control_files = lockable_files.LockableFiles(repo_transport,
 
1609
                                'lock', lockdir.LockDir)
1600
1610
        control_store = self._get_control_store(repo_transport, control_files)
1601
1611
        transaction = transactions.WriteTransaction()
1602
1612
        # trigger a write of the inventory store.
1620
1630
            repo_transport = _override_transport
1621
1631
        else:
1622
1632
            repo_transport = a_bzrdir.get_repository_transport(None)
1623
 
        control_files = LockableFiles(repo_transport, 'lock', LockDir)
 
1633
        control_files = lockable_files.LockableFiles(repo_transport,
 
1634
                                'lock', lockdir.LockDir)
1624
1635
        text_store = self._get_text_store(repo_transport, control_files)
1625
1636
        control_store = self._get_control_store(repo_transport, control_files)
1626
1637
        _revision_store = self._get_revision_store(repo_transport, control_files)
1705
1716
            repo_transport = _override_transport
1706
1717
        else:
1707
1718
            repo_transport = a_bzrdir.get_repository_transport(None)
1708
 
        control_files = LockableFiles(repo_transport, 'lock', LockDir)
 
1719
        control_files = lockable_files.LockableFiles(repo_transport, 'lock',
 
1720
                                                     lockdir.LockDir)
1709
1721
        text_store = self._get_text_store(repo_transport, control_files)
1710
1722
        control_store = self._get_control_store(repo_transport, control_files)
1711
1723
        _revision_store = self._get_revision_store(repo_transport, control_files)
1826
1838
        if basis is not None:
1827
1839
            self.target.fetch(basis, revision_id=revision_id)
1828
1840
        # but don't bother fetching if we have the needed data now.
1829
 
        if (revision_id not in (None, NULL_REVISION) and 
 
1841
        if (revision_id not in (None, _mod_revision.NULL_REVISION) and 
1830
1842
            self.target.has_revision(revision_id)):
1831
1843
            return
1832
1844
        self.target.fetch(self.source, revision_id=revision_id)
2070
2082
        if basis is not None:
2071
2083
            self.target.fetch(basis, revision_id=revision_id)
2072
2084
        # but don't bother fetching if we have the needed data now.
2073
 
        if (revision_id not in (None, NULL_REVISION) and 
 
2085
        if (revision_id not in (None, _mod_revision.NULL_REVISION) and 
2074
2086
            self.target.has_revision(revision_id)):
2075
2087
            return
2076
2088
        self.target.fetch(self.source, revision_id=revision_id)
2125
2137
        self._formats = formats
2126
2138
    
2127
2139
    def adapt(self, test):
2128
 
        result = TestSuite()
 
2140
        result = unittest.TestSuite()
2129
2141
        for repository_format, bzrdir_format in self._formats:
2130
2142
            new_test = deepcopy(test)
2131
2143
            new_test.transport_server = self._transport_server
2155
2167
        self._formats = formats
2156
2168
    
2157
2169
    def adapt(self, test):
2158
 
        result = TestSuite()
 
2170
        result = unittest.TestSuite()
2159
2171
        for interrepo_class, repository_format, repository_format_to in self._formats:
2160
2172
            new_test = deepcopy(test)
2161
2173
            new_test.transport_server = self._transport_server
2304
2316
 
2305
2317
        :return: The revision id of the recorded revision.
2306
2318
        """
2307
 
        rev = Revision(timestamp=self._timestamp,
 
2319
        rev = _mod_revision.Revision(
 
2320
                       timestamp=self._timestamp,
2308
2321
                       timezone=self._timezone,
2309
2322
                       committer=self._committer,
2310
2323
                       message=message,