/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/repofmt/pack_repo.py

Merge bzr.dev and resolve conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
42
42
""")
43
43
from bzrlib import (
44
44
    bzrdir,
45
 
    deprecated_graph,
46
45
    errors,
47
46
    knit,
48
47
    lockable_files,
61
60
    CommitBuilder,
62
61
    MetaDirRepository,
63
62
    MetaDirRepositoryFormat,
 
63
    RepositoryFormat,
64
64
    RootCommitBuilder,
65
65
    )
66
66
import bzrlib.revision as _mod_revision
67
67
from bzrlib.store.revision.knit import KnitRevisionStore
68
68
from bzrlib.store.versioned import VersionedFileStore
69
 
from bzrlib.trace import mutter, note, warning
 
69
from bzrlib.trace import (
 
70
    mutter,
 
71
    mutter_callsite,
 
72
    note,
 
73
    warning,
 
74
    )
70
75
 
71
76
 
72
77
class PackCommitBuilder(CommitBuilder):
198
203
            signature_index)
199
204
        self.name = name
200
205
        self.pack_transport = pack_transport
201
 
        assert None not in (revision_index, inventory_index, text_index,
202
 
            signature_index, name, pack_transport)
 
206
        if None in (revision_index, inventory_index, text_index,
 
207
                signature_index, name, pack_transport):
 
208
            raise AssertionError()
203
209
 
204
210
    def __eq__(self, other):
205
211
        return self.__dict__ == other.__dict__
322
328
 
323
329
    def access_tuple(self):
324
330
        """Return a tuple (transport, name) for the pack content."""
325
 
        assert self._state in ('open', 'finished')
326
331
        if self._state == 'finished':
327
332
            return Pack.access_tuple(self)
328
 
        else:
 
333
        elif self._state == 'open':
329
334
            return self.upload_transport, self.random_name
 
335
        else:
 
336
            raise AssertionError(self._state)
330
337
 
331
338
    def data_inserted(self):
332
339
        """True if data has been added to this pack."""
495
502
        :param index: An index from the pack parameter.
496
503
        :param pack: A Pack instance.
497
504
        """
498
 
        assert self.add_callback is None, \
499
 
            "%s already has a writable index through %s" % \
500
 
            (self, self.add_callback)
 
505
        if self.add_callback is not None:
 
506
            raise AssertionError(
 
507
                "%s already has a writable index through %s" % \
 
508
                (self, self.add_callback))
501
509
        # allow writing: queue writes to a new index
502
510
        self.add_index(index, pack)
503
511
        # Updates the index to packs mapping as a side effect,
596
604
        return NewPack(self._pack_collection._upload_transport,
597
605
            self._pack_collection._index_transport,
598
606
            self._pack_collection._pack_transport, upload_suffix=self.suffix,
599
 
            file_mode=self._pack_collection.repo.control_files._file_mode)
 
607
            file_mode=self._pack_collection.repo.bzrdir._get_file_mode())
600
608
 
601
609
    def _copy_revision_texts(self):
602
610
        """Copy revision data to the new pack."""
1093
1101
        missing_text_keys = self.new_pack._external_compression_parents_of_texts()
1094
1102
        if missing_text_keys:
1095
1103
            raise errors.BzrError('Reference to missing compression parents %r'
1096
 
                % (refs - keys,))
 
1104
                % (missing_text_keys,))
1097
1105
        self._log_copied_texts()
1098
1106
 
1099
1107
    def _use_pack(self, new_pack):
1149
1157
        
1150
1158
        :param pack: A Pack object.
1151
1159
        """
1152
 
        assert pack.name not in self._packs_by_name
 
1160
        if pack.name in self._packs_by_name:
 
1161
            raise AssertionError()
1153
1162
        self.packs.append(pack)
1154
1163
        self._packs_by_name[pack.name] = pack
1155
1164
        self.revision_index.add_index(pack.revision_index, pack)
1577
1586
            for key, value in disk_nodes:
1578
1587
                builder.add_node(key, value)
1579
1588
            self.transport.put_file('pack-names', builder.finish(),
1580
 
                mode=self.repo.control_files._file_mode)
 
1589
                mode=self.repo.bzrdir._get_file_mode())
1581
1590
            # move the baseline forward
1582
1591
            self._packs_at_load = disk_nodes
1583
 
            # now clear out the obsolete packs directory
1584
1592
            if clear_obsolete_packs:
1585
 
                self.transport.clone('obsolete_packs').delete_multi(
1586
 
                    self.transport.list_dir('obsolete_packs'))
 
1593
                self._clear_obsolete_packs()
1587
1594
        finally:
1588
1595
            self._unlock_names()
1589
1596
        # synchronise the memory packs list with what we just wrote:
1615
1622
                self._names[name] = sizes
1616
1623
                self.get_pack_by_name(name)
1617
1624
 
 
1625
    def _clear_obsolete_packs(self):
 
1626
        """Delete everything from the obsolete-packs directory.
 
1627
        """
 
1628
        obsolete_pack_transport = self.transport.clone('obsolete_packs')
 
1629
        for filename in obsolete_pack_transport.list_dir('.'):
 
1630
            try:
 
1631
                obsolete_pack_transport.delete(filename)
 
1632
            except (errors.PathError, errors.TransportError), e:
 
1633
                warning("couldn't delete obsolete pack, skipping it:\n%s" % (e,))
 
1634
 
1618
1635
    def _start_write_group(self):
1619
1636
        # Do not permit preparation for writing if we're not in a 'write lock'.
1620
1637
        if not self.repo.is_write_locked():
1621
1638
            raise errors.NotWriteLocked(self)
1622
1639
        self._new_pack = NewPack(self._upload_transport, self._index_transport,
1623
1640
            self._pack_transport, upload_suffix='.pack',
1624
 
            file_mode=self.repo.control_files._file_mode)
 
1641
            file_mode=self.repo.bzrdir._get_file_mode())
1625
1642
        # allow writing: queue writes to a new index
1626
1643
        self.revision_index.add_writable_index(self._new_pack.revision_index,
1627
1644
            self._new_pack)
1704
1721
            add_callback=add_callback)
1705
1722
        self.repo._revision_knit = knit.KnitVersionedFile(
1706
1723
            'revisions', self.transport.clone('..'),
1707
 
            self.repo.control_files._file_mode,
 
1724
            self.repo.bzrdir._get_file_mode(),
1708
1725
            create=False,
1709
1726
            index=knit_index, delta=False, factory=knit.KnitPlainFactory(),
1710
1727
            access_method=self.repo._pack_collection.revision_index.knit_access)
1722
1739
            add_callback=add_callback, parents=False)
1723
1740
        self.repo._signature_knit = knit.KnitVersionedFile(
1724
1741
            'signatures', self.transport.clone('..'),
1725
 
            self.repo.control_files._file_mode,
 
1742
            self.repo.bzrdir._get_file_mode(),
1726
1743
            create=False,
1727
1744
            index=knit_index, delta=False, factory=knit.KnitPlainFactory(),
1728
1745
            access_method=self.repo._pack_collection.signature_index.knit_access)
1811
1828
            add_callback=add_callback, deltas=True, parents=True)
1812
1829
        return knit.KnitVersionedFile(
1813
1830
            'inventory', self.transport.clone('..'),
1814
 
            self.repo.control_files._file_mode,
 
1831
            self.repo.bzrdir._get_file_mode(),
1815
1832
            create=False,
1816
1833
            index=knit_index, delta=True, factory=knit.KnitPlainFactory(),
1817
1834
            access_method=self.repo._pack_collection.inventory_index.knit_access)
1818
1835
 
1819
1836
 
1820
1837
class KnitPackRepository(KnitRepository):
1821
 
    """Experimental graph-knit using repository."""
 
1838
    """Repository with knit objects stored inside pack containers."""
1822
1839
 
1823
1840
    def __init__(self, _format, a_bzrdir, control_files, _revision_store,
1824
1841
        control_store, text_store, _commit_builder_class, _serializer):
1825
1842
        KnitRepository.__init__(self, _format, a_bzrdir, control_files,
1826
1843
            _revision_store, control_store, text_store, _commit_builder_class,
1827
1844
            _serializer)
1828
 
        index_transport = control_files._transport.clone('indices')
1829
 
        self._pack_collection = RepositoryPackCollection(self, control_files._transport,
 
1845
        index_transport = self._transport.clone('indices')
 
1846
        self._pack_collection = RepositoryPackCollection(self,
 
1847
            self._transport,
1830
1848
            index_transport,
1831
 
            control_files._transport.clone('upload'),
1832
 
            control_files._transport.clone('packs'))
 
1849
            self._transport.clone('upload'),
 
1850
            self._transport.clone('packs'))
1833
1851
        self._revision_store = KnitPackRevisionStore(self, index_transport, self._revision_store)
1834
1852
        self.weave_store = KnitPackTextStore(self, index_transport, self.weave_store)
1835
1853
        self._inv_thunk = InventoryKnitThunk(self, index_transport)
1903
1921
        self._pack_collection.ensure_loaded()
1904
1922
        index = self._pack_collection.revision_index.combined_index
1905
1923
        keys = set(keys)
 
1924
        if None in keys:
 
1925
            raise ValueError('get_parent_map(None) is not valid')
1906
1926
        if _mod_revision.NULL_REVISION in keys:
1907
1927
            keys.discard(_mod_revision.NULL_REVISION)
1908
1928
            found_parents = {_mod_revision.NULL_REVISION:()}
1918
1938
            found_parents[key[0]] = parents
1919
1939
        return found_parents
1920
1940
 
1921
 
    @symbol_versioning.deprecated_method(symbol_versioning.one_four)
1922
 
    @needs_read_lock
1923
 
    def get_revision_graph(self, revision_id=None):
1924
 
        """Return a dictionary containing the revision graph.
1925
 
 
1926
 
        :param revision_id: The revision_id to get a graph from. If None, then
1927
 
        the entire revision graph is returned. This is a deprecated mode of
1928
 
        operation and will be removed in the future.
1929
 
        :return: a dictionary of revision_id->revision_parents_list.
1930
 
        """
1931
 
        if 'evil' in debug.debug_flags:
1932
 
            mutter_callsite(3,
1933
 
                "get_revision_graph scales with size of history.")
1934
 
        # special case NULL_REVISION
1935
 
        if revision_id == _mod_revision.NULL_REVISION:
1936
 
            return {}
1937
 
        if revision_id is None:
1938
 
            revision_vf = self._get_revision_vf()
1939
 
            return revision_vf.get_graph()
1940
 
        g = self.get_graph()
1941
 
        first = g.get_parent_map([revision_id])
1942
 
        if revision_id not in first:
1943
 
            raise errors.NoSuchRevision(self, revision_id)
1944
 
        else:
1945
 
            ancestry = {}
1946
 
            children = {}
1947
 
            NULL_REVISION = _mod_revision.NULL_REVISION
1948
 
            ghosts = set([NULL_REVISION])
1949
 
            for rev_id, parent_ids in g.iter_ancestry([revision_id]):
1950
 
                if parent_ids is None: # This is a ghost
1951
 
                    ghosts.add(rev_id)
1952
 
                    continue
1953
 
                ancestry[rev_id] = parent_ids
1954
 
                for p in parent_ids:
1955
 
                    if p in children:
1956
 
                        children[p].append(rev_id)
1957
 
                    else:
1958
 
                        children[p] = [rev_id]
1959
 
 
1960
 
            if NULL_REVISION in ancestry:
1961
 
                del ancestry[NULL_REVISION]
1962
 
 
1963
 
            # Find all nodes that reference a ghost, and filter the ghosts out
1964
 
            # of their parent lists. To preserve the order of parents, and
1965
 
            # avoid double filtering nodes, we just find all children first,
1966
 
            # and then filter.
1967
 
            children_of_ghosts = set()
1968
 
            for ghost in ghosts:
1969
 
                children_of_ghosts.update(children[ghost])
1970
 
 
1971
 
            for child in children_of_ghosts:
1972
 
                ancestry[child] = tuple(p for p in ancestry[child]
1973
 
                                           if p not in ghosts)
1974
 
            return ancestry
1975
 
 
1976
1941
    def has_revisions(self, revision_ids):
1977
1942
        """See Repository.has_revisions()."""
1978
1943
        revision_ids = set(revision_ids)
2169
2134
        """
2170
2135
        if not _found:
2171
2136
            format = RepositoryFormat.find_format(a_bzrdir)
2172
 
            assert format.__class__ ==  self.__class__
2173
2137
        if _override_transport is not None:
2174
2138
            repo_transport = _override_transport
2175
2139
        else:
2176
2140
            repo_transport = a_bzrdir.get_repository_transport(None)
2177
2141
        control_files = lockable_files.LockableFiles(repo_transport,
2178
 
                                'lock', lockdir.LockDir)
 
2142
            'lock', lockdir.LockDir)
2179
2143
        text_store = self._get_text_store(repo_transport, control_files)
2180
2144
        control_store = self._get_control_store(repo_transport, control_files)
2181
2145
        _revision_store = self._get_revision_store(repo_transport, control_files)