/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/weaverepo.py

Merge bzr.dev.

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
"""Deprecated weave-based repository formats.
17
18
 
18
 
"""Old weave-based repository formats"""
 
19
Weave based formats scaled linearly with history size and could not represent
 
20
ghosts.
 
21
"""
19
22
 
20
23
from StringIO import StringIO
21
24
 
22
25
from bzrlib import (
23
26
    bzrdir,
 
27
    debug,
 
28
    errors,
24
29
    lockable_files,
25
30
    lockdir,
 
31
    osutils,
 
32
    revision as _mod_revision,
26
33
    weave,
27
34
    weavefile,
28
35
    xml5,
29
36
    )
30
37
from bzrlib.decorators import needs_read_lock, needs_write_lock
31
38
from bzrlib.repository import (
 
39
    CommitBuilder,
32
40
    MetaDirRepository,
33
41
    MetaDirRepositoryFormat,
34
42
    Repository,
69
77
            text_store = get_store('text-store')
70
78
        super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files, _revision_store, control_store, text_store)
71
79
 
 
80
    @needs_read_lock
 
81
    def _all_possible_ids(self):
 
82
        """Return all the possible revisions that we could find."""
 
83
        if 'evil' in debug.debug_flags:
 
84
            mutter_callsite(3, "_all_possible_ids scales with size of history.")
 
85
        return self.get_inventory_weave().versions()
 
86
 
 
87
    @needs_read_lock
 
88
    def _all_revision_ids(self):
 
89
        """Returns a list of all the revision ids in the repository. 
 
90
 
 
91
        These are in as much topological order as the underlying store can 
 
92
        present: for weaves ghosts may lead to a lack of correctness until
 
93
        the reweave updates the parents list.
 
94
        """
 
95
        if self._revision_store.text_store.listable():
 
96
            return self._revision_store.all_revision_ids(self.get_transaction())
 
97
        result = self._all_possible_ids()
 
98
        # TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
 
99
        #       ids. (It should, since _revision_store's API should change to
 
100
        #       return utf8 revision_ids)
 
101
        return self._eliminate_revisions_not_present(result)
 
102
 
 
103
    def _check_revision_parents(self, revision, inventory):
 
104
        """Private to Repository and Fetch.
 
105
        
 
106
        This checks the parentage of revision in an inventory weave for 
 
107
        consistency and is only applicable to inventory-weave-for-ancestry
 
108
        using repository formats & fetchers.
 
109
        """
 
110
        weave_parents = inventory.get_parents(revision.revision_id)
 
111
        weave_names = inventory.versions()
 
112
        for parent_id in revision.parent_ids:
 
113
            if parent_id in weave_names:
 
114
                # this parent must not be a ghost.
 
115
                if not parent_id in weave_parents:
 
116
                    # but it is a ghost
 
117
                    raise errors.CorruptRepository(self)
 
118
 
72
119
    def get_commit_builder(self, branch, parents, config, timestamp=None,
73
120
                           timezone=None, committer=None, revprops=None,
74
121
                           revision_id=None):
75
122
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
76
 
        return Repository.get_commit_builder(self, branch, parents, config,
77
 
            timestamp, timezone, committer, revprops, revision_id)
 
123
        result = WeaveCommitBuilder(self, parents, config, timestamp, timezone,
 
124
                              committer, revprops, revision_id)
 
125
        self.start_write_group()
 
126
        return result
 
127
 
 
128
    @needs_read_lock
 
129
    def get_revisions(self, revision_ids):
 
130
        revs = self._get_revisions(revision_ids)
 
131
        # weave corruption can lead to absent revision markers that should be
 
132
        # present.
 
133
        # the following test is reasonably cheap (it needs a single weave read)
 
134
        # and the weave is cached in read transactions. In write transactions
 
135
        # it is not cached but typically we only read a small number of
 
136
        # revisions. For knits when they are introduced we will probably want
 
137
        # to ensure that caching write transactions are in use.
 
138
        inv = self.get_inventory_weave()
 
139
        for rev in revs:
 
140
            self._check_revision_parents(rev, inv)
 
141
        return revs
 
142
 
 
143
    @needs_read_lock
 
144
    def get_revision_graph(self, revision_id=None):
 
145
        """Return a dictionary containing the revision graph.
 
146
        
 
147
        :param revision_id: The revision_id to get a graph from. If None, then
 
148
        the entire revision graph is returned. This is a deprecated mode of
 
149
        operation and will be removed in the future.
 
150
        :return: a dictionary of revision_id->revision_parents_list.
 
151
        """
 
152
        if 'evil' in debug.debug_flags:
 
153
            mutter_callsite(2,
 
154
                "get_revision_graph scales with size of history.")
 
155
        # special case NULL_REVISION
 
156
        if revision_id == _mod_revision.NULL_REVISION:
 
157
            return {}
 
158
        a_weave = self.get_inventory_weave()
 
159
        all_revisions = self._eliminate_revisions_not_present(
 
160
                                a_weave.versions())
 
161
        entire_graph = dict([(node, tuple(a_weave.get_parents(node))) for 
 
162
                             node in all_revisions])
 
163
        if revision_id is None:
 
164
            return entire_graph
 
165
        elif revision_id not in entire_graph:
 
166
            raise errors.NoSuchRevision(self, revision_id)
 
167
        else:
 
168
            # add what can be reached from revision_id
 
169
            result = {}
 
170
            pending = set([revision_id])
 
171
            while len(pending) > 0:
 
172
                node = pending.pop()
 
173
                result[node] = entire_graph[node]
 
174
                for revision_id in result[node]:
 
175
                    if revision_id not in result:
 
176
                        pending.add(revision_id)
 
177
            return result
78
178
 
79
179
    @needs_read_lock
80
180
    def is_shared(self):
97
197
        """Returns the policy for making working trees on new branches."""
98
198
        return True
99
199
 
 
200
    def revision_graph_can_have_wrong_parents(self):
 
201
        # XXX: This is an old format that we don't support full checking on, so
 
202
        # just claim that checking for this inconsistency is not required.
 
203
        return False
 
204
 
100
205
 
101
206
class WeaveMetaDirRepository(MetaDirRepository):
102
207
    """A subclass of MetaDirRepository to set weave specific policy."""
103
208
 
104
209
    _serializer = xml5.serializer_v5
105
210
 
 
211
    @needs_read_lock
 
212
    def _all_possible_ids(self):
 
213
        """Return all the possible revisions that we could find."""
 
214
        if 'evil' in debug.debug_flags:
 
215
            mutter_callsite(3, "_all_possible_ids scales with size of history.")
 
216
        return self.get_inventory_weave().versions()
 
217
 
 
218
    @needs_read_lock
 
219
    def _all_revision_ids(self):
 
220
        """Returns a list of all the revision ids in the repository. 
 
221
 
 
222
        These are in as much topological order as the underlying store can 
 
223
        present: for weaves ghosts may lead to a lack of correctness until
 
224
        the reweave updates the parents list.
 
225
        """
 
226
        if self._revision_store.text_store.listable():
 
227
            return self._revision_store.all_revision_ids(self.get_transaction())
 
228
        result = self._all_possible_ids()
 
229
        # TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
 
230
        #       ids. (It should, since _revision_store's API should change to
 
231
        #       return utf8 revision_ids)
 
232
        return self._eliminate_revisions_not_present(result)
 
233
 
 
234
    def _check_revision_parents(self, revision, inventory):
 
235
        """Private to Repository and Fetch.
 
236
        
 
237
        This checks the parentage of revision in an inventory weave for 
 
238
        consistency and is only applicable to inventory-weave-for-ancestry
 
239
        using repository formats & fetchers.
 
240
        """
 
241
        weave_parents = inventory.get_parents(revision.revision_id)
 
242
        weave_names = inventory.versions()
 
243
        for parent_id in revision.parent_ids:
 
244
            if parent_id in weave_names:
 
245
                # this parent must not be a ghost.
 
246
                if not parent_id in weave_parents:
 
247
                    # but it is a ghost
 
248
                    raise errors.CorruptRepository(self)
 
249
 
106
250
    def get_commit_builder(self, branch, parents, config, timestamp=None,
107
251
                           timezone=None, committer=None, revprops=None,
108
252
                           revision_id=None):
109
253
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
110
 
        return MetaDirRepository.get_commit_builder(self, branch, parents,
111
 
            config, timestamp, timezone, committer, revprops, revision_id)
 
254
        result = WeaveCommitBuilder(self, parents, config, timestamp, timezone,
 
255
                              committer, revprops, revision_id)
 
256
        self.start_write_group()
 
257
        return result
 
258
 
 
259
    @needs_read_lock
 
260
    def get_revision(self, revision_id):
 
261
        """Return the Revision object for a named revision"""
 
262
        # TODO: jam 20070210 get_revision_reconcile should do this for us
 
263
        r = self.get_revision_reconcile(revision_id)
 
264
        # weave corruption can lead to absent revision markers that should be
 
265
        # present.
 
266
        # the following test is reasonably cheap (it needs a single weave read)
 
267
        # and the weave is cached in read transactions. In write transactions
 
268
        # it is not cached but typically we only read a small number of
 
269
        # revisions. For knits when they are introduced we will probably want
 
270
        # to ensure that caching write transactions are in use.
 
271
        inv = self.get_inventory_weave()
 
272
        self._check_revision_parents(r, inv)
 
273
        return r
 
274
 
 
275
    @needs_read_lock
 
276
    def get_revision_graph(self, revision_id=None):
 
277
        """Return a dictionary containing the revision graph.
 
278
        
 
279
        :param revision_id: The revision_id to get a graph from. If None, then
 
280
        the entire revision graph is returned. This is a deprecated mode of
 
281
        operation and will be removed in the future.
 
282
        :return: a dictionary of revision_id->revision_parents_list.
 
283
        """
 
284
        if 'evil' in debug.debug_flags:
 
285
            mutter_callsite(3,
 
286
                "get_revision_graph scales with size of history.")
 
287
        # special case NULL_REVISION
 
288
        if revision_id == _mod_revision.NULL_REVISION:
 
289
            return {}
 
290
        a_weave = self.get_inventory_weave()
 
291
        all_revisions = self._eliminate_revisions_not_present(
 
292
                                a_weave.versions())
 
293
        entire_graph = dict([(node, tuple(a_weave.get_parents(node))) for 
 
294
                             node in all_revisions])
 
295
        if revision_id is None:
 
296
            return entire_graph
 
297
        elif revision_id not in entire_graph:
 
298
            raise errors.NoSuchRevision(self, revision_id)
 
299
        else:
 
300
            # add what can be reached from revision_id
 
301
            result = {}
 
302
            pending = set([revision_id])
 
303
            while len(pending) > 0:
 
304
                node = pending.pop()
 
305
                result[node] = entire_graph[node]
 
306
                for revision_id in result[node]:
 
307
                    if revision_id not in result:
 
308
                        pending.add(revision_id)
 
309
            return result
 
310
 
 
311
    def revision_graph_can_have_wrong_parents(self):
 
312
        # XXX: This is an old format that we don't support full checking on, so
 
313
        # just claim that checking for this inconsistency is not required.
 
314
        return False
112
315
 
113
316
 
114
317
class PreSplitOutRepositoryFormat(RepositoryFormat):
303
506
        """See RepositoryFormat._get_text_store()."""
304
507
        return self._get_versioned_file_store('weaves', transport, control_files)
305
508
 
306
 
 
307
509
class RepositoryFormat7(MetaDirRepositoryFormat):
308
510
    """Bzr repository 7.
309
511
 
398
600
            text_store=text_store)
399
601
 
400
602
 
 
603
class WeaveCommitBuilder(CommitBuilder):
 
604
    """A builder for weave based repos that don't support ghosts."""
 
605
 
 
606
    def _add_text_to_weave(self, file_id, new_lines, parents, nostore_sha):
 
607
        versionedfile = self.repository.weave_store.get_weave_or_empty(
 
608
            file_id, self.repository.get_transaction())
 
609
        result = versionedfile.add_lines(
 
610
            self._new_revision_id, parents, new_lines,
 
611
            nostore_sha=nostore_sha)[0:2]
 
612
        versionedfile.clear_cache()
 
613
        return result
 
614
 
 
615
 
401
616
_legacy_formats = [RepositoryFormat4(),
402
617
                   RepositoryFormat5(),
403
618
                   RepositoryFormat6()]