/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: Jelmer Vernooij
  • Date: 2017-10-27 00:18:42 UTC
  • mto: This revision was merged to the branch mainline in revision 6799.
  • Revision ID: jelmer@jelmer.uk-20171027001842-o77sekj0g2t2zwbn
Properly escape backslashes.

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,
 
53
    VersionedFileRootCommitBuilder,
45
54
    )
46
55
 
47
56
 
102
111
        return result
103
112
 
104
113
 
105
 
class KnitRepository(MetaDirRepository):
 
114
class KnitRepository(MetaDirVersionedFileRepository):
106
115
    """Knit format repository."""
107
116
 
108
117
    # These attributes are inherited from the Repository base class. Setting
112
121
    _commit_builder_class = None
113
122
    _serializer = None
114
123
 
115
 
    def __init__(self, _format, a_bzrdir, control_files, _commit_builder_class,
 
124
    def __init__(self, _format, a_controldir, control_files, _commit_builder_class,
116
125
        _serializer):
117
 
        MetaDirRepository.__init__(self, _format, a_bzrdir, control_files)
 
126
        super(KnitRepository, self).__init__(_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."""
176
185
        result.get_parent_map([('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 breezy.reconcile import KnitReconciler
 
210
        with self.lock_write():
 
211
            reconciler = KnitReconciler(self, thorough=thorough)
 
212
            reconciler.reconcile()
 
213
            return reconciler
228
214
 
229
215
    def _make_parents_provider(self):
230
216
        return _KnitsParentsProvider(self.revisions)
231
217
 
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):
 
218
 
 
219
class RepositoryFormatKnit(MetaDirVersionedFileRepositoryFormat):
270
220
    """Bzr repository knit format (generalized).
271
221
 
272
222
    This repository format has:
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)
334
288
        return _mod_knit.KnitVersionedFiles(index, access, max_delta_chain=200,
335
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(a_controldir, dirs, files, utf8_files, shared)
 
305
        repo_transport = a_controldir.get_repository_transport(None)
352
306
        control_files = lockable_files.LockableFiles(repo_transport,
353
307
                                'lock', lockdir.LockDir)
354
308
        transaction = transactions.WriteTransaction()
355
 
        result = self.open(a_bzrdir=a_bzrdir, _found=True)
 
309
        result = self.open(a_controldir=a_controldir, _found=True)
356
310
        result.lock_write()
357
311
        # the revision id here is irrelevant: it will not be stored, and cannot
358
312
        # already exist, we do this to create files on disk for older clients.
360
314
        result.revisions.get_parent_map([('A',)])
361
315
        result.signatures.get_parent_map([('A',)])
362
316
        result.unlock()
363
 
        self._run_post_repo_init_hooks(result, a_bzrdir, shared)
 
317
        self._run_post_repo_init_hooks(result, a_controldir, shared)
364
318
        return result
365
319
 
366
 
    def open(self, a_bzrdir, _found=False, _override_transport=None):
 
320
    def open(self, a_controldir, _found=False, _override_transport=None):
367
321
        """See RepositoryFormat.open().
368
322
 
369
323
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
371
325
                                    than normal. I.e. during 'upgrade'.
372
326
        """
373
327
        if not _found:
374
 
            format = RepositoryFormat.find_format(a_bzrdir)
 
328
            format = RepositoryFormatMetaDir.find_format(a_controldir)
375
329
        if _override_transport is not None:
376
330
            repo_transport = _override_transport
377
331
        else:
378
 
            repo_transport = a_bzrdir.get_repository_transport(None)
 
332
            repo_transport = a_controldir.get_repository_transport(None)
379
333
        control_files = lockable_files.LockableFiles(repo_transport,
380
334
                                'lock', lockdir.LockDir)
381
335
        repo = self.repository_class(_format=self,
382
 
                              a_bzrdir=a_bzrdir,
 
336
                              a_controldir=a_controldir,
383
337
                              control_files=control_files,
384
338
                              _commit_builder_class=self._commit_builder_class,
385
339
                              _serializer=self._serializer)
409
363
    """
410
364
 
411
365
    repository_class = KnitRepository
412
 
    _commit_builder_class = CommitBuilder
 
366
    _commit_builder_class = VersionedFileCommitBuilder
413
367
    @property
414
368
    def _serializer(self):
415
369
        return xml5.serializer_v5
417
371
    def __ne__(self, other):
418
372
        return self.__class__ is not other.__class__
419
373
 
420
 
    def get_format_string(self):
 
374
    @classmethod
 
375
    def get_format_string(cls):
421
376
        """See RepositoryFormat.get_format_string()."""
422
377
        return "Bazaar-NG Knit Repository Format 1"
423
378
 
443
398
    """
444
399
 
445
400
    repository_class = KnitRepository
446
 
    _commit_builder_class = RootCommitBuilder
 
401
    _commit_builder_class = VersionedFileRootCommitBuilder
447
402
    rich_root_data = True
448
403
    experimental = True
449
404
    supports_tree_reference = True
452
407
        return xml7.serializer_v7
453
408
 
454
409
    def _get_matching_bzrdir(self):
455
 
        return bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
 
410
        return controldir.format_registry.make_controldir('dirstate-with-subtree')
456
411
 
457
412
    def _ignore_setting_bzrdir(self, format):
458
413
        pass
459
414
 
460
 
    _matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
 
415
    _matchingcontroldir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
461
416
 
462
 
    def get_format_string(self):
 
417
    @classmethod
 
418
    def get_format_string(cls):
463
419
        """See RepositoryFormat.get_format_string()."""
464
420
        return "Bazaar Knit Repository Format 3 (bzr 0.15)\n"
465
421
 
485
441
    """
486
442
 
487
443
    repository_class = KnitRepository
488
 
    _commit_builder_class = RootCommitBuilder
 
444
    _commit_builder_class = VersionedFileRootCommitBuilder
489
445
    rich_root_data = True
490
446
    supports_tree_reference = False
491
447
    @property
493
449
        return xml6.serializer_v6
494
450
 
495
451
    def _get_matching_bzrdir(self):
496
 
        return bzrdir.format_registry.make_bzrdir('rich-root')
 
452
        return controldir.format_registry.make_controldir('rich-root')
497
453
 
498
454
    def _ignore_setting_bzrdir(self, format):
499
455
        pass
500
456
 
501
 
    _matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
 
457
    _matchingcontroldir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
502
458
 
503
 
    def get_format_string(self):
 
459
    @classmethod
 
460
    def get_format_string(cls):
504
461
        """See RepositoryFormat.get_format_string()."""
505
462
        return 'Bazaar Knit Repository Format 4 (bzr 1.0)\n'
506
463
 
507
464
    def get_format_description(self):
508
465
        """See RepositoryFormat.get_format_description()."""
509
466
        return "Knit repository format 4"
 
467
 
 
468
 
 
469
class InterKnitRepo(InterSameDataRepository):
 
470
    """Optimised code paths between Knit based repositories."""
 
471
 
 
472
    @classmethod
 
473
    def _get_repo_format_to_test(self):
 
474
        return RepositoryFormatKnit1()
 
475
 
 
476
    @staticmethod
 
477
    def is_compatible(source, target):
 
478
        """Be compatible with known Knit formats.
 
479
 
 
480
        We don't test for the stores being of specific types because that
 
481
        could lead to confusing results, and there is no need to be
 
482
        overly general.
 
483
        """
 
484
        try:
 
485
            are_knits = (isinstance(source._format, RepositoryFormatKnit) and
 
486
                isinstance(target._format, RepositoryFormatKnit))
 
487
        except AttributeError:
 
488
            return False
 
489
        return are_knits and InterRepository._same_model(source, target)
 
490
 
 
491
    def search_missing_revision_ids(self,
 
492
            find_ghosts=True, revision_ids=None, if_present_ids=None,
 
493
            limit=None):
 
494
        """See InterRepository.search_missing_revision_ids()."""
 
495
        with self.lock_read():
 
496
            source_ids_set = self._present_source_revisions_for(
 
497
                revision_ids, if_present_ids)
 
498
            # source_ids is the worst possible case we may need to pull.
 
499
            # now we want to filter source_ids against what we actually
 
500
            # have in target, but don't try to check for existence where we know
 
501
            # we do not have a revision as that would be pointless.
 
502
            target_ids = set(self.target.all_revision_ids())
 
503
            possibly_present_revisions = target_ids.intersection(source_ids_set)
 
504
            actually_present_revisions = set(
 
505
                self.target._eliminate_revisions_not_present(possibly_present_revisions))
 
506
            required_revisions = source_ids_set.difference(actually_present_revisions)
 
507
            if revision_ids is not None:
 
508
                # we used get_ancestry to determine source_ids then we are assured all
 
509
                # revisions referenced are present as they are installed in topological order.
 
510
                # and the tip revision was validated by get_ancestry.
 
511
                result_set = required_revisions
 
512
            else:
 
513
                # if we just grabbed the possibly available ids, then
 
514
                # we only have an estimate of whats available and need to validate
 
515
                # that against the revision records.
 
516
                result_set = set(
 
517
                    self.source._eliminate_revisions_not_present(required_revisions))
 
518
            if limit is not None:
 
519
                topo_ordered = self.source.get_graph().iter_topo_order(result_set)
 
520
                result_set = set(itertools.islice(topo_ordered, limit))
 
521
            return self.source.revision_ids_to_search_result(result_set)
 
522
 
 
523
 
 
524
InterRepository.register_optimiser(InterKnitRepo)