~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/plugins/weave_fmt/repository.py

  • Committer: John Arbash Meinel
  • Date: 2011-05-11 11:35:28 UTC
  • mto: This revision was merged to the branch mainline in revision 5851.
  • Revision ID: john@arbash-meinel.com-20110511113528-qepibuwxicjrbb2h
Break compatibility with python <2.6.

This includes auditing the code for places where we were doing
explicit 'sys.version' checks and removing them as appropriate.

Show diffs side-by-side

added added

removed removed

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