~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-07-22 18:09:04 UTC
  • mfrom: (2485.8.63 bzr.connection.sharing)
  • Revision ID: pqm@pqm.ubuntu.com-20070722180904-wy7y7oyi32wbghgf
Transport connection sharing

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
lazy_import(globals(), """
21
21
import re
22
22
import time
23
 
import unittest
24
23
 
25
24
from bzrlib import (
26
25
    bzrdir,
27
26
    check,
 
27
    deprecated_graph,
28
28
    errors,
29
29
    generate_ids,
30
30
    gpg,
40
40
    transactions,
41
41
    ui,
42
42
    )
 
43
from bzrlib.bundle import serializer
43
44
from bzrlib.revisiontree import RevisionTree
44
45
from bzrlib.store.versioned import VersionedFileStore
45
46
from bzrlib.store.text import TextStore
143
144
                self.add_inventory(revision_id, inv, rev.parent_ids)
144
145
        self._revision_store.add_revision(rev, self.get_transaction())
145
146
 
 
147
    def _add_revision_text(self, revision_id, text):
 
148
        revision = self._revision_store._serializer.read_revision_from_string(
 
149
            text)
 
150
        self._revision_store._add_revision(revision, StringIO(text),
 
151
                                           self.get_transaction())
 
152
 
146
153
    @needs_read_lock
147
154
    def _all_possible_ids(self):
148
155
        """Return all the possible revisions that we could find."""
365
372
        except NotImplementedError:
366
373
            raise errors.IncompatibleRepositories(source, self)
367
374
 
 
375
    def create_bundle(self, target, base, fileobj, format=None):
 
376
        return serializer.write_bundle(self, target, base, fileobj, format)
 
377
 
368
378
    def get_commit_builder(self, branch, parents, config, timestamp=None, 
369
379
                           timezone=None, committer=None, revprops=None, 
370
380
                           revision_id=None):
643
653
    def serialise_inventory(self, inv):
644
654
        return self._serializer.write_inventory_to_string(inv)
645
655
 
 
656
    def get_serializer_format(self):
 
657
        return self._serializer.format_num
 
658
 
646
659
    @needs_read_lock
647
660
    def get_inventory_xml(self, revision_id):
648
661
        """Get inventory XML as a file object."""
703
716
        :param revision_ids: an iterable of revisions to graph or None for all.
704
717
        :return: a Graph object with the graph reachable from revision_ids.
705
718
        """
706
 
        result = graph.Graph()
 
719
        result = deprecated_graph.Graph()
707
720
        if not revision_ids:
708
721
            pending = set(self.all_revision_ids())
709
722
            required = set([])
818
831
            yield RevisionTree(self, inv, revision_id)
819
832
 
820
833
    @needs_read_lock
821
 
    def get_ancestry(self, revision_id):
 
834
    def get_ancestry(self, revision_id, topo_sorted=True):
822
835
        """Return a list of revision-ids integrated by a revision.
823
836
 
824
837
        The first element of the list is always None, indicating the origin 
827
840
        
828
841
        This is topologically sorted.
829
842
        """
830
 
        if revision_id is None:
 
843
        if _mod_revision.is_null(revision_id):
831
844
            return [None]
832
845
        revision_id = osutils.safe_revision_id(revision_id)
833
846
        if not self.has_revision(revision_id):
834
847
            raise errors.NoSuchRevision(self, revision_id)
835
848
        w = self.get_inventory_weave()
836
 
        candidates = w.get_ancestry(revision_id)
 
849
        candidates = w.get_ancestry(revision_id, topo_sorted)
837
850
        return [None] + candidates # self._eliminate_revisions_not_present(candidates)
838
851
 
 
852
    def pack(self):
 
853
        """Compress the data within the repository.
 
854
 
 
855
        This operation only makes sense for some repository types. For other
 
856
        types it should be a no-op that just returns.
 
857
 
 
858
        This stub method does not require a lock, but subclasses should use
 
859
        @needs_write_lock as this is a long running call its reasonable to 
 
860
        implicitly lock for the user.
 
861
        """
 
862
 
839
863
    @needs_read_lock
840
864
    def print_file(self, file, revision_id):
841
865
        """Print `file` to stdout.
862
886
        revision_id = osutils.safe_revision_id(revision_id)
863
887
        return self.get_inventory_weave().parent_names(revision_id)
864
888
 
 
889
    def get_parents(self, revision_ids):
 
890
        """See StackedParentsProvider.get_parents"""
 
891
        parents_list = []
 
892
        for revision_id in revision_ids:
 
893
            if revision_id == _mod_revision.NULL_REVISION:
 
894
                parents = []
 
895
            else:
 
896
                try:
 
897
                    parents = self.get_revision(revision_id).parent_ids
 
898
                except errors.NoSuchRevision:
 
899
                    parents = None
 
900
                else:
 
901
                    if len(parents) == 0:
 
902
                        parents = [_mod_revision.NULL_REVISION]
 
903
            parents_list.append(parents)
 
904
        return parents_list
 
905
 
 
906
    def _make_parents_provider(self):
 
907
        return self
 
908
 
 
909
    def get_graph(self, other_repository=None):
 
910
        """Return the graph walker for this repository format"""
 
911
        parents_provider = self._make_parents_provider()
 
912
        if (other_repository is not None and
 
913
            other_repository.bzrdir.transport.base !=
 
914
            self.bzrdir.transport.base):
 
915
            parents_provider = graph._StackedParentsProvider(
 
916
                [parents_provider, other_repository._make_parents_provider()])
 
917
        return graph.Graph(parents_provider)
 
918
 
865
919
    @needs_write_lock
866
920
    def set_make_working_trees(self, new_value):
867
921
        """Set the policy flag for making working trees when creating branches.
1756
1810
InterRepository.register_optimiser(InterRemoteRepository)
1757
1811
 
1758
1812
 
1759
 
class RepositoryTestProviderAdapter(object):
1760
 
    """A tool to generate a suite testing multiple repository formats at once.
1761
 
 
1762
 
    This is done by copying the test once for each transport and injecting
1763
 
    the transport_server, transport_readonly_server, and bzrdir_format and
1764
 
    repository_format classes into each copy. Each copy is also given a new id()
1765
 
    to make it easy to identify.
1766
 
    """
1767
 
 
1768
 
    def __init__(self, transport_server, transport_readonly_server, formats,
1769
 
                 vfs_transport_factory=None):
1770
 
        self._transport_server = transport_server
1771
 
        self._transport_readonly_server = transport_readonly_server
1772
 
        self._vfs_transport_factory = vfs_transport_factory
1773
 
        self._formats = formats
1774
 
    
1775
 
    def adapt(self, test):
1776
 
        result = unittest.TestSuite()
1777
 
        for repository_format, bzrdir_format in self._formats:
1778
 
            from copy import deepcopy
1779
 
            new_test = deepcopy(test)
1780
 
            new_test.transport_server = self._transport_server
1781
 
            new_test.transport_readonly_server = self._transport_readonly_server
1782
 
            # Only override the test's vfs_transport_factory if one was
1783
 
            # specified, otherwise just leave the default in place.
1784
 
            if self._vfs_transport_factory:
1785
 
                new_test.vfs_transport_factory = self._vfs_transport_factory
1786
 
            new_test.bzrdir_format = bzrdir_format
1787
 
            new_test.repository_format = repository_format
1788
 
            def make_new_test_id():
1789
 
                new_id = "%s(%s)" % (new_test.id(), repository_format.__class__.__name__)
1790
 
                return lambda: new_id
1791
 
            new_test.id = make_new_test_id()
1792
 
            result.addTest(new_test)
1793
 
        return result
1794
 
 
1795
 
 
1796
 
class InterRepositoryTestProviderAdapter(object):
1797
 
    """A tool to generate a suite testing multiple inter repository formats.
1798
 
 
1799
 
    This is done by copying the test once for each interrepo provider and injecting
1800
 
    the transport_server, transport_readonly_server, repository_format and 
1801
 
    repository_to_format classes into each copy.
1802
 
    Each copy is also given a new id() to make it easy to identify.
1803
 
    """
1804
 
 
1805
 
    def __init__(self, transport_server, transport_readonly_server, formats):
1806
 
        self._transport_server = transport_server
1807
 
        self._transport_readonly_server = transport_readonly_server
1808
 
        self._formats = formats
1809
 
    
1810
 
    def adapt(self, test):
1811
 
        result = unittest.TestSuite()
1812
 
        for interrepo_class, repository_format, repository_format_to in self._formats:
1813
 
            from copy import deepcopy
1814
 
            new_test = deepcopy(test)
1815
 
            new_test.transport_server = self._transport_server
1816
 
            new_test.transport_readonly_server = self._transport_readonly_server
1817
 
            new_test.interrepo_class = interrepo_class
1818
 
            new_test.repository_format = repository_format
1819
 
            new_test.repository_format_to = repository_format_to
1820
 
            def make_new_test_id():
1821
 
                new_id = "%s(%s)" % (new_test.id(), interrepo_class.__name__)
1822
 
                return lambda: new_id
1823
 
            new_test.id = make_new_test_id()
1824
 
            result.addTest(new_test)
1825
 
        return result
1826
 
 
1827
 
    @staticmethod
1828
 
    def default_test_list():
1829
 
        """Generate the default list of interrepo permutations to test."""
1830
 
        from bzrlib.repofmt import knitrepo, weaverepo
1831
 
        result = []
1832
 
        # test the default InterRepository between format 6 and the current 
1833
 
        # default format.
1834
 
        # XXX: robertc 20060220 reinstate this when there are two supported
1835
 
        # formats which do not have an optimal code path between them.
1836
 
        #result.append((InterRepository,
1837
 
        #               RepositoryFormat6(),
1838
 
        #               RepositoryFormatKnit1()))
1839
 
        for optimiser_class in InterRepository._optimisers:
1840
 
            format_to_test = optimiser_class._get_repo_format_to_test()
1841
 
            if format_to_test is not None:
1842
 
                result.append((optimiser_class,
1843
 
                               format_to_test, format_to_test))
1844
 
        # if there are specific combinations we want to use, we can add them 
1845
 
        # here.
1846
 
        result.append((InterModel1and2,
1847
 
                       weaverepo.RepositoryFormat5(),
1848
 
                       knitrepo.RepositoryFormatKnit3()))
1849
 
        result.append((InterKnit1and2,
1850
 
                       knitrepo.RepositoryFormatKnit1(),
1851
 
                       knitrepo.RepositoryFormatKnit3()))
1852
 
        return result
1853
 
 
1854
 
 
1855
1813
class CopyConverter(object):
1856
1814
    """A repository conversion tool which just performs a copy of the content.
1857
1815