~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

merge trunk

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
27
28
from bzrlib.lazy_import import lazy_import
28
29
lazy_import(globals(), """
29
30
from bzrlib import (
 
31
    bzrdir_weave,
30
32
    xml5,
31
33
    graph as _mod_graph,
 
34
    ui,
32
35
    )
33
36
""")
34
37
from bzrlib import (
35
 
    bzrdir,
36
38
    debug,
37
39
    errors,
38
40
    lockable_files,
39
41
    lockdir,
40
42
    osutils,
41
 
    revision as _mod_revision,
 
43
    symbol_versioning,
42
44
    trace,
 
45
    tuned_gzip,
43
46
    urlutils,
44
47
    versionedfile,
45
48
    weave,
48
51
from bzrlib.decorators import needs_read_lock, needs_write_lock
49
52
from bzrlib.repository import (
50
53
    CommitBuilder,
 
54
    InterRepository,
 
55
    InterSameDataRepository,
51
56
    MetaDirVersionedFileRepository,
52
57
    MetaDirRepositoryFormat,
53
58
    Repository,
54
59
    RepositoryFormat,
55
60
    )
56
61
from bzrlib.store.text import TextStore
57
 
from bzrlib.tuned_gzip import GzipFile, bytes_to_gzip
58
62
from bzrlib.versionedfile import (
59
63
    AbsentContentFactory,
60
64
    FulltextContentFactory,
61
65
    VersionedFiles,
62
66
    )
63
67
 
 
68
from bzrlib.plugins.weave_fmt import bzrdir as weave_bzrdir
 
69
 
64
70
 
65
71
class AllInOneRepository(Repository):
66
72
    """Legacy support - the repository behaviour for all-in-one branches."""
273
279
    _fetch_order = 'topological'
274
280
    _fetch_reconcile = True
275
281
    fast_deltas = False
 
282
    supports_leaving_lock = False
 
283
    supports_full_versioned_files = True
276
284
 
277
285
    def initialize(self, a_bzrdir, shared=False, _internal=False):
278
286
        """Create a weave repository."""
324
332
        result.chk_bytes = None
325
333
        return result
326
334
 
 
335
    def is_deprecated(self):
 
336
        return True
 
337
 
327
338
 
328
339
class RepositoryFormat4(PreSplitOutRepositoryFormat):
329
340
    """Bzr repository format 4.
337
348
    has been removed.
338
349
    """
339
350
 
340
 
    _matchingbzrdir = bzrdir.BzrDirFormat4()
 
351
    supports_funky_characters = False
 
352
 
 
353
    _matchingbzrdir = weave_bzrdir.BzrDirFormat4()
341
354
 
342
355
    def get_format_description(self):
343
356
        """See RepositoryFormat.get_format_description()."""
361
374
        return None
362
375
 
363
376
    def _get_revisions(self, repo_transport, repo):
364
 
        from bzrlib.xml4 import serializer_v4
 
377
        from bzrlib.plugins.weave_fmt.xml4 import serializer_v4
365
378
        return RevisionTextStore(repo_transport.clone('revision-store'),
366
379
            serializer_v4, True, versionedfile.PrefixMapper(),
367
380
            repo.is_locked, repo.is_write_locked)
385
398
    """
386
399
 
387
400
    _versionedfile_class = weave.WeaveFile
388
 
    _matchingbzrdir = bzrdir.BzrDirFormat5()
 
401
    _matchingbzrdir = weave_bzrdir.BzrDirFormat5()
 
402
    supports_funky_characters = False
 
403
 
389
404
    @property
390
405
    def _serializer(self):
391
406
        return xml5.serializer_v5
419
434
        return versionedfile.ThunkedVersionedFiles(base_transport,
420
435
            weave.WeaveFile, mapper, repo.is_locked)
421
436
 
 
437
    def _get_extra_interrepo_test_combinations(self):
 
438
        from bzrlib.repofmt import knitrepo
 
439
        return [(InterRepository, RepositoryFormat5(),
 
440
            knitrepo.RepositoryFormatKnit3())]
 
441
 
422
442
 
423
443
class RepositoryFormat6(PreSplitOutRepositoryFormat):
424
444
    """Bzr control format 6.
430
450
    """
431
451
 
432
452
    _versionedfile_class = weave.WeaveFile
433
 
    _matchingbzrdir = bzrdir.BzrDirFormat6()
 
453
    _matchingbzrdir = weave_bzrdir.BzrDirFormat6()
 
454
    supports_funky_characters = False
434
455
    @property
435
456
    def _serializer(self):
436
457
        return xml5.serializer_v5
480
501
    _versionedfile_class = weave.WeaveFile
481
502
    supports_ghosts = False
482
503
    supports_chks = False
 
504
    supports_funky_characters = False
 
505
    supports_full_versioned_files = True
483
506
 
484
507
    _fetch_order = 'topological'
485
508
    _fetch_reconcile = True
562
585
        result._transport = repo_transport
563
586
        return result
564
587
 
 
588
    def is_deprecated(self):
 
589
        return True
 
590
 
565
591
 
566
592
class TextVersionedFiles(VersionedFiles):
567
593
    """Just-a-bunch-of-files based VersionedFile stores."""
587
613
            raise ValueError('bad idea to put / in %r' % (key,))
588
614
        text = ''.join(lines)
589
615
        if self._compressed:
590
 
            text = bytes_to_gzip(text)
 
616
            text = tuned_gzip.bytes_to_gzip(text)
591
617
        path = self._map(key)
592
618
        self._transport.put_bytes_non_atomic(path, text, create_parent_dir=True)
593
619
 
635
661
            else:
636
662
                return None
637
663
        if compressed:
638
 
            text = GzipFile(mode='rb', fileobj=StringIO(text)).read()
 
664
            text = gzip.GzipFile(mode='rb', fileobj=StringIO(text)).read()
639
665
        return text
640
666
 
641
667
    def _map(self, key):
738
764
        paths = list(relpaths)
739
765
        return set([self._mapper.unmap(path) for path in paths])
740
766
 
741
 
_legacy_formats = [RepositoryFormat4(),
742
 
                   RepositoryFormat5(),
743
 
                   RepositoryFormat6()]
 
767
 
 
768
class InterWeaveRepo(InterSameDataRepository):
 
769
    """Optimised code paths between Weave based repositories.
 
770
    """
 
771
 
 
772
    @classmethod
 
773
    def _get_repo_format_to_test(self):
 
774
        return RepositoryFormat7()
 
775
 
 
776
    @staticmethod
 
777
    def is_compatible(source, target):
 
778
        """Be compatible with known Weave formats.
 
779
 
 
780
        We don't test for the stores being of specific types because that
 
781
        could lead to confusing results, and there is no need to be
 
782
        overly general.
 
783
        """
 
784
        try:
 
785
            return (isinstance(source._format, (RepositoryFormat5,
 
786
                                                RepositoryFormat6,
 
787
                                                RepositoryFormat7)) and
 
788
                    isinstance(target._format, (RepositoryFormat5,
 
789
                                                RepositoryFormat6,
 
790
                                                RepositoryFormat7)))
 
791
        except AttributeError:
 
792
            return False
 
793
 
 
794
    @needs_write_lock
 
795
    def copy_content(self, revision_id=None):
 
796
        """See InterRepository.copy_content()."""
 
797
        # weave specific optimised path:
 
798
        try:
 
799
            self.target.set_make_working_trees(self.source.make_working_trees())
 
800
        except (errors.RepositoryUpgradeRequired, NotImplemented):
 
801
            pass
 
802
        # FIXME do not peek!
 
803
        if self.source._transport.listable():
 
804
            pb = ui.ui_factory.nested_progress_bar()
 
805
            try:
 
806
                self.target.texts.insert_record_stream(
 
807
                    self.source.texts.get_record_stream(
 
808
                        self.source.texts.keys(), 'topological', False))
 
809
                pb.update('Copying inventory', 0, 1)
 
810
                self.target.inventories.insert_record_stream(
 
811
                    self.source.inventories.get_record_stream(
 
812
                        self.source.inventories.keys(), 'topological', False))
 
813
                self.target.signatures.insert_record_stream(
 
814
                    self.source.signatures.get_record_stream(
 
815
                        self.source.signatures.keys(),
 
816
                        'unordered', True))
 
817
                self.target.revisions.insert_record_stream(
 
818
                    self.source.revisions.get_record_stream(
 
819
                        self.source.revisions.keys(),
 
820
                        'topological', True))
 
821
            finally:
 
822
                pb.finished()
 
823
        else:
 
824
            self.target.fetch(self.source, revision_id=revision_id)
 
825
 
 
826
    @needs_read_lock
 
827
    def search_missing_revision_ids(self,
 
828
            revision_id=symbol_versioning.DEPRECATED_PARAMETER,
 
829
            find_ghosts=True, revision_ids=None, if_present_ids=None):
 
830
        """See InterRepository.search_missing_revision_ids()."""
 
831
        # we want all revisions to satisfy revision_id in source.
 
832
        # but we don't want to stat every file here and there.
 
833
        # we want then, all revisions other needs to satisfy revision_id
 
834
        # checked, but not those that we have locally.
 
835
        # so the first thing is to get a subset of the revisions to
 
836
        # satisfy revision_id in source, and then eliminate those that
 
837
        # we do already have.
 
838
        # this is slow on high latency connection to self, but as this
 
839
        # disk format scales terribly for push anyway due to rewriting
 
840
        # inventory.weave, this is considered acceptable.
 
841
        # - RBC 20060209
 
842
        if symbol_versioning.deprecated_passed(revision_id):
 
843
            symbol_versioning.warn(
 
844
                'search_missing_revision_ids(revision_id=...) was '
 
845
                'deprecated in 2.4.  Use revision_ids=[...] instead.',
 
846
                DeprecationWarning, stacklevel=2)
 
847
            if revision_ids is not None:
 
848
                raise AssertionError(
 
849
                    'revision_ids is mutually exclusive with revision_id')
 
850
            if revision_id is not None:
 
851
                revision_ids = [revision_id]
 
852
        del revision_id
 
853
        source_ids_set = self._present_source_revisions_for(
 
854
            revision_ids, if_present_ids)
 
855
        # source_ids is the worst possible case we may need to pull.
 
856
        # now we want to filter source_ids against what we actually
 
857
        # have in target, but don't try to check for existence where we know
 
858
        # we do not have a revision as that would be pointless.
 
859
        target_ids = set(self.target._all_possible_ids())
 
860
        possibly_present_revisions = target_ids.intersection(source_ids_set)
 
861
        actually_present_revisions = set(
 
862
            self.target._eliminate_revisions_not_present(possibly_present_revisions))
 
863
        required_revisions = source_ids_set.difference(actually_present_revisions)
 
864
        if revision_ids is not None:
 
865
            # we used get_ancestry to determine source_ids then we are assured all
 
866
            # revisions referenced are present as they are installed in topological order.
 
867
            # and the tip revision was validated by get_ancestry.
 
868
            result_set = required_revisions
 
869
        else:
 
870
            # if we just grabbed the possibly available ids, then
 
871
            # we only have an estimate of whats available and need to validate
 
872
            # that against the revision records.
 
873
            result_set = set(
 
874
                self.source._eliminate_revisions_not_present(required_revisions))
 
875
        return self.source.revision_ids_to_search_result(result_set)
 
876
 
 
877
 
 
878
InterRepository.register_optimiser(InterWeaveRepo)
 
879
 
 
880
 
 
881
def get_extra_interrepo_test_combinations():
 
882
    from bzrlib.repofmt import knitrepo
 
883
    return [(InterRepository, RepositoryFormat5(),
 
884
        knitrepo.RepositoryFormatKnit3())]