/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 breezy/bzr/knitrepo.py

  • Committer: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2019-10-13 17:31:55 UTC
  • mfrom: (7397.4.9 remove-unused)
  • Revision ID: breezy.the.bot@gmail.com-20191013173155-yoiokny4mknxb3um
Remove Tree.has_id.

Merged from https://code.launchpad.net/~jelmer/brz/remove-unused/+merge/373320

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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
from bzrlib.lazy_import import lazy_import
 
17
from __future__ import absolute_import
 
18
 
 
19
from ..lazy_import import lazy_import
18
20
lazy_import(globals(), """
19
 
from bzrlib import (
20
 
    bzrdir,
 
21
import itertools
 
22
 
 
23
from breezy import (
 
24
    controldir,
21
25
    errors,
22
 
    knit as _mod_knit,
23
26
    lockable_files,
24
27
    lockdir,
25
28
    osutils,
26
29
    revision as _mod_revision,
27
30
    trace,
28
31
    transactions,
 
32
    )
 
33
from breezy.bzr import (
 
34
    knit as _mod_knit,
29
35
    versionedfile,
30
36
    xml5,
31
37
    xml6,
32
38
    xml7,
33
39
    )
34
40
""")
35
 
from bzrlib import (
36
 
    symbol_versioning,
37
 
    )
38
 
from bzrlib.decorators import needs_read_lock, needs_write_lock
39
 
from bzrlib.repository import (
40
 
    CommitBuilder,
41
 
    MetaDirRepository,
42
 
    MetaDirRepositoryFormat,
43
 
    RepositoryFormat,
44
 
    RootCommitBuilder,
 
41
from ..repository import (
 
42
    InterRepository,
 
43
    IsInWriteGroupError,
 
44
    )
 
45
from ..bzr.repository import (
 
46
    RepositoryFormatMetaDir,
 
47
    )
 
48
from ..bzr.vf_repository import (
 
49
    InterSameDataRepository,
 
50
    MetaDirVersionedFileRepository,
 
51
    MetaDirVersionedFileRepositoryFormat,
 
52
    VersionedFileCommitBuilder,
45
53
    )
46
54
 
47
55
 
102
110
        return result
103
111
 
104
112
 
105
 
class KnitRepository(MetaDirRepository):
 
113
class KnitRepository(MetaDirVersionedFileRepository):
106
114
    """Knit format repository."""
107
115
 
108
116
    # These attributes are inherited from the Repository base class. Setting
112
120
    _commit_builder_class = None
113
121
    _serializer = None
114
122
 
115
 
    def __init__(self, _format, a_bzrdir, control_files, _commit_builder_class,
116
 
        _serializer):
117
 
        MetaDirRepository.__init__(self, _format, a_bzrdir, control_files)
 
123
    def __init__(self, _format, a_controldir, control_files, _commit_builder_class,
 
124
                 _serializer):
 
125
        super(KnitRepository, self).__init__(
 
126
            _format, a_controldir, control_files)
118
127
        self._commit_builder_class = _commit_builder_class
119
128
        self._serializer = _serializer
120
129
        self._reconcile_fixes_text_parents = True
121
130
 
122
 
    @needs_read_lock
123
131
    def _all_revision_ids(self):
124
132
        """See Repository.all_revision_ids()."""
125
 
        return [key[0] for key in self.revisions.keys()]
 
133
        with self.lock_read():
 
134
            return [key[0] for key in self.revisions.keys()]
126
135
 
127
136
    def _activate_new_inventory(self):
128
137
        """Put a replacement inventory.new into use as inventories."""
169
178
 
170
179
    def _temp_inventories(self):
171
180
        result = self._format._get_inventories(self._transport, self,
172
 
            'inventory.new')
 
181
                                               'inventory.new')
173
182
        # Reconciling when the output has no revisions would result in no
174
183
        # writes - but we want to ensure there is an inventory for
175
184
        # compatibility with older clients that don't lazy-load.
176
 
        result.get_parent_map([('A',)])
 
185
        result.get_parent_map([(b'A',)])
177
186
        return result
178
187
 
179
 
    def fileid_involved_between_revs(self, from_revid, to_revid):
180
 
        """Find file_id(s) which are involved in the changes between revisions.
181
 
 
182
 
        This determines the set of revisions which are involved, and then
183
 
        finds all file ids affected by those revisions.
184
 
        """
185
 
        vf = self._get_revision_vf()
186
 
        from_set = set(vf.get_ancestry(from_revid))
187
 
        to_set = set(vf.get_ancestry(to_revid))
188
 
        changed = to_set.difference(from_set)
189
 
        return self._fileid_involved_by_set(changed)
190
 
 
191
 
    def fileid_involved(self, last_revid=None):
192
 
        """Find all file_ids modified in the ancestry of last_revid.
193
 
 
194
 
        :param last_revid: If None, last_revision() will be used.
195
 
        """
196
 
        if not last_revid:
197
 
            changed = set(self.all_revision_ids())
198
 
        else:
199
 
            changed = set(self.get_ancestry(last_revid))
200
 
        if None in changed:
201
 
            changed.remove(None)
202
 
        return self._fileid_involved_by_set(changed)
203
 
 
204
 
    @needs_read_lock
205
188
    def get_revision(self, revision_id):
206
189
        """Return the Revision object for a named revision"""
207
190
        revision_id = osutils.safe_revision_id(revision_id)
208
 
        return self.get_revision_reconcile(revision_id)
 
191
        with self.lock_read():
 
192
            return self.get_revision_reconcile(revision_id)
209
193
 
210
194
    def _refresh_data(self):
211
195
        if not self.is_locked():
212
196
            return
 
197
        if self.is_in_write_group():
 
198
            raise IsInWriteGroupError(self)
213
199
        # Create a new transaction to force all knits to see the scope change.
214
200
        # This is safe because we're outside a write group.
215
201
        self.control_files._finish_transaction()
218
204
        else:
219
205
            self.control_files._set_read_transaction()
220
206
 
221
 
    @needs_write_lock
222
207
    def reconcile(self, other=None, thorough=False):
223
208
        """Reconcile this repository."""
224
 
        from bzrlib.reconcile import KnitReconciler
225
 
        reconciler = KnitReconciler(self, thorough=thorough)
226
 
        reconciler.reconcile()
227
 
        return reconciler
 
209
        from .reconcile import KnitReconciler
 
210
        with self.lock_write():
 
211
            reconciler = KnitReconciler(self, thorough=thorough)
 
212
            return reconciler.reconcile()
228
213
 
229
214
    def _make_parents_provider(self):
230
215
        return _KnitsParentsProvider(self.revisions)
231
216
 
232
 
    def _find_inconsistent_revision_parents(self, revisions_iterator=None):
233
 
        """Find revisions with different parent lists in the revision object
234
 
        and in the index graph.
235
 
 
236
 
        :param revisions_iterator: None, or an iterator of (revid,
237
 
            Revision-or-None). This iterator controls the revisions checked.
238
 
        :returns: an iterator yielding tuples of (revison-id, parents-in-index,
239
 
            parents-in-revision).
240
 
        """
241
 
        if not self.is_locked():
242
 
            raise AssertionError()
243
 
        vf = self.revisions
244
 
        if revisions_iterator is None:
245
 
            revisions_iterator = self._iter_revisions(None)
246
 
        for revid, revision in revisions_iterator:
247
 
            if revision is None:
248
 
                pass
249
 
            parent_map = vf.get_parent_map([(revid,)])
250
 
            parents_according_to_index = tuple(parent[-1] for parent in
251
 
                parent_map[(revid,)])
252
 
            parents_according_to_revision = tuple(revision.parent_ids)
253
 
            if parents_according_to_index != parents_according_to_revision:
254
 
                yield (revid, parents_according_to_index,
255
 
                    parents_according_to_revision)
256
 
 
257
 
    def _check_for_inconsistent_revision_parents(self):
258
 
        inconsistencies = list(self._find_inconsistent_revision_parents())
259
 
        if inconsistencies:
260
 
            raise errors.BzrCheckError(
261
 
                "Revision knit has inconsistent parents.")
262
 
 
263
 
    def revision_graph_can_have_wrong_parents(self):
264
 
        # The revision.kndx could potentially claim a revision has a different
265
 
        # parent to the revision text.
266
 
        return True
267
 
 
268
 
 
269
 
class RepositoryFormatKnit(MetaDirRepositoryFormat):
 
217
 
 
218
class RepositoryFormatKnit(MetaDirVersionedFileRepositoryFormat):
270
219
    """Bzr repository knit format (generalized).
271
220
 
272
221
    This repository format has:
289
238
    _commit_builder_class = None
290
239
    # Set this attribute in derived clases to control the _serializer that the
291
240
    # repository objects will have passed to their constructor.
 
241
 
292
242
    @property
293
243
    def _serializer(self):
294
244
        return xml5.serializer_v5
301
251
    _fetch_order = 'topological'
302
252
    _fetch_uses_deltas = True
303
253
    fast_deltas = False
 
254
    supports_funky_characters = True
 
255
    # The revision.kndx could potentially claim a revision has a different
 
256
    # parent to the revision text.
 
257
    revision_graph_can_have_wrong_parents = True
304
258
 
305
259
    def _get_inventories(self, repo_transport, repo, name='inventory'):
306
260
        mapper = versionedfile.ConstantMapper(name)
307
261
        index = _mod_knit._KndxIndex(repo_transport, mapper,
308
 
            repo.get_transaction, repo.is_write_locked, repo.is_locked)
 
262
                                     repo.get_transaction, repo.is_write_locked, repo.is_locked)
309
263
        access = _mod_knit._KnitKeyAccess(repo_transport, mapper)
310
264
        return _mod_knit.KnitVersionedFiles(index, access, annotated=False)
311
265
 
312
266
    def _get_revisions(self, repo_transport, repo):
313
267
        mapper = versionedfile.ConstantMapper('revisions')
314
268
        index = _mod_knit._KndxIndex(repo_transport, mapper,
315
 
            repo.get_transaction, repo.is_write_locked, repo.is_locked)
 
269
                                     repo.get_transaction, repo.is_write_locked, repo.is_locked)
316
270
        access = _mod_knit._KnitKeyAccess(repo_transport, mapper)
317
271
        return _mod_knit.KnitVersionedFiles(index, access, max_delta_chain=0,
318
 
            annotated=False)
 
272
                                            annotated=False)
319
273
 
320
274
    def _get_signatures(self, repo_transport, repo):
321
275
        mapper = versionedfile.ConstantMapper('signatures')
322
276
        index = _mod_knit._KndxIndex(repo_transport, mapper,
323
 
            repo.get_transaction, repo.is_write_locked, repo.is_locked)
 
277
                                     repo.get_transaction, repo.is_write_locked, repo.is_locked)
324
278
        access = _mod_knit._KnitKeyAccess(repo_transport, mapper)
325
279
        return _mod_knit.KnitVersionedFiles(index, access, max_delta_chain=0,
326
 
            annotated=False)
 
280
                                            annotated=False)
327
281
 
328
282
    def _get_texts(self, repo_transport, repo):
329
283
        mapper = versionedfile.HashEscapedPrefixMapper()
330
284
        base_transport = repo_transport.clone('knits')
331
285
        index = _mod_knit._KndxIndex(base_transport, mapper,
332
 
            repo.get_transaction, repo.is_write_locked, repo.is_locked)
 
286
                                     repo.get_transaction, repo.is_write_locked, repo.is_locked)
333
287
        access = _mod_knit._KnitKeyAccess(base_transport, mapper)
334
288
        return _mod_knit.KnitVersionedFiles(index, access, max_delta_chain=200,
335
 
            annotated=True)
 
289
                                            annotated=True)
336
290
 
337
 
    def initialize(self, a_bzrdir, shared=False):
 
291
    def initialize(self, a_controldir, shared=False):
338
292
        """Create a knit format 1 repository.
339
293
 
340
 
        :param a_bzrdir: bzrdir to contain the new repository; must already
 
294
        :param a_controldir: bzrdir to contain the new repository; must already
341
295
            be initialized.
342
296
        :param shared: If true the repository will be initialized as a shared
343
297
                       repository.
344
298
        """
345
 
        trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
 
299
        trace.mutter('creating repository in %s.', a_controldir.transport.base)
346
300
        dirs = ['knits']
347
301
        files = []
348
302
        utf8_files = [('format', self.get_format_string())]
349
303
 
350
 
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
351
 
        repo_transport = a_bzrdir.get_repository_transport(None)
 
304
        self._upload_blank_content(
 
305
            a_controldir, dirs, files, utf8_files, shared)
 
306
        repo_transport = a_controldir.get_repository_transport(None)
352
307
        control_files = lockable_files.LockableFiles(repo_transport,
353
 
                                'lock', lockdir.LockDir)
 
308
                                                     'lock', lockdir.LockDir)
354
309
        transaction = transactions.WriteTransaction()
355
 
        result = self.open(a_bzrdir=a_bzrdir, _found=True)
 
310
        result = self.open(a_controldir=a_controldir, _found=True)
356
311
        result.lock_write()
357
312
        # the revision id here is irrelevant: it will not be stored, and cannot
358
313
        # already exist, we do this to create files on disk for older clients.
359
 
        result.inventories.get_parent_map([('A',)])
360
 
        result.revisions.get_parent_map([('A',)])
361
 
        result.signatures.get_parent_map([('A',)])
 
314
        result.inventories.get_parent_map([(b'A',)])
 
315
        result.revisions.get_parent_map([(b'A',)])
 
316
        result.signatures.get_parent_map([(b'A',)])
362
317
        result.unlock()
363
 
        self._run_post_repo_init_hooks(result, a_bzrdir, shared)
 
318
        self._run_post_repo_init_hooks(result, a_controldir, shared)
364
319
        return result
365
320
 
366
 
    def open(self, a_bzrdir, _found=False, _override_transport=None):
 
321
    def open(self, a_controldir, _found=False, _override_transport=None):
367
322
        """See RepositoryFormat.open().
368
323
 
369
324
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
371
326
                                    than normal. I.e. during 'upgrade'.
372
327
        """
373
328
        if not _found:
374
 
            format = RepositoryFormat.find_format(a_bzrdir)
 
329
            format = RepositoryFormatMetaDir.find_format(a_controldir)
375
330
        if _override_transport is not None:
376
331
            repo_transport = _override_transport
377
332
        else:
378
 
            repo_transport = a_bzrdir.get_repository_transport(None)
 
333
            repo_transport = a_controldir.get_repository_transport(None)
379
334
        control_files = lockable_files.LockableFiles(repo_transport,
380
 
                                'lock', lockdir.LockDir)
 
335
                                                     'lock', lockdir.LockDir)
381
336
        repo = self.repository_class(_format=self,
382
 
                              a_bzrdir=a_bzrdir,
383
 
                              control_files=control_files,
384
 
                              _commit_builder_class=self._commit_builder_class,
385
 
                              _serializer=self._serializer)
 
337
                                     a_controldir=a_controldir,
 
338
                                     control_files=control_files,
 
339
                                     _commit_builder_class=self._commit_builder_class,
 
340
                                     _serializer=self._serializer)
386
341
        repo.revisions = self._get_revisions(repo_transport, repo)
387
342
        repo.signatures = self._get_signatures(repo_transport, repo)
388
343
        repo.inventories = self._get_inventories(repo_transport, repo)
409
364
    """
410
365
 
411
366
    repository_class = KnitRepository
412
 
    _commit_builder_class = CommitBuilder
 
367
    _commit_builder_class = VersionedFileCommitBuilder
 
368
 
413
369
    @property
414
370
    def _serializer(self):
415
371
        return xml5.serializer_v5
417
373
    def __ne__(self, other):
418
374
        return self.__class__ is not other.__class__
419
375
 
420
 
    def get_format_string(self):
 
376
    @classmethod
 
377
    def get_format_string(cls):
421
378
        """See RepositoryFormat.get_format_string()."""
422
 
        return "Bazaar-NG Knit Repository Format 1"
 
379
        return b"Bazaar-NG Knit Repository Format 1"
423
380
 
424
381
    def get_format_description(self):
425
382
        """See RepositoryFormat.get_format_description()."""
443
400
    """
444
401
 
445
402
    repository_class = KnitRepository
446
 
    _commit_builder_class = RootCommitBuilder
 
403
    _commit_builder_class = VersionedFileCommitBuilder
447
404
    rich_root_data = True
448
405
    experimental = True
449
406
    supports_tree_reference = True
 
407
 
450
408
    @property
451
409
    def _serializer(self):
452
410
        return xml7.serializer_v7
453
411
 
454
412
    def _get_matching_bzrdir(self):
455
 
        return bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
 
413
        return controldir.format_registry.make_controldir('dirstate-with-subtree')
456
414
 
457
415
    def _ignore_setting_bzrdir(self, format):
458
416
        pass
459
417
 
460
 
    _matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
 
418
    _matchingcontroldir = property(
 
419
        _get_matching_bzrdir, _ignore_setting_bzrdir)
461
420
 
462
 
    def get_format_string(self):
 
421
    @classmethod
 
422
    def get_format_string(cls):
463
423
        """See RepositoryFormat.get_format_string()."""
464
 
        return "Bazaar Knit Repository Format 3 (bzr 0.15)\n"
 
424
        return b"Bazaar Knit Repository Format 3 (bzr 0.15)\n"
465
425
 
466
426
    def get_format_description(self):
467
427
        """See RepositoryFormat.get_format_description()."""
485
445
    """
486
446
 
487
447
    repository_class = KnitRepository
488
 
    _commit_builder_class = RootCommitBuilder
 
448
    _commit_builder_class = VersionedFileCommitBuilder
489
449
    rich_root_data = True
490
450
    supports_tree_reference = False
 
451
 
491
452
    @property
492
453
    def _serializer(self):
493
454
        return xml6.serializer_v6
494
455
 
495
456
    def _get_matching_bzrdir(self):
496
 
        return bzrdir.format_registry.make_bzrdir('rich-root')
 
457
        return controldir.format_registry.make_controldir('rich-root')
497
458
 
498
459
    def _ignore_setting_bzrdir(self, format):
499
460
        pass
500
461
 
501
 
    _matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
 
462
    _matchingcontroldir = property(
 
463
        _get_matching_bzrdir, _ignore_setting_bzrdir)
502
464
 
503
 
    def get_format_string(self):
 
465
    @classmethod
 
466
    def get_format_string(cls):
504
467
        """See RepositoryFormat.get_format_string()."""
505
 
        return 'Bazaar Knit Repository Format 4 (bzr 1.0)\n'
 
468
        return b'Bazaar Knit Repository Format 4 (bzr 1.0)\n'
506
469
 
507
470
    def get_format_description(self):
508
471
        """See RepositoryFormat.get_format_description()."""
509
472
        return "Knit repository format 4"
 
473
 
 
474
 
 
475
class InterKnitRepo(InterSameDataRepository):
 
476
    """Optimised code paths between Knit based repositories."""
 
477
 
 
478
    @classmethod
 
479
    def _get_repo_format_to_test(self):
 
480
        return RepositoryFormatKnit1()
 
481
 
 
482
    @staticmethod
 
483
    def is_compatible(source, target):
 
484
        """Be compatible with known Knit formats.
 
485
 
 
486
        We don't test for the stores being of specific types because that
 
487
        could lead to confusing results, and there is no need to be
 
488
        overly general.
 
489
        """
 
490
        try:
 
491
            are_knits = (isinstance(source._format, RepositoryFormatKnit)
 
492
                         and isinstance(target._format, RepositoryFormatKnit))
 
493
        except AttributeError:
 
494
            return False
 
495
        return are_knits and InterRepository._same_model(source, target)
 
496
 
 
497
    def search_missing_revision_ids(self,
 
498
                                    find_ghosts=True, revision_ids=None, if_present_ids=None,
 
499
                                    limit=None):
 
500
        """See InterRepository.search_missing_revision_ids()."""
 
501
        with self.lock_read():
 
502
            source_ids_set = self._present_source_revisions_for(
 
503
                revision_ids, if_present_ids)
 
504
            # source_ids is the worst possible case we may need to pull.
 
505
            # now we want to filter source_ids against what we actually
 
506
            # have in target, but don't try to check for existence where we know
 
507
            # we do not have a revision as that would be pointless.
 
508
            target_ids = set(self.target.all_revision_ids())
 
509
            possibly_present_revisions = target_ids.intersection(
 
510
                source_ids_set)
 
511
            actually_present_revisions = set(
 
512
                self.target._eliminate_revisions_not_present(possibly_present_revisions))
 
513
            required_revisions = source_ids_set.difference(
 
514
                actually_present_revisions)
 
515
            if revision_ids is not None:
 
516
                # we used get_ancestry to determine source_ids then we are assured all
 
517
                # revisions referenced are present as they are installed in topological order.
 
518
                # and the tip revision was validated by get_ancestry.
 
519
                result_set = required_revisions
 
520
            else:
 
521
                # if we just grabbed the possibly available ids, then
 
522
                # we only have an estimate of whats available and need to validate
 
523
                # that against the revision records.
 
524
                result_set = set(
 
525
                    self.source._eliminate_revisions_not_present(required_revisions))
 
526
            if limit is not None:
 
527
                topo_ordered = self.source.get_graph().iter_topo_order(result_set)
 
528
                result_set = set(itertools.islice(topo_ordered, limit))
 
529
            return self.source.revision_ids_to_search_result(result_set)
 
530
 
 
531
 
 
532
InterRepository.register_optimiser(InterKnitRepo)