~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/vf_repository.py

  • Committer: Patch Queue Manager
  • Date: 2011-10-14 16:54:26 UTC
  • mfrom: (6216.1.1 remove-this-file)
  • Revision ID: pqm@pqm.ubuntu.com-20111014165426-tjix4e6idryf1r2z
(jelmer) Remove an accidentally committed .THIS file. (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Repository formats built around versioned files."""
18
18
 
19
 
from __future__ import absolute_import
20
 
 
21
19
 
22
20
from bzrlib.lazy_import import lazy_import
23
21
lazy_import(globals(), """
25
23
 
26
24
from bzrlib import (
27
25
    check,
28
 
    config as _mod_config,
29
26
    debug,
30
27
    fetch as _mod_fetch,
31
28
    fifo_cache,
41
38
    tsort,
42
39
    ui,
43
40
    versionedfile,
44
 
    vf_search,
45
41
    )
46
42
 
47
43
from bzrlib.recordcounter import RecordCounter
69
65
    CommitBuilder,
70
66
    InterRepository,
71
67
    MetaDirRepository,
72
 
    RepositoryFormatMetaDir,
 
68
    MetaDirRepositoryFormat,
73
69
    Repository,
74
70
    RepositoryFormat,
75
71
    )
84
80
 
85
81
    supports_full_versioned_files = True
86
82
    supports_versioned_directories = True
87
 
    supports_unreferenced_revisions = True
88
83
 
89
84
    # Should commit add an inventory, or an inventory delta to the repository.
90
85
    _commit_inv_deltas = True
109
104
    # the default CommitBuilder does not manage trees whose root is versioned.
110
105
    _versioned_root = False
111
106
 
112
 
    def __init__(self, repository, parents, config_stack, timestamp=None,
 
107
    def __init__(self, repository, parents, config, timestamp=None,
113
108
                 timezone=None, committer=None, revprops=None,
114
109
                 revision_id=None, lossy=False):
115
110
        super(VersionedFileCommitBuilder, self).__init__(repository,
116
 
            parents, config_stack, timestamp, timezone, committer, revprops,
 
111
            parents, config, timestamp, timezone, committer, revprops,
117
112
            revision_id, lossy)
118
113
        try:
119
114
            basis_id = self.parents[0]
200
195
                       revision_id=self._new_revision_id,
201
196
                       properties=self._revprops)
202
197
        rev.parent_ids = self.parents
203
 
        if self._config_stack.get('create_signatures') == _mod_config.SIGN_ALWAYS:
204
 
            testament = Testament(rev, self.revision_tree())
205
 
            plaintext = testament.as_short_text()
206
 
            self.repository.store_revision_signature(
207
 
                gpg.GPGStrategy(self._config_stack), plaintext,
208
 
                self._new_revision_id)
209
 
        self.repository._add_revision(rev)
 
198
        self.repository.add_revision(self._new_revision_id, rev,
 
199
            self.new_inventory, self._config)
210
200
        self._ensure_fallback_inventories()
211
201
        self.repository.commit_write_group()
212
202
        return self._new_revision_id
1038
1028
        self.inventories._access.flush()
1039
1029
        return result
1040
1030
 
1041
 
    def add_revision(self, revision_id, rev, inv=None):
 
1031
    def add_revision(self, revision_id, rev, inv=None, config=None):
1042
1032
        """Add rev to the revision store as revision_id.
1043
1033
 
1044
1034
        :param revision_id: the revision id to use.
1045
1035
        :param rev: The revision object.
1046
1036
        :param inv: The inventory for the revision. if None, it will be looked
1047
1037
                    up in the inventory storer
 
1038
        :param config: If None no digital signature will be created.
 
1039
                       If supplied its signature_needed method will be used
 
1040
                       to determine if a signature should be made.
1048
1041
        """
1049
1042
        # TODO: jam 20070210 Shouldn't we check rev.revision_id and
1050
1043
        #       rev.parent_ids?
1051
1044
        _mod_revision.check_not_reserved_id(revision_id)
 
1045
        if config is not None and config.signature_needed():
 
1046
            if inv is None:
 
1047
                inv = self.get_inventory(revision_id)
 
1048
            tree = InventoryRevisionTree(self, inv, revision_id)
 
1049
            testament = Testament(rev, tree)
 
1050
            plaintext = testament.as_short_text()
 
1051
            self.store_revision_signature(
 
1052
                gpg.GPGStrategy(config), plaintext, revision_id)
1052
1053
        # check inventory present
1053
1054
        if not self.inventories.get_parent_map([(revision_id,)]):
1054
1055
            if inv is None:
1218
1219
        # rather copying them?
1219
1220
        self._safe_to_return_from_cache = False
1220
1221
 
1221
 
    def fetch(self, source, revision_id=None, find_ghosts=False,
1222
 
            fetch_spec=None):
1223
 
        """Fetch the content required to construct revision_id from source.
1224
 
 
1225
 
        If revision_id is None and fetch_spec is None, then all content is
1226
 
        copied.
1227
 
 
1228
 
        fetch() may not be used when the repository is in a write group -
1229
 
        either finish the current write group before using fetch, or use
1230
 
        fetch before starting the write group.
1231
 
 
1232
 
        :param find_ghosts: Find and copy revisions in the source that are
1233
 
            ghosts in the target (and not reachable directly by walking out to
1234
 
            the first-present revision in target from revision_id).
1235
 
        :param revision_id: If specified, all the content needed for this
1236
 
            revision ID will be copied to the target.  Fetch will determine for
1237
 
            itself which content needs to be copied.
1238
 
        :param fetch_spec: If specified, a SearchResult or
1239
 
            PendingAncestryResult that describes which revisions to copy.  This
1240
 
            allows copying multiple heads at once.  Mutually exclusive with
1241
 
            revision_id.
1242
 
        """
1243
 
        if fetch_spec is not None and revision_id is not None:
1244
 
            raise AssertionError(
1245
 
                "fetch_spec and revision_id are mutually exclusive.")
1246
 
        if self.is_in_write_group():
1247
 
            raise errors.InternalBzrError(
1248
 
                "May not fetch while in a write group.")
1249
 
        # fast path same-url fetch operations
1250
 
        # TODO: lift out to somewhere common with RemoteRepository
1251
 
        # <https://bugs.launchpad.net/bzr/+bug/401646>
1252
 
        if (self.has_same_location(source)
1253
 
            and fetch_spec is None
1254
 
            and self._has_same_fallbacks(source)):
1255
 
            # check that last_revision is in 'from' and then return a
1256
 
            # no-operation.
1257
 
            if (revision_id is not None and
1258
 
                not _mod_revision.is_null(revision_id)):
1259
 
                self.get_revision(revision_id)
1260
 
            return 0, []
1261
 
        inter = InterRepository.get(source, self)
1262
 
        if (fetch_spec is not None and
1263
 
            not getattr(inter, "supports_fetch_spec", False)):
1264
 
            raise errors.UnsupportedOperation(
1265
 
                "fetch_spec not supported for %r" % inter)
1266
 
        return inter.fetch(revision_id=revision_id,
1267
 
            find_ghosts=find_ghosts, fetch_spec=fetch_spec)
1268
 
 
1269
1222
    @needs_read_lock
1270
1223
    def gather_stats(self, revid=None, committers=None):
1271
1224
        """See Repository.gather_stats()."""
1280
1233
            # result['size'] = t
1281
1234
        return result
1282
1235
 
1283
 
    def get_commit_builder(self, branch, parents, config_stack, timestamp=None,
 
1236
    def get_commit_builder(self, branch, parents, config, timestamp=None,
1284
1237
                           timezone=None, committer=None, revprops=None,
1285
1238
                           revision_id=None, lossy=False):
1286
1239
        """Obtain a CommitBuilder for this repository.
1287
1240
 
1288
1241
        :param branch: Branch to commit to.
1289
1242
        :param parents: Revision ids of the parents of the new revision.
1290
 
        :param config_stack: Configuration stack to use.
 
1243
        :param config: Configuration to use.
1291
1244
        :param timestamp: Optional timestamp recorded for commit.
1292
1245
        :param timezone: Optional timezone for timestamp.
1293
1246
        :param committer: Optional committer to set for commit.
1300
1253
            raise errors.BzrError("Cannot commit directly to a stacked branch"
1301
1254
                " in pre-2a formats. See "
1302
1255
                "https://bugs.launchpad.net/bzr/+bug/375013 for details.")
1303
 
        result = self._commit_builder_class(self, parents, config_stack,
 
1256
        result = self._commit_builder_class(self, parents, config,
1304
1257
            timestamp, timezone, committer, revprops, revision_id,
1305
1258
            lossy)
1306
1259
        self.start_write_group()
1562
1515
            text_keys[(file_id, revision_id)] = callable_data
1563
1516
        for record in self.texts.get_record_stream(text_keys, 'unordered', True):
1564
1517
            if record.storage_kind == 'absent':
1565
 
                raise errors.RevisionNotPresent(record.key[1], record.key[0])
 
1518
                raise errors.RevisionNotPresent(record.key, self)
1566
1519
            yield text_keys[record.key], record.get_bytes_as('chunked')
1567
1520
 
1568
1521
    def _generate_text_key_index(self, text_key_references=None,
1746
1699
        if ((None in revision_ids)
1747
1700
            or (_mod_revision.NULL_REVISION in revision_ids)):
1748
1701
            raise ValueError('cannot get null revision inventory')
1749
 
        for inv, revid in self._iter_inventories(revision_ids, ordering):
1750
 
            if inv is None:
1751
 
                raise errors.NoSuchRevision(self, revid)
1752
 
            yield inv
 
1702
        return self._iter_inventories(revision_ids, ordering)
1753
1703
 
1754
1704
    def _iter_inventories(self, revision_ids, ordering):
1755
1705
        """single-document based inventory iteration."""
1756
1706
        inv_xmls = self._iter_inventory_xmls(revision_ids, ordering)
1757
1707
        for text, revision_id in inv_xmls:
1758
 
            if text is None:
1759
 
                yield None, revision_id
1760
 
            else:
1761
 
                yield self._deserialise_inventory(revision_id, text), revision_id
 
1708
            yield self._deserialise_inventory(revision_id, text)
1762
1709
 
1763
1710
    def _iter_inventory_xmls(self, revision_ids, ordering):
1764
1711
        if ordering is None:
1782
1729
                else:
1783
1730
                    yield ''.join(chunks), record.key[-1]
1784
1731
            else:
1785
 
                yield None, record.key[-1]
 
1732
                raise errors.NoSuchRevision(self, record.key)
1786
1733
            if order_as_requested:
1787
1734
                # Yield as many results as we can while preserving order.
1788
1735
                while next_key in text_chunks:
1817
1764
    def _get_inventory_xml(self, revision_id):
1818
1765
        """Get serialized inventory as a string."""
1819
1766
        texts = self._iter_inventory_xmls([revision_id], 'unordered')
1820
 
        text, revision_id = texts.next()
1821
 
        if text is None:
1822
 
            raise errors.NoSuchRevision(self, revision_id)
 
1767
        try:
 
1768
            text, revision_id = texts.next()
 
1769
        except StopIteration:
 
1770
            raise errors.HistoryMissing(self, 'inventory', revision_id)
1823
1771
        return text
1824
1772
 
1825
1773
    @needs_read_lock
1900
1848
        """Return the graph walker for text revisions."""
1901
1849
        return graph.Graph(self.texts)
1902
1850
 
1903
 
    def revision_ids_to_search_result(self, result_set):
1904
 
        """Convert a set of revision ids to a graph SearchResult."""
1905
 
        result_parents = set()
1906
 
        for parents in self.get_graph().get_parent_map(
1907
 
            result_set).itervalues():
1908
 
            result_parents.update(parents)
1909
 
        included_keys = result_set.intersection(result_parents)
1910
 
        start_keys = result_set.difference(included_keys)
1911
 
        exclude_keys = result_parents.difference(result_set)
1912
 
        result = vf_search.SearchResult(start_keys, exclude_keys,
1913
 
            len(result_set), result_set)
1914
 
        return result
1915
 
 
1916
1851
    def _get_versioned_file_checker(self, text_key_references=None,
1917
1852
        ancestors=None):
1918
1853
        """Return an object suitable for checking versioned files.
2003
1938
            control_files)
2004
1939
 
2005
1940
 
2006
 
class MetaDirVersionedFileRepositoryFormat(RepositoryFormatMetaDir,
 
1941
class MetaDirVersionedFileRepositoryFormat(MetaDirRepositoryFormat,
2007
1942
        VersionedFileRepositoryFormat):
2008
1943
    """Base class for repository formats using versioned files in metadirs."""
2009
1944
 
2554
2489
 
2555
2490
    _walk_to_common_revisions_batch_size = 50
2556
2491
 
2557
 
    supports_fetch_spec = True
2558
 
 
2559
2492
    @needs_write_lock
2560
2493
    def fetch(self, revision_id=None, find_ghosts=False,
2561
2494
            fetch_spec=None):
2637
2570
                searcher.stop_searching_any(stop_revs)
2638
2571
            if searcher_exhausted:
2639
2572
                break
2640
 
        (started_keys, excludes, included_keys) = searcher.get_state()
2641
 
        return vf_search.SearchResult(started_keys, excludes,
2642
 
            len(included_keys), included_keys)
 
2573
        return searcher.get_result()
2643
2574
 
2644
2575
    @needs_read_lock
2645
2576
    def search_missing_revision_ids(self,