~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Patch Queue Manager
  • Date: 2016-01-15 09:21:49 UTC
  • mfrom: (6606.2.1 autodoc-unicode)
  • Revision ID: pqm@pqm.ubuntu.com-20160115092149-z5f4sfq3jvaz0enb
(vila) Fix autodoc runner when LANG=C. (Jelmer Vernooij)

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