/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/knitrepo.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
from bzrlib.lazy_import import lazy_import
 
18
lazy_import(globals(), """
 
19
from bzrlib import (
 
20
    debug,
 
21
    )
 
22
from bzrlib.store import revision
 
23
from bzrlib.store.revision.knit import KnitRevisionStore
 
24
""")
17
25
from bzrlib import (
18
26
    bzrdir,
19
27
    deprecated_graph,
29
37
 
30
38
from bzrlib.decorators import needs_read_lock, needs_write_lock
31
39
from bzrlib.repository import (
 
40
    CommitBuilder,
32
41
    MetaDirRepository,
33
42
    MetaDirRepositoryFormat,
34
43
    RepositoryFormat,
36
45
    )
37
46
import bzrlib.revision as _mod_revision
38
47
from bzrlib.store.versioned import VersionedFileStore
39
 
from bzrlib.trace import mutter, note, warning
 
48
from bzrlib.trace import mutter, mutter_callsite
40
49
from bzrlib.util import bencode
41
50
 
42
51
 
68
77
class KnitRepository(MetaDirRepository):
69
78
    """Knit format repository."""
70
79
 
71
 
    _serializer = xml5.serializer_v5
 
80
    # These attributes are inherited from the Repository base class. Setting
 
81
    # them to None ensures that if the constructor is changed to not initialize
 
82
    # them, or a subclass fails to call the constructor, that an error will
 
83
    # occur rather than the system working but generating incorrect data.
 
84
    _commit_builder_class = None
 
85
    _serializer = None
 
86
 
 
87
    def __init__(self, _format, a_bzrdir, control_files, _revision_store,
 
88
        control_store, text_store, _commit_builder_class, _serializer):
 
89
        MetaDirRepository.__init__(self, _format, a_bzrdir, control_files,
 
90
            _revision_store, control_store, text_store)
 
91
        self._commit_builder_class = _commit_builder_class
 
92
        self._serializer = _serializer
 
93
        self._reconcile_fixes_text_parents = True
72
94
 
73
95
    def _warn_if_deprecated(self):
74
96
        # This class isn't deprecated
75
97
        pass
76
98
 
77
 
    def _inventory_add_lines(self, inv_vf, revid, parents, lines):
78
 
        inv_vf.add_lines_with_ghosts(revid, parents, lines)
 
99
    def _inventory_add_lines(self, inv_vf, revid, parents, lines, check_content):
 
100
        return inv_vf.add_lines_with_ghosts(revid, parents, lines,
 
101
            check_content=check_content)[0]
79
102
 
80
103
    @needs_read_lock
81
104
    def _all_revision_ids(self):
90
113
        This determines the set of revisions which are involved, and then
91
114
        finds all file ids affected by those revisions.
92
115
        """
93
 
        from_revid = osutils.safe_revision_id(from_revid)
94
 
        to_revid = osutils.safe_revision_id(to_revid)
95
116
        vf = self._get_revision_vf()
96
117
        from_set = set(vf.get_ancestry(from_revid))
97
118
        to_set = set(vf.get_ancestry(to_revid))
120
141
        """
121
142
        if _mod_revision.is_null(revision_id):
122
143
            return [None]
123
 
        revision_id = osutils.safe_revision_id(revision_id)
124
144
        vf = self._get_revision_vf()
125
145
        try:
126
146
            return [None] + vf.get_ancestry(revision_id, topo_sorted)
128
148
            raise errors.NoSuchRevision(self, revision_id)
129
149
 
130
150
    @needs_read_lock
 
151
    def get_data_stream(self, revision_ids):
 
152
        """See Repository.get_data_stream."""
 
153
        item_keys = self.item_keys_introduced_by(revision_ids)
 
154
        for knit_kind, file_id, versions in item_keys:
 
155
            name = (knit_kind,)
 
156
            if knit_kind == 'file':
 
157
                name = ('file', file_id)
 
158
                knit = self.weave_store.get_weave_or_empty(
 
159
                    file_id, self.get_transaction())
 
160
            elif knit_kind == 'inventory':
 
161
                knit = self.get_inventory_weave()
 
162
            elif knit_kind == 'revisions':
 
163
                knit = self._revision_store.get_revision_file(
 
164
                    self.get_transaction())
 
165
            elif knit_kind == 'signatures':
 
166
                knit = self._revision_store.get_signature_file(
 
167
                    self.get_transaction())
 
168
            else:
 
169
                raise AssertionError('Unknown knit kind %r' % (knit_kind,))
 
170
            yield name, _get_stream_as_bytes(knit, versions)
 
171
 
 
172
    @needs_read_lock
131
173
    def get_revision(self, revision_id):
132
174
        """Return the Revision object for a named revision"""
133
175
        revision_id = osutils.safe_revision_id(revision_id)
142
184
        operation and will be removed in the future.
143
185
        :return: a dictionary of revision_id->revision_parents_list.
144
186
        """
 
187
        if 'evil' in debug.debug_flags:
 
188
            mutter_callsite(3,
 
189
                "get_revision_graph scales with size of history.")
145
190
        # special case NULL_REVISION
146
191
        if revision_id == _mod_revision.NULL_REVISION:
147
192
            return {}
148
 
        revision_id = osutils.safe_revision_id(revision_id)
149
193
        a_weave = self._get_revision_vf()
150
194
        if revision_id is None:
151
195
            return a_weave.get_graph()
152
 
        elif revision_id not in a_weave:
 
196
        if revision_id not in a_weave:
153
197
            raise errors.NoSuchRevision(self, revision_id)
154
198
        else:
155
199
            # add what can be reached from revision_id
162
206
        :param revision_ids: an iterable of revisions to graph or None for all.
163
207
        :return: a Graph object with the graph reachable from revision_ids.
164
208
        """
 
209
        if 'evil' in debug.debug_flags:
 
210
            mutter_callsite(3,
 
211
                "get_revision_graph_with_ghosts scales with size of history.")
165
212
        result = deprecated_graph.Graph()
166
213
        vf = self._get_revision_vf()
167
214
        versions = set(vf.versions())
169
216
            pending = set(self.all_revision_ids())
170
217
            required = set([])
171
218
        else:
172
 
            pending = set(osutils.safe_revision_id(r) for r in revision_ids)
 
219
            pending = set(revision_ids)
173
220
            # special case NULL_REVISION
174
221
            if _mod_revision.NULL_REVISION in pending:
175
222
                pending.remove(_mod_revision.NULL_REVISION)
217
264
        return reconciler
218
265
    
219
266
    def revision_parents(self, revision_id):
220
 
        revision_id = osutils.safe_revision_id(revision_id)
221
267
        return self._get_revision_vf().get_parents(revision_id)
222
268
 
223
269
    def _make_parents_provider(self):
224
270
        return _KnitParentsProvider(self._get_revision_vf())
225
271
 
226
 
 
227
 
class KnitRepository3(KnitRepository):
228
 
 
229
 
    def __init__(self, _format, a_bzrdir, control_files, _revision_store,
230
 
                 control_store, text_store):
231
 
        KnitRepository.__init__(self, _format, a_bzrdir, control_files,
232
 
                              _revision_store, control_store, text_store)
233
 
        self._serializer = xml7.serializer_v7
234
 
 
235
 
    def deserialise_inventory(self, revision_id, xml):
236
 
        """Transform the xml into an inventory object. 
237
 
 
238
 
        :param revision_id: The expected revision id of the inventory.
239
 
        :param xml: A serialised inventory.
240
 
        """
241
 
        result = self._serializer.read_inventory_from_string(xml)
242
 
        assert result.root.revision is not None
243
 
        return result
244
 
 
245
 
    def serialise_inventory(self, inv):
246
 
        """Transform the inventory object into XML text.
247
 
 
248
 
        :param revision_id: The expected revision id of the inventory.
249
 
        :param xml: A serialised inventory.
250
 
        """
251
 
        assert inv.revision_id is not None
252
 
        assert inv.root.revision is not None
253
 
        return KnitRepository.serialise_inventory(self, inv)
254
 
 
255
 
    def get_commit_builder(self, branch, parents, config, timestamp=None,
256
 
                           timezone=None, committer=None, revprops=None,
257
 
                           revision_id=None):
258
 
        """Obtain a CommitBuilder for this repository.
259
 
        
260
 
        :param branch: Branch to commit to.
261
 
        :param parents: Revision ids of the parents of the new revision.
262
 
        :param config: Configuration to use.
263
 
        :param timestamp: Optional timestamp recorded for commit.
264
 
        :param timezone: Optional timezone for timestamp.
265
 
        :param committer: Optional committer to set for commit.
266
 
        :param revprops: Optional dictionary of revision properties.
267
 
        :param revision_id: Optional revision id.
268
 
        """
269
 
        revision_id = osutils.safe_revision_id(revision_id)
270
 
        result = RootCommitBuilder(self, parents, config, timestamp, timezone,
271
 
                                 committer, revprops, revision_id)
272
 
        self.start_write_group()
273
 
        return result
 
272
    def _find_inconsistent_revision_parents(self):
 
273
        """Find revisions with different parent lists in the revision object
 
274
        and in the index graph.
 
275
 
 
276
        :returns: an iterator yielding tuples of (revison-id, parents-in-index,
 
277
            parents-in-revision).
 
278
        """
 
279
        vf = self._get_revision_vf()
 
280
        index_versions = vf.versions()
 
281
        for index_version in index_versions:
 
282
            parents_according_to_index = vf._index.get_parents_with_ghosts(
 
283
                index_version)
 
284
            revision = self._revision_store.get_revision(index_version,
 
285
                self.get_transaction())
 
286
            parents_according_to_revision = revision.parent_ids
 
287
            if parents_according_to_index != parents_according_to_revision:
 
288
                yield (index_version, parents_according_to_index,
 
289
                    parents_according_to_revision)
 
290
 
 
291
    def _check_for_inconsistent_revision_parents(self):
 
292
        inconsistencies = list(self._find_inconsistent_revision_parents())
 
293
        if inconsistencies:
 
294
            raise errors.BzrCheckError(
 
295
                "Revision knit has inconsistent parents.")
 
296
 
 
297
    def revision_graph_can_have_wrong_parents(self):
 
298
        # The revision.kndx could potentially claim a revision has a different
 
299
        # parent to the revision text.
 
300
        return True
274
301
 
275
302
 
276
303
class RepositoryFormatKnit(MetaDirRepositoryFormat):
287
314
     - a LockDir lock
288
315
    """
289
316
 
 
317
    # Set this attribute in derived classes to control the repository class
 
318
    # created by open and initialize.
 
319
    repository_class = None
 
320
    # Set this attribute in derived classes to control the
 
321
    # _commit_builder_class that the repository objects will have passed to
 
322
    # their constructor.
 
323
    _commit_builder_class = None
 
324
    # Set this attribute in derived clases to control the _serializer that the
 
325
    # repository objects will have passed to their constructor.
 
326
    _serializer = xml5.serializer_v5
 
327
 
290
328
    def _get_control_store(self, repo_transport, control_files):
291
329
        """Return the control store for this repository."""
292
330
        return VersionedFileStore(
299
337
 
300
338
    def _get_revision_store(self, repo_transport, control_files):
301
339
        """See RepositoryFormat._get_revision_store()."""
302
 
        from bzrlib.store.revision.knit import KnitRevisionStore
303
340
        versioned_file_store = VersionedFileStore(
304
341
            repo_transport,
305
342
            file_mode=control_files._file_mode,
335
372
                       repository.
336
373
        """
337
374
        mutter('creating repository in %s.', a_bzrdir.transport.base)
338
 
        dirs = ['revision-store', 'knits']
 
375
        dirs = ['knits']
339
376
        files = []
340
377
        utf8_files = [('format', self.get_format_string())]
341
378
        
373
410
        text_store = self._get_text_store(repo_transport, control_files)
374
411
        control_store = self._get_control_store(repo_transport, control_files)
375
412
        _revision_store = self._get_revision_store(repo_transport, control_files)
376
 
        return KnitRepository(_format=self,
 
413
        return self.repository_class(_format=self,
377
414
                              a_bzrdir=a_bzrdir,
378
415
                              control_files=control_files,
379
416
                              _revision_store=_revision_store,
380
417
                              control_store=control_store,
381
 
                              text_store=text_store)
 
418
                              text_store=text_store,
 
419
                              _commit_builder_class=self._commit_builder_class,
 
420
                              _serializer=self._serializer)
382
421
 
383
422
 
384
423
class RepositoryFormatKnit1(RepositoryFormatKnit):
397
436
    This format was introduced in bzr 0.8.
398
437
    """
399
438
 
 
439
    repository_class = KnitRepository
 
440
    _commit_builder_class = CommitBuilder
 
441
    _serializer = xml5.serializer_v5
 
442
 
400
443
    def __ne__(self, other):
401
444
        return self.__class__ is not other.__class__
402
445
 
428
471
     - support for recording tree-references
429
472
    """
430
473
 
431
 
    repository_class = KnitRepository3
 
474
    repository_class = KnitRepository
 
475
    _commit_builder_class = RootCommitBuilder
432
476
    rich_root_data = True
433
477
    supports_tree_reference = True
 
478
    _serializer = xml7.serializer_v7
434
479
 
435
480
    def _get_matching_bzrdir(self):
436
481
        return bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
456
501
        """See RepositoryFormat.get_format_description()."""
457
502
        return "Knit repository format 3"
458
503
 
459
 
    def open(self, a_bzrdir, _found=False, _override_transport=None):
460
 
        """See RepositoryFormat.open().
461
 
        
462
 
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
463
 
                                    repository at a slightly different url
464
 
                                    than normal. I.e. during 'upgrade'.
465
 
        """
466
 
        if not _found:
467
 
            format = RepositoryFormat.find_format(a_bzrdir)
468
 
            assert format.__class__ ==  self.__class__
469
 
        if _override_transport is not None:
470
 
            repo_transport = _override_transport
471
 
        else:
472
 
            repo_transport = a_bzrdir.get_repository_transport(None)
473
 
        control_files = lockable_files.LockableFiles(repo_transport, 'lock',
474
 
                                                     lockdir.LockDir)
475
 
        text_store = self._get_text_store(repo_transport, control_files)
476
 
        control_store = self._get_control_store(repo_transport, control_files)
477
 
        _revision_store = self._get_revision_store(repo_transport, control_files)
478
 
        return self.repository_class(_format=self,
479
 
                                     a_bzrdir=a_bzrdir,
480
 
                                     control_files=control_files,
481
 
                                     _revision_store=_revision_store,
482
 
                                     control_store=control_store,
483
 
                                     text_store=text_store)
484
 
 
485
504
 
486
505
def _get_stream_as_bytes(knit, required_versions):
487
506
    """Generate a serialised data stream.
504
523
    for version, options, length, parents in data_list:
505
524
        data.append([version, options, parents, callable(length)])
506
525
    return bencode.bencode(data)
507