~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/weaverepo.py

  • Committer: Andrew Bennetts
  • Date: 2010-11-22 03:35:24 UTC
  • mto: This revision was merged to the branch mainline in revision 5547.
  • Revision ID: andrew.bennetts@canonical.com-20101122033524-ouxj0onm3gtkimx3
Remove RepositoryFormatCHK1 and RepositoryFormatCHK2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2011 Canonical Ltd
 
1
# Copyright (C) 2007-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
20
20
ghosts.
21
21
"""
22
22
 
23
 
import gzip
24
23
import os
25
24
from cStringIO import StringIO
26
25
import urllib
27
26
 
28
27
from bzrlib.lazy_import import lazy_import
29
28
lazy_import(globals(), """
30
 
import itertools
31
 
 
32
29
from bzrlib import (
33
30
    xml5,
34
31
    graph as _mod_graph,
35
 
    ui,
36
32
    )
37
33
""")
38
34
from bzrlib import (
 
35
    bzrdir,
39
36
    debug,
40
37
    errors,
41
38
    lockable_files,
42
39
    lockdir,
43
40
    osutils,
44
 
    symbol_versioning,
 
41
    revision as _mod_revision,
45
42
    trace,
46
 
    tuned_gzip,
47
43
    urlutils,
48
44
    versionedfile,
49
45
    weave,
51
47
    )
52
48
from bzrlib.decorators import needs_read_lock, needs_write_lock
53
49
from bzrlib.repository import (
54
 
    InterRepository,
 
50
    CommitBuilder,
 
51
    MetaDirVersionedFileRepository,
 
52
    MetaDirRepositoryFormat,
 
53
    Repository,
55
54
    RepositoryFormat,
56
55
    )
57
56
from bzrlib.store.text import TextStore
 
57
from bzrlib.tuned_gzip import GzipFile, bytes_to_gzip
58
58
from bzrlib.versionedfile import (
59
59
    AbsentContentFactory,
60
60
    FulltextContentFactory,
61
61
    VersionedFiles,
62
62
    )
63
 
from bzrlib.vf_repository import (
64
 
    InterSameDataRepository,
65
 
    VersionedFileCommitBuilder,
66
 
    VersionedFileRepository,
67
 
    VersionedFileRepositoryFormat,
68
 
    MetaDirVersionedFileRepository,
69
 
    MetaDirVersionedFileRepositoryFormat,
70
 
    )
71
 
 
72
 
from bzrlib.plugins.weave_fmt import bzrdir as weave_bzrdir
73
 
 
74
 
 
75
 
class AllInOneRepository(VersionedFileRepository):
 
63
 
 
64
 
 
65
class AllInOneRepository(Repository):
76
66
    """Legacy support - the repository behaviour for all-in-one branches."""
77
67
 
78
68
    @property
150
140
 
151
141
    def get_commit_builder(self, branch, parents, config, timestamp=None,
152
142
                           timezone=None, committer=None, revprops=None,
153
 
                           revision_id=None, lossy=False):
 
143
                           revision_id=None):
154
144
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
155
 
        result = VersionedFileCommitBuilder(self, parents, config, timestamp,
156
 
            timezone, committer, revprops, revision_id, lossy=lossy)
 
145
        result = CommitBuilder(self, parents, config, timestamp, timezone,
 
146
                              committer, revprops, revision_id)
157
147
        self.start_write_group()
158
148
        return result
159
149
 
193
183
        """Returns the policy for making working trees on new branches."""
194
184
        return True
195
185
 
 
186
    def revision_graph_can_have_wrong_parents(self):
 
187
        # XXX: This is an old format that we don't support full checking on, so
 
188
        # just claim that checking for this inconsistency is not required.
 
189
        return False
 
190
 
196
191
 
197
192
class WeaveMetaDirRepository(MetaDirVersionedFileRepository):
198
193
    """A subclass of MetaDirRepository to set weave specific policy."""
239
234
 
240
235
    def get_commit_builder(self, branch, parents, config, timestamp=None,
241
236
                           timezone=None, committer=None, revprops=None,
242
 
                           revision_id=None, lossy=False):
 
237
                           revision_id=None):
243
238
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
244
 
        result = VersionedFileCommitBuilder(self, parents, config, timestamp,
245
 
            timezone, committer, revprops, revision_id, lossy=lossy)
 
239
        result = CommitBuilder(self, parents, config, timestamp, timezone,
 
240
                              committer, revprops, revision_id)
246
241
        self.start_write_group()
247
242
        return result
248
243
 
263
258
        return self.inventories.add_lines((revision_id,), final_parents, lines,
264
259
            check_content=check_content)[0]
265
260
 
266
 
 
267
 
class PreSplitOutRepositoryFormat(VersionedFileRepositoryFormat):
 
261
    def revision_graph_can_have_wrong_parents(self):
 
262
        return False
 
263
 
 
264
 
 
265
class PreSplitOutRepositoryFormat(RepositoryFormat):
268
266
    """Base class for the pre split out repository formats."""
269
267
 
270
268
    rich_root_data = False
272
270
    supports_ghosts = False
273
271
    supports_external_lookups = False
274
272
    supports_chks = False
275
 
    supports_nesting_repositories = True
276
273
    _fetch_order = 'topological'
277
274
    _fetch_reconcile = True
278
275
    fast_deltas = False
279
 
    supports_leaving_lock = False
280
 
    # XXX: This is an old format that we don't support full checking on, so
281
 
    # just claim that checking for this inconsistency is not required.
282
 
    revision_graph_can_have_wrong_parents = False
283
276
 
284
277
    def initialize(self, a_bzrdir, shared=False, _internal=False):
285
278
        """Create a weave repository."""
331
324
        result.chk_bytes = None
332
325
        return result
333
326
 
334
 
    def is_deprecated(self):
335
 
        return True
336
 
 
337
327
 
338
328
class RepositoryFormat4(PreSplitOutRepositoryFormat):
339
329
    """Bzr repository format 4.
347
337
    has been removed.
348
338
    """
349
339
 
350
 
    supports_funky_characters = False
351
 
 
352
 
    _matchingbzrdir = weave_bzrdir.BzrDirFormat4()
 
340
    _matchingbzrdir = bzrdir.BzrDirFormat4()
353
341
 
354
342
    def get_format_description(self):
355
343
        """See RepositoryFormat.get_format_description()."""
373
361
        return None
374
362
 
375
363
    def _get_revisions(self, repo_transport, repo):
376
 
        from bzrlib.plugins.weave_fmt.xml4 import serializer_v4
 
364
        from bzrlib.xml4 import serializer_v4
377
365
        return RevisionTextStore(repo_transport.clone('revision-store'),
378
366
            serializer_v4, True, versionedfile.PrefixMapper(),
379
367
            repo.is_locked, repo.is_write_locked)
397
385
    """
398
386
 
399
387
    _versionedfile_class = weave.WeaveFile
400
 
    _matchingbzrdir = weave_bzrdir.BzrDirFormat5()
401
 
    supports_funky_characters = False
402
 
 
 
388
    _matchingbzrdir = bzrdir.BzrDirFormat5()
403
389
    @property
404
390
    def _serializer(self):
405
391
        return xml5.serializer_v5
444
430
    """
445
431
 
446
432
    _versionedfile_class = weave.WeaveFile
447
 
    _matchingbzrdir = weave_bzrdir.BzrDirFormat6()
448
 
    supports_funky_characters = False
 
433
    _matchingbzrdir = bzrdir.BzrDirFormat6()
449
434
    @property
450
435
    def _serializer(self):
451
436
        return xml5.serializer_v5
480
465
            weave.WeaveFile, mapper, repo.is_locked)
481
466
 
482
467
 
483
 
class RepositoryFormat7(MetaDirVersionedFileRepositoryFormat):
 
468
class RepositoryFormat7(MetaDirRepositoryFormat):
484
469
    """Bzr repository 7.
485
470
 
486
471
    This repository format has:
495
480
    _versionedfile_class = weave.WeaveFile
496
481
    supports_ghosts = False
497
482
    supports_chks = False
498
 
    supports_funky_characters = False
499
 
    revision_graph_can_have_wrong_parents = False
500
483
 
501
484
    _fetch_order = 'topological'
502
485
    _fetch_reconcile = True
579
562
        result._transport = repo_transport
580
563
        return result
581
564
 
582
 
    def is_deprecated(self):
583
 
        return True
584
 
 
585
565
 
586
566
class TextVersionedFiles(VersionedFiles):
587
567
    """Just-a-bunch-of-files based VersionedFile stores."""
607
587
            raise ValueError('bad idea to put / in %r' % (key,))
608
588
        text = ''.join(lines)
609
589
        if self._compressed:
610
 
            text = tuned_gzip.bytes_to_gzip(text)
 
590
            text = bytes_to_gzip(text)
611
591
        path = self._map(key)
612
592
        self._transport.put_bytes_non_atomic(path, text, create_parent_dir=True)
613
593
 
633
613
                    record, record.get_bytes_as(record.storage_kind)))
634
614
                try:
635
615
                    self.add_lines(record.key, None, lines)
636
 
                except errors.RevisionAlreadyPresent:
 
616
                except RevisionAlreadyPresent:
637
617
                    pass
638
618
 
639
619
    def _load_text(self, key):
655
635
            else:
656
636
                return None
657
637
        if compressed:
658
 
            text = gzip.GzipFile(mode='rb', fileobj=StringIO(text)).read()
 
638
            text = GzipFile(mode='rb', fileobj=StringIO(text)).read()
659
639
        return text
660
640
 
661
641
    def _map(self, key):
758
738
        paths = list(relpaths)
759
739
        return set([self._mapper.unmap(path) for path in paths])
760
740
 
761
 
 
762
 
class InterWeaveRepo(InterSameDataRepository):
763
 
    """Optimised code paths between Weave based repositories.
764
 
    """
765
 
 
766
 
    @classmethod
767
 
    def _get_repo_format_to_test(self):
768
 
        return RepositoryFormat7()
769
 
 
770
 
    @staticmethod
771
 
    def is_compatible(source, target):
772
 
        """Be compatible with known Weave formats.
773
 
 
774
 
        We don't test for the stores being of specific types because that
775
 
        could lead to confusing results, and there is no need to be
776
 
        overly general.
777
 
        """
778
 
        try:
779
 
            return (isinstance(source._format, (RepositoryFormat5,
780
 
                                                RepositoryFormat6,
781
 
                                                RepositoryFormat7)) and
782
 
                    isinstance(target._format, (RepositoryFormat5,
783
 
                                                RepositoryFormat6,
784
 
                                                RepositoryFormat7)))
785
 
        except AttributeError:
786
 
            return False
787
 
 
788
 
    @needs_write_lock
789
 
    def copy_content(self, revision_id=None):
790
 
        """See InterRepository.copy_content()."""
791
 
        # weave specific optimised path:
792
 
        try:
793
 
            self.target.set_make_working_trees(self.source.make_working_trees())
794
 
        except (errors.RepositoryUpgradeRequired, NotImplemented):
795
 
            pass
796
 
        # FIXME do not peek!
797
 
        if self.source._transport.listable():
798
 
            pb = ui.ui_factory.nested_progress_bar()
799
 
            try:
800
 
                self.target.texts.insert_record_stream(
801
 
                    self.source.texts.get_record_stream(
802
 
                        self.source.texts.keys(), 'topological', False))
803
 
                pb.update('Copying inventory', 0, 1)
804
 
                self.target.inventories.insert_record_stream(
805
 
                    self.source.inventories.get_record_stream(
806
 
                        self.source.inventories.keys(), 'topological', False))
807
 
                self.target.signatures.insert_record_stream(
808
 
                    self.source.signatures.get_record_stream(
809
 
                        self.source.signatures.keys(),
810
 
                        'unordered', True))
811
 
                self.target.revisions.insert_record_stream(
812
 
                    self.source.revisions.get_record_stream(
813
 
                        self.source.revisions.keys(),
814
 
                        'topological', True))
815
 
            finally:
816
 
                pb.finished()
817
 
        else:
818
 
            self.target.fetch(self.source, revision_id=revision_id)
819
 
 
820
 
    @needs_read_lock
821
 
    def search_missing_revision_ids(self,
822
 
            revision_id=symbol_versioning.DEPRECATED_PARAMETER,
823
 
            find_ghosts=True, revision_ids=None, if_present_ids=None,
824
 
            limit=None):
825
 
        """See InterRepository.search_missing_revision_ids()."""
826
 
        # we want all revisions to satisfy revision_id in source.
827
 
        # but we don't want to stat every file here and there.
828
 
        # we want then, all revisions other needs to satisfy revision_id
829
 
        # checked, but not those that we have locally.
830
 
        # so the first thing is to get a subset of the revisions to
831
 
        # satisfy revision_id in source, and then eliminate those that
832
 
        # we do already have.
833
 
        # this is slow on high latency connection to self, but as this
834
 
        # disk format scales terribly for push anyway due to rewriting
835
 
        # inventory.weave, this is considered acceptable.
836
 
        # - RBC 20060209
837
 
        if symbol_versioning.deprecated_passed(revision_id):
838
 
            symbol_versioning.warn(
839
 
                'search_missing_revision_ids(revision_id=...) was '
840
 
                'deprecated in 2.4.  Use revision_ids=[...] instead.',
841
 
                DeprecationWarning, stacklevel=2)
842
 
            if revision_ids is not None:
843
 
                raise AssertionError(
844
 
                    'revision_ids is mutually exclusive with revision_id')
845
 
            if revision_id is not None:
846
 
                revision_ids = [revision_id]
847
 
        del revision_id
848
 
        source_ids_set = self._present_source_revisions_for(
849
 
            revision_ids, if_present_ids)
850
 
        # source_ids is the worst possible case we may need to pull.
851
 
        # now we want to filter source_ids against what we actually
852
 
        # have in target, but don't try to check for existence where we know
853
 
        # we do not have a revision as that would be pointless.
854
 
        target_ids = set(self.target._all_possible_ids())
855
 
        possibly_present_revisions = target_ids.intersection(source_ids_set)
856
 
        actually_present_revisions = set(
857
 
            self.target._eliminate_revisions_not_present(possibly_present_revisions))
858
 
        required_revisions = source_ids_set.difference(actually_present_revisions)
859
 
        if revision_ids is not None:
860
 
            # we used get_ancestry to determine source_ids then we are assured all
861
 
            # revisions referenced are present as they are installed in topological order.
862
 
            # and the tip revision was validated by get_ancestry.
863
 
            result_set = required_revisions
864
 
        else:
865
 
            # if we just grabbed the possibly available ids, then
866
 
            # we only have an estimate of whats available and need to validate
867
 
            # that against the revision records.
868
 
            result_set = set(
869
 
                self.source._eliminate_revisions_not_present(required_revisions))
870
 
        if limit is not None:
871
 
            topo_ordered = self.get_graph().iter_topo_order(result_set)
872
 
            result_set = set(itertools.islice(topo_ordered, limit))
873
 
        return self.source.revision_ids_to_search_result(result_set)
874
 
 
875
 
 
876
 
InterRepository.register_optimiser(InterWeaveRepo)
877
 
 
878
 
 
879
 
def get_extra_interrepo_test_combinations():
880
 
    from bzrlib.repofmt import knitrepo
881
 
    return [(InterRepository, RepositoryFormat5(),
882
 
        knitrepo.RepositoryFormatKnit3())]
 
741
_legacy_formats = [RepositoryFormat4(),
 
742
                   RepositoryFormat5(),
 
743
                   RepositoryFormat6()]