/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: Aaron Bentley
  • Date: 2007-02-16 07:02:19 UTC
  • mfrom: (2292 +trunk)
  • mto: (2255.6.1 dirstate)
  • mto: This revision was merged to the branch mainline in revision 2322.
  • Revision ID: aaron.bentley@utoronto.ca-20070216070219-b22k0gwnisnxawnk
Merged bzr.dev (17 tests failing)

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
from bzrlib.lazy_import import lazy_import
20
20
lazy_import(globals(), """
21
 
from binascii import hexlify
22
 
from copy import deepcopy
23
21
import re
24
22
import time
25
23
import unittest
27
25
from bzrlib import (
28
26
    bzrdir,
29
27
    check,
30
 
    delta,
31
28
    errors,
32
29
    generate_ids,
33
30
    gpg,
34
31
    graph,
35
 
    knit,
36
32
    lazy_regex,
37
33
    lockable_files,
38
34
    lockdir,
42
38
    symbol_versioning,
43
39
    transactions,
44
40
    ui,
45
 
    weave,
46
 
    weavefile,
47
 
    xml5,
48
 
    xml6,
49
 
    xml7,
50
 
    )
51
 
from bzrlib.osutils import (
52
 
    rand_bytes,
53
 
    compact_date, 
54
 
    local_time_offset,
55
41
    )
56
42
from bzrlib.revisiontree import RevisionTree
57
43
from bzrlib.store.versioned import VersionedFileStore
58
44
from bzrlib.store.text import TextStore
59
45
from bzrlib.testament import Testament
 
46
 
60
47
""")
61
48
 
62
49
from bzrlib.decorators import needs_read_lock, needs_write_lock
225
212
        # TODO: make sure to construct the right store classes, etc, depending
226
213
        # on whether escaping is required.
227
214
        self._warn_if_deprecated()
228
 
        self._serializer = xml5.serializer_v5
229
215
 
230
216
    def __repr__(self):
231
217
        return '%s(%r)' % (self.__class__.__name__, 
355
341
 
356
342
        Currently no check is made that the format of this repository and
357
343
        the bzrdir format are compatible. FIXME RBC 20060201.
 
344
 
 
345
        :return: The newly created destination repository.
358
346
        """
359
347
        if not isinstance(a_bzrdir._format, self.bzrdir._format.__class__):
360
348
            # use target default format.
361
 
            result = a_bzrdir.create_repository()
362
 
        # FIXME RBC 20060209 split out the repository type to avoid this check ?
363
 
        elif isinstance(a_bzrdir._format,
364
 
                      (bzrdir.BzrDirFormat4,
365
 
                       bzrdir.BzrDirFormat5,
366
 
                       bzrdir.BzrDirFormat6)):
367
 
            result = a_bzrdir.open_repository()
 
349
            dest_repo = a_bzrdir.create_repository()
368
350
        else:
369
 
            result = self._format.initialize(a_bzrdir, shared=self.is_shared())
370
 
        self.copy_content_into(result, revision_id, basis)
371
 
        return result
 
351
            # Most control formats need the repository to be specifically
 
352
            # created, but on some old all-in-one formats it's not needed
 
353
            try:
 
354
                dest_repo = self._format.initialize(a_bzrdir, shared=self.is_shared())
 
355
            except errors.UninitializableFormat:
 
356
                dest_repo = a_bzrdir.open_repository()
 
357
        self.copy_content_into(dest_repo, revision_id, basis)
 
358
        return dest_repo
372
359
 
373
360
    @needs_read_lock
374
361
    def has_revision(self, revision_id):
657
644
            done.add(revision_id)
658
645
        return result
659
646
 
 
647
    def _get_history_vf(self):
 
648
        """Get a versionedfile whose history graph reflects all revisions.
 
649
 
 
650
        For weave repositories, this is the inventory weave.
 
651
        """
 
652
        return self.get_inventory_weave()
 
653
 
 
654
    def iter_reverse_revision_history(self, revision_id):
 
655
        """Iterate backwards through revision ids in the lefthand history
 
656
 
 
657
        :param revision_id: The revision id to start with.  All its lefthand
 
658
            ancestors will be traversed.
 
659
        """
 
660
        if revision_id in (None, _mod_revision.NULL_REVISION):
 
661
            return
 
662
        next_id = revision_id
 
663
        versionedfile = self._get_history_vf()
 
664
        while True:
 
665
            yield next_id
 
666
            parents = versionedfile.get_parents(next_id)
 
667
            if len(parents) == 0:
 
668
                return
 
669
            else:
 
670
                next_id = parents[0]
 
671
 
660
672
    @needs_read_lock
661
673
    def get_revision_inventory(self, revision_id):
662
674
        """Return inventory of a past revision."""
830
842
                    raise errors.NonAsciiRevisionId(method, self)
831
843
 
832
844
 
833
 
class AllInOneRepository(Repository):
834
 
    """Legacy support - the repository behaviour for all-in-one branches."""
835
 
 
836
 
    def __init__(self, _format, a_bzrdir, _revision_store, control_store, text_store):
837
 
        # we reuse one control files instance.
838
 
        dir_mode = a_bzrdir._control_files._dir_mode
839
 
        file_mode = a_bzrdir._control_files._file_mode
840
 
 
841
 
        def get_store(name, compressed=True, prefixed=False):
842
 
            # FIXME: This approach of assuming stores are all entirely compressed
843
 
            # or entirely uncompressed is tidy, but breaks upgrade from 
844
 
            # some existing branches where there's a mixture; we probably 
845
 
            # still want the option to look for both.
846
 
            relpath = a_bzrdir._control_files._escape(name)
847
 
            store = TextStore(a_bzrdir._control_files._transport.clone(relpath),
848
 
                              prefixed=prefixed, compressed=compressed,
849
 
                              dir_mode=dir_mode,
850
 
                              file_mode=file_mode)
851
 
            #if self._transport.should_cache():
852
 
            #    cache_path = os.path.join(self.cache_root, name)
853
 
            #    os.mkdir(cache_path)
854
 
            #    store = bzrlib.store.CachedStore(store, cache_path)
855
 
            return store
856
 
 
857
 
        # not broken out yet because the controlweaves|inventory_store
858
 
        # and text_store | weave_store bits are still different.
859
 
        if isinstance(_format, RepositoryFormat4):
860
 
            # cannot remove these - there is still no consistent api 
861
 
            # which allows access to this old info.
862
 
            self.inventory_store = get_store('inventory-store')
863
 
            text_store = get_store('text-store')
864
 
        super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files, _revision_store, control_store, text_store)
865
 
 
866
 
    def get_commit_builder(self, branch, parents, config, timestamp=None,
867
 
                           timezone=None, committer=None, revprops=None,
868
 
                           revision_id=None):
869
 
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
870
 
        return Repository.get_commit_builder(self, branch, parents, config,
871
 
            timestamp, timezone, committer, revprops, revision_id)
872
 
 
873
 
    @needs_read_lock
874
 
    def is_shared(self):
875
 
        """AllInOne repositories cannot be shared."""
876
 
        return False
877
 
 
878
 
    @needs_write_lock
879
 
    def set_make_working_trees(self, new_value):
880
 
        """Set the policy flag for making working trees when creating branches.
881
 
 
882
 
        This only applies to branches that use this repository.
883
 
 
884
 
        The default is 'True'.
885
 
        :param new_value: True to restore the default, False to disable making
886
 
                          working trees.
887
 
        """
888
 
        raise NotImplementedError(self.set_make_working_trees)
889
 
    
890
 
    def make_working_trees(self):
891
 
        """Returns the policy for making working trees on new branches."""
892
 
        return True
 
845
 
 
846
# remove these delegates a while after bzr 0.15
 
847
def __make_delegated(name, from_module):
 
848
    def _deprecated_repository_forwarder():
 
849
        symbol_versioning.warn('%s moved to %s in bzr 0.15'
 
850
            % (name, from_module),
 
851
            DeprecationWarning,
 
852
            stacklevel=2)
 
853
        m = __import__(from_module, globals(), locals(), [name])
 
854
        try:
 
855
            return getattr(m, name)
 
856
        except AttributeError:
 
857
            raise AttributeError('module %s has no name %s'
 
858
                    % (m, name))
 
859
    globals()[name] = _deprecated_repository_forwarder
 
860
 
 
861
for _name in [
 
862
        'AllInOneRepository',
 
863
        'WeaveMetaDirRepository',
 
864
        'PreSplitOutRepositoryFormat',
 
865
        'RepositoryFormat4',
 
866
        'RepositoryFormat5',
 
867
        'RepositoryFormat6',
 
868
        'RepositoryFormat7',
 
869
        ]:
 
870
    __make_delegated(_name, 'bzrlib.repofmt.weaverepo')
 
871
 
 
872
for _name in [
 
873
        'KnitRepository',
 
874
        'KnitRepository2',
 
875
        'RepositoryFormatKnit',
 
876
        'RepositoryFormatKnit1',
 
877
        'RepositoryFormatKnit2',
 
878
        ]:
 
879
    __make_delegated(_name, 'bzrlib.repofmt.knitrepo')
893
880
 
894
881
 
895
882
def install_revision(repository, rev, revision_tree):
981
968
        return not self.control_files._transport.has('no-working-trees')
982
969
 
983
970
 
984
 
class WeaveMetaDirRepository(MetaDirRepository):
985
 
    """A subclass of MetaDirRepository to set weave specific policy."""
986
 
 
987
 
    def get_commit_builder(self, branch, parents, config, timestamp=None,
988
 
                           timezone=None, committer=None, revprops=None,
989
 
                           revision_id=None):
990
 
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
991
 
        return MetaDirRepository.get_commit_builder(self, branch, parents,
992
 
            config, timestamp, timezone, committer, revprops, revision_id)
993
 
 
994
 
 
995
 
class KnitRepository(MetaDirRepository):
996
 
    """Knit format repository."""
997
 
 
998
 
    def _warn_if_deprecated(self):
999
 
        # This class isn't deprecated
1000
 
        pass
1001
 
 
1002
 
    def _inventory_add_lines(self, inv_vf, revid, parents, lines):
1003
 
        inv_vf.add_lines_with_ghosts(revid, parents, lines)
1004
 
 
1005
 
    @needs_read_lock
1006
 
    def _all_revision_ids(self):
1007
 
        """See Repository.all_revision_ids()."""
1008
 
        # Knits get the revision graph from the index of the revision knit, so
1009
 
        # it's always possible even if they're on an unlistable transport.
1010
 
        return self._revision_store.all_revision_ids(self.get_transaction())
1011
 
 
1012
 
    def fileid_involved_between_revs(self, from_revid, to_revid):
1013
 
        """Find file_id(s) which are involved in the changes between revisions.
1014
 
 
1015
 
        This determines the set of revisions which are involved, and then
1016
 
        finds all file ids affected by those revisions.
1017
 
        """
1018
 
        vf = self._get_revision_vf()
1019
 
        from_set = set(vf.get_ancestry(from_revid))
1020
 
        to_set = set(vf.get_ancestry(to_revid))
1021
 
        changed = to_set.difference(from_set)
1022
 
        return self._fileid_involved_by_set(changed)
1023
 
 
1024
 
    def fileid_involved(self, last_revid=None):
1025
 
        """Find all file_ids modified in the ancestry of last_revid.
1026
 
 
1027
 
        :param last_revid: If None, last_revision() will be used.
1028
 
        """
1029
 
        if not last_revid:
1030
 
            changed = set(self.all_revision_ids())
1031
 
        else:
1032
 
            changed = set(self.get_ancestry(last_revid))
1033
 
        if None in changed:
1034
 
            changed.remove(None)
1035
 
        return self._fileid_involved_by_set(changed)
1036
 
 
1037
 
    @needs_read_lock
1038
 
    def get_ancestry(self, revision_id):
1039
 
        """Return a list of revision-ids integrated by a revision.
1040
 
        
1041
 
        This is topologically sorted.
1042
 
        """
1043
 
        if revision_id is None:
1044
 
            return [None]
1045
 
        vf = self._get_revision_vf()
1046
 
        try:
1047
 
            return [None] + vf.get_ancestry(revision_id)
1048
 
        except errors.RevisionNotPresent:
1049
 
            raise errors.NoSuchRevision(self, revision_id)
1050
 
 
1051
 
    @needs_read_lock
1052
 
    def get_revision(self, revision_id):
1053
 
        """Return the Revision object for a named revision"""
1054
 
        return self.get_revision_reconcile(revision_id)
1055
 
 
1056
 
    @needs_read_lock
1057
 
    def get_revision_graph(self, revision_id=None):
1058
 
        """Return a dictionary containing the revision graph.
1059
 
 
1060
 
        :param revision_id: The revision_id to get a graph from. If None, then
1061
 
        the entire revision graph is returned. This is a deprecated mode of
1062
 
        operation and will be removed in the future.
1063
 
        :return: a dictionary of revision_id->revision_parents_list.
1064
 
        """
1065
 
        # special case NULL_REVISION
1066
 
        if revision_id == _mod_revision.NULL_REVISION:
1067
 
            return {}
1068
 
        a_weave = self._get_revision_vf()
1069
 
        entire_graph = a_weave.get_graph()
1070
 
        if revision_id is None:
1071
 
            return a_weave.get_graph()
1072
 
        elif revision_id not in a_weave:
1073
 
            raise errors.NoSuchRevision(self, revision_id)
1074
 
        else:
1075
 
            # add what can be reached from revision_id
1076
 
            result = {}
1077
 
            pending = set([revision_id])
1078
 
            while len(pending) > 0:
1079
 
                node = pending.pop()
1080
 
                result[node] = a_weave.get_parents(node)
1081
 
                for revision_id in result[node]:
1082
 
                    if revision_id not in result:
1083
 
                        pending.add(revision_id)
1084
 
            return result
1085
 
 
1086
 
    @needs_read_lock
1087
 
    def get_revision_graph_with_ghosts(self, revision_ids=None):
1088
 
        """Return a graph of the revisions with ghosts marked as applicable.
1089
 
 
1090
 
        :param revision_ids: an iterable of revisions to graph or None for all.
1091
 
        :return: a Graph object with the graph reachable from revision_ids.
1092
 
        """
1093
 
        result = graph.Graph()
1094
 
        vf = self._get_revision_vf()
1095
 
        versions = set(vf.versions())
1096
 
        if not revision_ids:
1097
 
            pending = set(self.all_revision_ids())
1098
 
            required = set([])
1099
 
        else:
1100
 
            pending = set(revision_ids)
1101
 
            # special case NULL_REVISION
1102
 
            if _mod_revision.NULL_REVISION in pending:
1103
 
                pending.remove(_mod_revision.NULL_REVISION)
1104
 
            required = set(pending)
1105
 
        done = set([])
1106
 
        while len(pending):
1107
 
            revision_id = pending.pop()
1108
 
            if not revision_id in versions:
1109
 
                if revision_id in required:
1110
 
                    raise errors.NoSuchRevision(self, revision_id)
1111
 
                # a ghost
1112
 
                result.add_ghost(revision_id)
1113
 
                # mark it as done so we don't try for it again.
1114
 
                done.add(revision_id)
1115
 
                continue
1116
 
            parent_ids = vf.get_parents_with_ghosts(revision_id)
1117
 
            for parent_id in parent_ids:
1118
 
                # is this queued or done ?
1119
 
                if (parent_id not in pending and
1120
 
                    parent_id not in done):
1121
 
                    # no, queue it.
1122
 
                    pending.add(parent_id)
1123
 
            result.add_node(revision_id, parent_ids)
1124
 
            done.add(revision_id)
1125
 
        return result
1126
 
 
1127
 
    def _get_revision_vf(self):
1128
 
        """:return: a versioned file containing the revisions."""
1129
 
        vf = self._revision_store.get_revision_file(self.get_transaction())
1130
 
        return vf
1131
 
 
1132
 
    @needs_write_lock
1133
 
    def reconcile(self, other=None, thorough=False):
1134
 
        """Reconcile this repository."""
1135
 
        from bzrlib.reconcile import KnitReconciler
1136
 
        reconciler = KnitReconciler(self, thorough=thorough)
1137
 
        reconciler.reconcile()
1138
 
        return reconciler
1139
 
    
1140
 
    def revision_parents(self, revision_id):
1141
 
        return self._get_revision_vf().get_parents(revision_id)
1142
 
 
1143
 
 
1144
 
class KnitRepository2(KnitRepository):
1145
 
    """"""
1146
 
    def __init__(self, _format, a_bzrdir, control_files, _revision_store,
1147
 
                 control_store, text_store):
1148
 
        KnitRepository.__init__(self, _format, a_bzrdir, control_files,
1149
 
                              _revision_store, control_store, text_store)
1150
 
        self._serializer = xml6.serializer_v6
1151
 
 
1152
 
    def deserialise_inventory(self, revision_id, xml):
1153
 
        """Transform the xml into an inventory object. 
1154
 
 
1155
 
        :param revision_id: The expected revision id of the inventory.
1156
 
        :param xml: A serialised inventory.
1157
 
        """
1158
 
        result = self._serializer.read_inventory_from_string(xml)
1159
 
        assert result.root.revision is not None
1160
 
        return result
1161
 
 
1162
 
    def serialise_inventory(self, inv):
1163
 
        """Transform the inventory object into XML text.
1164
 
 
1165
 
        :param revision_id: The expected revision id of the inventory.
1166
 
        :param xml: A serialised inventory.
1167
 
        """
1168
 
        assert inv.revision_id is not None
1169
 
        assert inv.root.revision is not None
1170
 
        return KnitRepository.serialise_inventory(self, inv)
1171
 
 
1172
 
    def get_commit_builder(self, branch, parents, config, timestamp=None, 
1173
 
                           timezone=None, committer=None, revprops=None, 
1174
 
                           revision_id=None):
1175
 
        """Obtain a CommitBuilder for this repository.
1176
 
        
1177
 
        :param branch: Branch to commit to.
1178
 
        :param parents: Revision ids of the parents of the new revision.
1179
 
        :param config: Configuration to use.
1180
 
        :param timestamp: Optional timestamp recorded for commit.
1181
 
        :param timezone: Optional timezone for timestamp.
1182
 
        :param committer: Optional committer to set for commit.
1183
 
        :param revprops: Optional dictionary of revision properties.
1184
 
        :param revision_id: Optional revision id.
1185
 
        """
1186
 
        return RootCommitBuilder(self, parents, config, timestamp, timezone,
1187
 
                                 committer, revprops, revision_id)
1188
 
 
1189
 
 
1190
 
class KnitRepository3(KnitRepository2):
1191
 
 
1192
 
    def __init__(self, _format, a_bzrdir, control_files, _revision_store,
1193
 
                 control_store, text_store):
1194
 
        KnitRepository2.__init__(self, _format, a_bzrdir, control_files,
1195
 
                                 _revision_store, control_store, text_store)
1196
 
        self._serializer = xml7.serializer_v7
1197
 
 
1198
 
 
1199
971
class RepositoryFormatRegistry(registry.Registry):
1200
972
    """Registry of RepositoryFormats.
1201
973
    """
 
974
 
 
975
    def get(self, format_string):
 
976
        r = registry.Registry.get(self, format_string)
 
977
        if callable(r):
 
978
            r = r()
 
979
        return r
1202
980
    
1203
981
 
1204
982
format_registry = RepositoryFormatRegistry()
1205
 
"""Registry of formats, indexed by their identifying format string."""
 
983
"""Registry of formats, indexed by their identifying format string.
 
984
 
 
985
This can contain either format instances themselves, or classes/factories that
 
986
can be called to obtain one.
 
987
"""
1206
988
 
1207
989
 
1208
990
class RepositoryFormat(object):
1232
1014
    def __str__(self):
1233
1015
        return "<%s>" % self.__class__.__name__
1234
1016
 
 
1017
    def __eq__(self, other):
 
1018
        # format objects are generally stateless
 
1019
        return isinstance(other, self.__class__)
 
1020
 
 
1021
    def __neq__(self, other):
 
1022
        return not self == other
 
1023
 
1235
1024
    @classmethod
1236
1025
    def find_format(klass, a_bzrdir):
1237
1026
        """Return the format for the repository object in a_bzrdir.
1306
1095
        _revision_store = TextRevisionStore(text_store, serializer)
1307
1096
        return _revision_store
1308
1097
 
 
1098
    # TODO: this shouldn't be in the base class, it's specific to things that
 
1099
    # use weaves or knits -- mbp 20070207
1309
1100
    def _get_versioned_file_store(self,
1310
1101
                                  name,
1311
1102
                                  transport,
1312
1103
                                  control_files,
1313
1104
                                  prefixed=True,
1314
 
                                  versionedfile_class=weave.WeaveFile,
 
1105
                                  versionedfile_class=None,
1315
1106
                                  versionedfile_kwargs={},
1316
1107
                                  escaped=False):
 
1108
        if versionedfile_class is None:
 
1109
            versionedfile_class = self._versionedfile_class
1317
1110
        weave_transport = control_files._transport.clone(name)
1318
1111
        dir_mode = control_files._dir_mode
1319
1112
        file_mode = control_files._file_mode
1354
1147
        raise NotImplementedError(self.open)
1355
1148
 
1356
1149
 
1357
 
class PreSplitOutRepositoryFormat(RepositoryFormat):
1358
 
    """Base class for the pre split out repository formats."""
1359
 
 
1360
 
    rich_root_data = False
1361
 
 
1362
 
    def initialize(self, a_bzrdir, shared=False, _internal=False):
1363
 
        """Create a weave repository.
1364
 
        
1365
 
        TODO: when creating split out bzr branch formats, move this to a common
1366
 
        base for Format5, Format6. or something like that.
1367
 
        """
1368
 
        if shared:
1369
 
            raise errors.IncompatibleFormat(self, a_bzrdir._format)
1370
 
 
1371
 
        if not _internal:
1372
 
            # always initialized when the bzrdir is.
1373
 
            return self.open(a_bzrdir, _found=True)
1374
 
        
1375
 
        # Create an empty weave
1376
 
        sio = StringIO()
1377
 
        weavefile.write_weave_v5(weave.Weave(), sio)
1378
 
        empty_weave = sio.getvalue()
1379
 
 
1380
 
        mutter('creating repository in %s.', a_bzrdir.transport.base)
1381
 
        dirs = ['revision-store', 'weaves']
1382
 
        files = [('inventory.weave', StringIO(empty_weave)),
1383
 
                 ]
1384
 
        
1385
 
        # FIXME: RBC 20060125 don't peek under the covers
1386
 
        # NB: no need to escape relative paths that are url safe.
1387
 
        control_files = lockable_files.LockableFiles(a_bzrdir.transport,
1388
 
                                'branch-lock', lockable_files.TransportLock)
1389
 
        control_files.create_lock()
1390
 
        control_files.lock_write()
1391
 
        control_files._transport.mkdir_multi(dirs,
1392
 
                mode=control_files._dir_mode)
1393
 
        try:
1394
 
            for file, content in files:
1395
 
                control_files.put(file, content)
1396
 
        finally:
1397
 
            control_files.unlock()
1398
 
        return self.open(a_bzrdir, _found=True)
1399
 
 
1400
 
    def _get_control_store(self, repo_transport, control_files):
1401
 
        """Return the control store for this repository."""
1402
 
        return self._get_versioned_file_store('',
1403
 
                                              repo_transport,
1404
 
                                              control_files,
1405
 
                                              prefixed=False)
1406
 
 
1407
 
    def _get_text_store(self, transport, control_files):
1408
 
        """Get a store for file texts for this format."""
1409
 
        raise NotImplementedError(self._get_text_store)
1410
 
 
1411
 
    def open(self, a_bzrdir, _found=False):
1412
 
        """See RepositoryFormat.open()."""
1413
 
        if not _found:
1414
 
            # we are being called directly and must probe.
1415
 
            raise NotImplementedError
1416
 
 
1417
 
        repo_transport = a_bzrdir.get_repository_transport(None)
1418
 
        control_files = a_bzrdir._control_files
1419
 
        text_store = self._get_text_store(repo_transport, control_files)
1420
 
        control_store = self._get_control_store(repo_transport, control_files)
1421
 
        _revision_store = self._get_revision_store(repo_transport, control_files)
1422
 
        return AllInOneRepository(_format=self,
1423
 
                                  a_bzrdir=a_bzrdir,
1424
 
                                  _revision_store=_revision_store,
1425
 
                                  control_store=control_store,
1426
 
                                  text_store=text_store)
1427
 
 
1428
 
    def check_conversion_target(self, target_format):
1429
 
        pass
1430
 
 
1431
 
 
1432
 
class RepositoryFormat4(PreSplitOutRepositoryFormat):
1433
 
    """Bzr repository format 4.
1434
 
 
1435
 
    This repository format has:
1436
 
     - flat stores
1437
 
     - TextStores for texts, inventories,revisions.
1438
 
 
1439
 
    This format is deprecated: it indexes texts using a text id which is
1440
 
    removed in format 5; initialization and write support for this format
1441
 
    has been removed.
1442
 
    """
1443
 
 
1444
 
    def __init__(self):
1445
 
        super(RepositoryFormat4, self).__init__()
1446
 
        self._matchingbzrdir = bzrdir.BzrDirFormat4()
1447
 
 
1448
 
    def get_format_description(self):
1449
 
        """See RepositoryFormat.get_format_description()."""
1450
 
        return "Repository format 4"
1451
 
 
1452
 
    def initialize(self, url, shared=False, _internal=False):
1453
 
        """Format 4 branches cannot be created."""
1454
 
        raise errors.UninitializableFormat(self)
1455
 
 
1456
 
    def is_supported(self):
1457
 
        """Format 4 is not supported.
1458
 
 
1459
 
        It is not supported because the model changed from 4 to 5 and the
1460
 
        conversion logic is expensive - so doing it on the fly was not 
1461
 
        feasible.
1462
 
        """
1463
 
        return False
1464
 
 
1465
 
    def _get_control_store(self, repo_transport, control_files):
1466
 
        """Format 4 repositories have no formal control store at this point.
1467
 
        
1468
 
        This will cause any control-file-needing apis to fail - this is desired.
1469
 
        """
1470
 
        return None
1471
 
    
1472
 
    def _get_revision_store(self, repo_transport, control_files):
1473
 
        """See RepositoryFormat._get_revision_store()."""
1474
 
        from bzrlib.xml4 import serializer_v4
1475
 
        return self._get_text_rev_store(repo_transport,
1476
 
                                        control_files,
1477
 
                                        'revision-store',
1478
 
                                        serializer=serializer_v4)
1479
 
 
1480
 
    def _get_text_store(self, transport, control_files):
1481
 
        """See RepositoryFormat._get_text_store()."""
1482
 
 
1483
 
class RepositoryFormat5(PreSplitOutRepositoryFormat):
1484
 
    """Bzr control format 5.
1485
 
 
1486
 
    This repository format has:
1487
 
     - weaves for file texts and inventory
1488
 
     - flat stores
1489
 
     - TextStores for revisions and signatures.
1490
 
    """
1491
 
 
1492
 
    def __init__(self):
1493
 
        super(RepositoryFormat5, self).__init__()
1494
 
        self._matchingbzrdir = bzrdir.BzrDirFormat5()
1495
 
 
1496
 
    def get_format_description(self):
1497
 
        """See RepositoryFormat.get_format_description()."""
1498
 
        return "Weave repository format 5"
1499
 
 
1500
 
    def _get_revision_store(self, repo_transport, control_files):
1501
 
        """See RepositoryFormat._get_revision_store()."""
1502
 
        """Return the revision store object for this a_bzrdir."""
1503
 
        return self._get_text_rev_store(repo_transport,
1504
 
                                        control_files,
1505
 
                                        'revision-store',
1506
 
                                        compressed=False)
1507
 
 
1508
 
    def _get_text_store(self, transport, control_files):
1509
 
        """See RepositoryFormat._get_text_store()."""
1510
 
        return self._get_versioned_file_store('weaves', transport, control_files, prefixed=False)
1511
 
 
1512
 
 
1513
 
class RepositoryFormat6(PreSplitOutRepositoryFormat):
1514
 
    """Bzr control format 6.
1515
 
 
1516
 
    This repository format has:
1517
 
     - weaves for file texts and inventory
1518
 
     - hash subdirectory based stores.
1519
 
     - TextStores for revisions and signatures.
1520
 
    """
1521
 
 
1522
 
    def __init__(self):
1523
 
        super(RepositoryFormat6, self).__init__()
1524
 
        self._matchingbzrdir = bzrdir.BzrDirFormat6()
1525
 
 
1526
 
    def get_format_description(self):
1527
 
        """See RepositoryFormat.get_format_description()."""
1528
 
        return "Weave repository format 6"
1529
 
 
1530
 
    def _get_revision_store(self, repo_transport, control_files):
1531
 
        """See RepositoryFormat._get_revision_store()."""
1532
 
        return self._get_text_rev_store(repo_transport,
1533
 
                                        control_files,
1534
 
                                        'revision-store',
1535
 
                                        compressed=False,
1536
 
                                        prefixed=True)
1537
 
 
1538
 
    def _get_text_store(self, transport, control_files):
1539
 
        """See RepositoryFormat._get_text_store()."""
1540
 
        return self._get_versioned_file_store('weaves', transport, control_files)
1541
 
 
1542
 
 
1543
1150
class MetaDirRepositoryFormat(RepositoryFormat):
1544
1151
    """Common base class for the new repositories using the metadir layout."""
1545
1152
 
1546
1153
    rich_root_data = False
 
1154
    _matchingbzrdir = bzrdir.BzrDirMetaFormat1()
1547
1155
 
1548
1156
    def __init__(self):
1549
1157
        super(MetaDirRepositoryFormat, self).__init__()
1550
 
        self._matchingbzrdir = bzrdir.BzrDirMetaFormat1()
1551
1158
 
1552
1159
    def _create_control_files(self, a_bzrdir):
1553
1160
        """Create the required files and the initial control_files object."""
1576
1183
            control_files.unlock()
1577
1184
 
1578
1185
 
1579
 
class RepositoryFormat7(MetaDirRepositoryFormat):
1580
 
    """Bzr repository 7.
1581
 
 
1582
 
    This repository format has:
1583
 
     - weaves for file texts and inventory
1584
 
     - hash subdirectory based stores.
1585
 
     - TextStores for revisions and signatures.
1586
 
     - a format marker of its own
1587
 
     - an optional 'shared-storage' flag
1588
 
     - an optional 'no-working-trees' flag
1589
 
    """
1590
 
 
1591
 
    def _get_control_store(self, repo_transport, control_files):
1592
 
        """Return the control store for this repository."""
1593
 
        return self._get_versioned_file_store('',
1594
 
                                              repo_transport,
1595
 
                                              control_files,
1596
 
                                              prefixed=False)
1597
 
 
1598
 
    def get_format_string(self):
1599
 
        """See RepositoryFormat.get_format_string()."""
1600
 
        return "Bazaar-NG Repository format 7"
1601
 
 
1602
 
    def get_format_description(self):
1603
 
        """See RepositoryFormat.get_format_description()."""
1604
 
        return "Weave repository format 7"
1605
 
 
1606
 
    def check_conversion_target(self, target_format):
1607
 
        pass
1608
 
 
1609
 
    def _get_revision_store(self, repo_transport, control_files):
1610
 
        """See RepositoryFormat._get_revision_store()."""
1611
 
        return self._get_text_rev_store(repo_transport,
1612
 
                                        control_files,
1613
 
                                        'revision-store',
1614
 
                                        compressed=False,
1615
 
                                        prefixed=True,
1616
 
                                        )
1617
 
 
1618
 
    def _get_text_store(self, transport, control_files):
1619
 
        """See RepositoryFormat._get_text_store()."""
1620
 
        return self._get_versioned_file_store('weaves',
1621
 
                                              transport,
1622
 
                                              control_files)
1623
 
 
1624
 
    def initialize(self, a_bzrdir, shared=False):
1625
 
        """Create a weave repository.
1626
 
 
1627
 
        :param shared: If true the repository will be initialized as a shared
1628
 
                       repository.
1629
 
        """
1630
 
        # Create an empty weave
1631
 
        sio = StringIO()
1632
 
        weavefile.write_weave_v5(weave.Weave(), sio)
1633
 
        empty_weave = sio.getvalue()
1634
 
 
1635
 
        mutter('creating repository in %s.', a_bzrdir.transport.base)
1636
 
        dirs = ['revision-store', 'weaves']
1637
 
        files = [('inventory.weave', StringIO(empty_weave)), 
1638
 
                 ]
1639
 
        utf8_files = [('format', self.get_format_string())]
1640
 
 
1641
 
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
1642
 
        return self.open(a_bzrdir=a_bzrdir, _found=True)
1643
 
 
1644
 
    def open(self, a_bzrdir, _found=False, _override_transport=None):
1645
 
        """See RepositoryFormat.open().
1646
 
        
1647
 
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
1648
 
                                    repository at a slightly different url
1649
 
                                    than normal. I.e. during 'upgrade'.
1650
 
        """
1651
 
        if not _found:
1652
 
            format = RepositoryFormat.find_format(a_bzrdir)
1653
 
            assert format.__class__ ==  self.__class__
1654
 
        if _override_transport is not None:
1655
 
            repo_transport = _override_transport
1656
 
        else:
1657
 
            repo_transport = a_bzrdir.get_repository_transport(None)
1658
 
        control_files = lockable_files.LockableFiles(repo_transport,
1659
 
                                'lock', lockdir.LockDir)
1660
 
        text_store = self._get_text_store(repo_transport, control_files)
1661
 
        control_store = self._get_control_store(repo_transport, control_files)
1662
 
        _revision_store = self._get_revision_store(repo_transport, control_files)
1663
 
        return WeaveMetaDirRepository(_format=self,
1664
 
            a_bzrdir=a_bzrdir,
1665
 
            control_files=control_files,
1666
 
            _revision_store=_revision_store,
1667
 
            control_store=control_store,
1668
 
            text_store=text_store)
1669
 
 
1670
 
 
1671
 
class RepositoryFormatKnit(MetaDirRepositoryFormat):
1672
 
    """Bzr repository knit format (generalized). 
1673
 
 
1674
 
    This repository format has:
1675
 
     - knits for file texts and inventory
1676
 
     - hash subdirectory based stores.
1677
 
     - knits for revisions and signatures
1678
 
     - TextStores for revisions and signatures.
1679
 
     - a format marker of its own
1680
 
     - an optional 'shared-storage' flag
1681
 
     - an optional 'no-working-trees' flag
1682
 
     - a LockDir lock
1683
 
    """
1684
 
 
1685
 
    def _get_control_store(self, repo_transport, control_files):
1686
 
        """Return the control store for this repository."""
1687
 
        return VersionedFileStore(
1688
 
            repo_transport,
1689
 
            prefixed=False,
1690
 
            file_mode=control_files._file_mode,
1691
 
            versionedfile_class=knit.KnitVersionedFile,
1692
 
            versionedfile_kwargs={'factory':knit.KnitPlainFactory()},
1693
 
            )
1694
 
 
1695
 
    def _get_revision_store(self, repo_transport, control_files):
1696
 
        """See RepositoryFormat._get_revision_store()."""
1697
 
        from bzrlib.store.revision.knit import KnitRevisionStore
1698
 
        versioned_file_store = VersionedFileStore(
1699
 
            repo_transport,
1700
 
            file_mode=control_files._file_mode,
1701
 
            prefixed=False,
1702
 
            precious=True,
1703
 
            versionedfile_class=knit.KnitVersionedFile,
1704
 
            versionedfile_kwargs={'delta':False,
1705
 
                                  'factory':knit.KnitPlainFactory(),
1706
 
                                 },
1707
 
            escaped=True,
1708
 
            )
1709
 
        return KnitRevisionStore(versioned_file_store)
1710
 
 
1711
 
    def _get_text_store(self, transport, control_files):
1712
 
        """See RepositoryFormat._get_text_store()."""
1713
 
        return self._get_versioned_file_store('knits',
1714
 
                                  transport,
1715
 
                                  control_files,
1716
 
                                  versionedfile_class=knit.KnitVersionedFile,
1717
 
                                  versionedfile_kwargs={
1718
 
                                      'create_parent_dir':True,
1719
 
                                      'delay_create':True,
1720
 
                                      'dir_mode':control_files._dir_mode,
1721
 
                                  },
1722
 
                                  escaped=True)
1723
 
 
1724
 
    def initialize(self, a_bzrdir, shared=False):
1725
 
        """Create a knit format 1 repository.
1726
 
 
1727
 
        :param a_bzrdir: bzrdir to contain the new repository; must already
1728
 
            be initialized.
1729
 
        :param shared: If true the repository will be initialized as a shared
1730
 
                       repository.
1731
 
        """
1732
 
        mutter('creating repository in %s.', a_bzrdir.transport.base)
1733
 
        dirs = ['revision-store', 'knits']
1734
 
        files = []
1735
 
        utf8_files = [('format', self.get_format_string())]
1736
 
        
1737
 
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
1738
 
        repo_transport = a_bzrdir.get_repository_transport(None)
1739
 
        control_files = lockable_files.LockableFiles(repo_transport,
1740
 
                                'lock', lockdir.LockDir)
1741
 
        control_store = self._get_control_store(repo_transport, control_files)
1742
 
        transaction = transactions.WriteTransaction()
1743
 
        # trigger a write of the inventory store.
1744
 
        control_store.get_weave_or_empty('inventory', transaction)
1745
 
        _revision_store = self._get_revision_store(repo_transport, control_files)
1746
 
        # the revision id here is irrelevant: it will not be stored, and cannot
1747
 
        # already exist.
1748
 
        _revision_store.has_revision_id('A', transaction)
1749
 
        _revision_store.get_signature_file(transaction)
1750
 
        return self.open(a_bzrdir=a_bzrdir, _found=True)
1751
 
 
1752
 
    def open(self, a_bzrdir, _found=False, _override_transport=None):
1753
 
        """See RepositoryFormat.open().
1754
 
        
1755
 
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
1756
 
                                    repository at a slightly different url
1757
 
                                    than normal. I.e. during 'upgrade'.
1758
 
        """
1759
 
        if not _found:
1760
 
            format = RepositoryFormat.find_format(a_bzrdir)
1761
 
            assert format.__class__ ==  self.__class__
1762
 
        if _override_transport is not None:
1763
 
            repo_transport = _override_transport
1764
 
        else:
1765
 
            repo_transport = a_bzrdir.get_repository_transport(None)
1766
 
        control_files = lockable_files.LockableFiles(repo_transport,
1767
 
                                'lock', lockdir.LockDir)
1768
 
        text_store = self._get_text_store(repo_transport, control_files)
1769
 
        control_store = self._get_control_store(repo_transport, control_files)
1770
 
        _revision_store = self._get_revision_store(repo_transport, control_files)
1771
 
        return KnitRepository(_format=self,
1772
 
                              a_bzrdir=a_bzrdir,
1773
 
                              control_files=control_files,
1774
 
                              _revision_store=_revision_store,
1775
 
                              control_store=control_store,
1776
 
                              text_store=text_store)
1777
 
 
1778
 
 
1779
 
class RepositoryFormatKnit1(RepositoryFormatKnit):
1780
 
    """Bzr repository knit format 1.
1781
 
 
1782
 
    This repository format has:
1783
 
     - knits for file texts and inventory
1784
 
     - hash subdirectory based stores.
1785
 
     - knits for revisions and signatures
1786
 
     - TextStores for revisions and signatures.
1787
 
     - a format marker of its own
1788
 
     - an optional 'shared-storage' flag
1789
 
     - an optional 'no-working-trees' flag
1790
 
     - a LockDir lock
1791
 
 
1792
 
    This format was introduced in bzr 0.8.
1793
 
    """
1794
 
    def get_format_string(self):
1795
 
        """See RepositoryFormat.get_format_string()."""
1796
 
        return "Bazaar-NG Knit Repository Format 1"
1797
 
 
1798
 
    def get_format_description(self):
1799
 
        """See RepositoryFormat.get_format_description()."""
1800
 
        return "Knit repository format 1"
1801
 
 
1802
 
    def check_conversion_target(self, target_format):
1803
 
        pass
1804
 
 
1805
 
 
1806
 
class RepositoryFormatKnit2(RepositoryFormatKnit):
1807
 
    """Bzr repository knit format 2.
1808
 
 
1809
 
    THIS FORMAT IS EXPERIMENTAL
1810
 
    This repository format has:
1811
 
     - knits for file texts and inventory
1812
 
     - hash subdirectory based stores.
1813
 
     - knits for revisions and signatures
1814
 
     - TextStores for revisions and signatures.
1815
 
     - a format marker of its own
1816
 
     - an optional 'shared-storage' flag
1817
 
     - an optional 'no-working-trees' flag
1818
 
     - a LockDir lock
1819
 
     - Support for recording full info about the tree root
1820
 
 
1821
 
    """
1822
 
    
1823
 
    rich_root_data = True
1824
 
    repository_class = KnitRepository2
1825
 
 
1826
 
    def get_format_string(self):
1827
 
        """See RepositoryFormat.get_format_string()."""
1828
 
        return "Bazaar Knit Repository Format 2\n"
1829
 
 
1830
 
    def get_format_description(self):
1831
 
        """See RepositoryFormat.get_format_description()."""
1832
 
        return "Knit repository format 2"
1833
 
 
1834
 
    def check_conversion_target(self, target_format):
1835
 
        if not target_format.rich_root_data:
1836
 
            raise errors.BadConversionTarget(
1837
 
                'Does not support rich root data.', target_format)
1838
 
 
1839
 
    def open(self, a_bzrdir, _found=False, _override_transport=None):
1840
 
        """See RepositoryFormat.open().
1841
 
        
1842
 
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
1843
 
                                    repository at a slightly different url
1844
 
                                    than normal. I.e. during 'upgrade'.
1845
 
        """
1846
 
        if not _found:
1847
 
            format = RepositoryFormat.find_format(a_bzrdir)
1848
 
            assert format.__class__ ==  self.__class__
1849
 
        if _override_transport is not None:
1850
 
            repo_transport = _override_transport
1851
 
        else:
1852
 
            repo_transport = a_bzrdir.get_repository_transport(None)
1853
 
        control_files = lockable_files.LockableFiles(repo_transport, 'lock',
1854
 
                                                     lockdir.LockDir)
1855
 
        text_store = self._get_text_store(repo_transport, control_files)
1856
 
        control_store = self._get_control_store(repo_transport, control_files)
1857
 
        _revision_store = self._get_revision_store(repo_transport, control_files)
1858
 
        return self.repository_class(_format=self,
1859
 
                                     a_bzrdir=a_bzrdir,
1860
 
                                     control_files=control_files,
1861
 
                                     _revision_store=_revision_store,
1862
 
                                     control_store=control_store,
1863
 
                                     text_store=text_store)
1864
 
 
1865
 
 
1866
 
class RepositoryFormatKnit3(RepositoryFormatKnit2):
1867
 
    """Bzr repository knit format 2.
1868
 
 
1869
 
    THIS FORMAT IS EXPERIMENTAL
1870
 
    This repository format has:
1871
 
     - knits for file texts and inventory
1872
 
     - hash subdirectory based stores.
1873
 
     - knits for revisions and signatures
1874
 
     - TextStores for revisions and signatures.
1875
 
     - a format marker of its own
1876
 
     - an optional 'shared-storage' flag
1877
 
     - an optional 'no-working-trees' flag
1878
 
     - a LockDir lock
1879
 
     - support for recording full info about the tree root
1880
 
     - support for recording tree-references
1881
 
    """
1882
 
 
1883
 
    repository_class = KnitRepository3
1884
 
    support_tree_reference = True
1885
 
 
1886
 
    def _get_matching_bzrdir(self):
1887
 
        return bzrdir.format_registry.make_bzrdir('experimental-knit3')
1888
 
 
1889
 
    def _ignore_setting_bzrdir(self, format):
1890
 
        pass
1891
 
 
1892
 
    _matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
1893
 
 
1894
 
    def check_conversion_target(self, target_format):
1895
 
        RepositoryFormatKnit2.check_conversion_target(self, target_format)
1896
 
        if not getattr(target_format, 'support_tree_reference', False):
1897
 
            raise errors.BadConversionTarget(
1898
 
                'Does not support nested trees', target_format)
1899
 
            
1900
 
 
1901
 
    def get_format_string(self):
1902
 
        """See RepositoryFormat.get_format_string()."""
1903
 
        return "Bazaar Knit Repository Format 3\n"
1904
 
 
1905
 
    def get_format_description(self):
1906
 
        """See RepositoryFormat.get_format_description()."""
1907
 
        return "Knit repository format 3"
1908
 
 
1909
1186
# formats which have no format string are not discoverable
1910
 
# and not independently creatable, so are not registered.
1911
 
RepositoryFormat.register_format(RepositoryFormat7())
1912
 
# KEEP in sync with bzrdir.format_registry default
1913
 
RepositoryFormat.register_format(RepositoryFormatKnit1())
1914
 
RepositoryFormat.register_format(RepositoryFormatKnit2())
1915
 
RepositoryFormat.register_format(RepositoryFormatKnit3())
1916
 
_legacy_formats = [RepositoryFormat4(),
1917
 
                   RepositoryFormat5(),
1918
 
                   RepositoryFormat6()]
 
1187
# and not independently creatable, so are not registered.  They're 
 
1188
# all in bzrlib.repofmt.weaverepo now.  When an instance of one of these is
 
1189
# needed, it's constructed directly by the BzrDir.  Non-native formats where
 
1190
# the repository is not separately opened are similar.
 
1191
 
 
1192
format_registry.register_lazy(
 
1193
    'Bazaar-NG Repository format 7',
 
1194
    'bzrlib.repofmt.weaverepo',
 
1195
    'RepositoryFormat7'
 
1196
    )
 
1197
# KEEP in sync with bzrdir.format_registry default, which controls the overall
 
1198
# default control directory format
 
1199
 
 
1200
format_registry.register_lazy(
 
1201
    'Bazaar-NG Knit Repository Format 1',
 
1202
    'bzrlib.repofmt.knitrepo',
 
1203
    'RepositoryFormatKnit1',
 
1204
    )
 
1205
format_registry.default_key = 'Bazaar-NG Knit Repository Format 1'
 
1206
 
 
1207
format_registry.register_lazy(
 
1208
    'Bazaar Knit Repository Format 2\n',
 
1209
    'bzrlib.repofmt.knitrepo',
 
1210
    'RepositoryFormatKnit2',
 
1211
    )
 
1212
 
 
1213
format_registry.register_lazy(
 
1214
    'Bazaar Knit Repository Format 3\n',
 
1215
    'bzrlib.repofmt.knitrepo',
 
1216
    'RepositoryFormatKnit3',
 
1217
    )
1919
1218
 
1920
1219
 
1921
1220
class InterRepository(InterObject):
1981
1280
    Data format and model must match for this to work.
1982
1281
    """
1983
1282
 
1984
 
    _matching_repo_format = RepositoryFormat4()
1985
 
    """Repository format for testing with."""
 
1283
    @classmethod
 
1284
    def _get_repo_format_to_test(self):
 
1285
        """Repository format for testing with."""
 
1286
        return RepositoryFormat.get_default_format()
1986
1287
 
1987
1288
    @staticmethod
1988
1289
    def is_compatible(source, target):
2038
1339
class InterWeaveRepo(InterSameDataRepository):
2039
1340
    """Optimised code paths between Weave based repositories."""
2040
1341
 
2041
 
    _matching_repo_format = RepositoryFormat7()
2042
 
    """Repository format for testing with."""
 
1342
    @classmethod
 
1343
    def _get_repo_format_to_test(self):
 
1344
        from bzrlib.repofmt import weaverepo
 
1345
        return weaverepo.RepositoryFormat7()
2043
1346
 
2044
1347
    @staticmethod
2045
1348
    def is_compatible(source, target):
2049
1352
        could lead to confusing results, and there is no need to be 
2050
1353
        overly general.
2051
1354
        """
 
1355
        from bzrlib.repofmt.weaverepo import (
 
1356
                RepositoryFormat5,
 
1357
                RepositoryFormat6,
 
1358
                RepositoryFormat7,
 
1359
                )
2052
1360
        try:
2053
1361
            return (isinstance(source._format, (RepositoryFormat5,
2054
1362
                                                RepositoryFormat6,
2156
1464
class InterKnitRepo(InterSameDataRepository):
2157
1465
    """Optimised code paths between Knit based repositories."""
2158
1466
 
2159
 
    _matching_repo_format = RepositoryFormatKnit1()
2160
 
    """Repository format for testing with."""
 
1467
    @classmethod
 
1468
    def _get_repo_format_to_test(self):
 
1469
        from bzrlib.repofmt import knitrepo
 
1470
        return knitrepo.RepositoryFormatKnit1()
2161
1471
 
2162
1472
    @staticmethod
2163
1473
    def is_compatible(source, target):
2167
1477
        could lead to confusing results, and there is no need to be 
2168
1478
        overly general.
2169
1479
        """
 
1480
        from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
2170
1481
        try:
2171
1482
            return (isinstance(source._format, (RepositoryFormatKnit1)) and
2172
1483
                    isinstance(target._format, (RepositoryFormatKnit1)))
2218
1529
 
2219
1530
class InterModel1and2(InterRepository):
2220
1531
 
2221
 
    _matching_repo_format = None
 
1532
    @classmethod
 
1533
    def _get_repo_format_to_test(self):
 
1534
        return None
2222
1535
 
2223
1536
    @staticmethod
2224
1537
    def is_compatible(source, target):
2268
1581
 
2269
1582
class InterKnit1and2(InterKnitRepo):
2270
1583
 
2271
 
    _matching_repo_format = None
 
1584
    @classmethod
 
1585
    def _get_repo_format_to_test(self):
 
1586
        return None
2272
1587
 
2273
1588
    @staticmethod
2274
1589
    def is_compatible(source, target):
2275
1590
        """Be compatible with Knit1 source and Knit2 target"""
 
1591
        from bzrlib.repofmt.knitrepo import RepositoryFormatKnit2
2276
1592
        try:
 
1593
            from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1, \
 
1594
                    RepositoryFormatKnit2
2277
1595
            return (isinstance(source._format, (RepositoryFormatKnit1)) and
2278
1596
                    isinstance(target._format, (RepositoryFormatKnit2)))
2279
1597
        except AttributeError:
2317
1635
    def adapt(self, test):
2318
1636
        result = unittest.TestSuite()
2319
1637
        for repository_format, bzrdir_format in self._formats:
 
1638
            from copy import deepcopy
2320
1639
            new_test = deepcopy(test)
2321
1640
            new_test.transport_server = self._transport_server
2322
1641
            new_test.transport_readonly_server = self._transport_readonly_server
2347
1666
    def adapt(self, test):
2348
1667
        result = unittest.TestSuite()
2349
1668
        for interrepo_class, repository_format, repository_format_to in self._formats:
 
1669
            from copy import deepcopy
2350
1670
            new_test = deepcopy(test)
2351
1671
            new_test.transport_server = self._transport_server
2352
1672
            new_test.transport_readonly_server = self._transport_readonly_server
2363
1683
    @staticmethod
2364
1684
    def default_test_list():
2365
1685
        """Generate the default list of interrepo permutations to test."""
 
1686
        from bzrlib.repofmt import knitrepo, weaverepo
2366
1687
        result = []
2367
1688
        # test the default InterRepository between format 6 and the current 
2368
1689
        # default format.
2371
1692
        #result.append((InterRepository,
2372
1693
        #               RepositoryFormat6(),
2373
1694
        #               RepositoryFormatKnit1()))
2374
 
        for optimiser in InterRepository._optimisers:
2375
 
            if optimiser._matching_repo_format is not None:
2376
 
                result.append((optimiser,
2377
 
                               optimiser._matching_repo_format,
2378
 
                               optimiser._matching_repo_format
2379
 
                               ))
 
1695
        for optimiser_class in InterRepository._optimisers:
 
1696
            format_to_test = optimiser_class._get_repo_format_to_test()
 
1697
            if format_to_test is not None:
 
1698
                result.append((optimiser_class,
 
1699
                               format_to_test, format_to_test))
2380
1700
        # if there are specific combinations we want to use, we can add them 
2381
1701
        # here.
2382
 
        result.append((InterModel1and2, RepositoryFormat5(),
2383
 
                       RepositoryFormatKnit2()))
2384
 
        result.append((InterKnit1and2, RepositoryFormatKnit1(),
2385
 
                       RepositoryFormatKnit2()))
 
1702
        result.append((InterModel1and2,
 
1703
                       weaverepo.RepositoryFormat5(),
 
1704
                       knitrepo.RepositoryFormatKnit2()))
 
1705
        result.append((InterKnit1and2,
 
1706
                       knitrepo.RepositoryFormatKnit1(),
 
1707
                       knitrepo.RepositoryFormatKnit2()))
2386
1708
        return result
2387
1709
 
2388
1710
 
2483
1805
        self._timestamp = round(timestamp, 3)
2484
1806
 
2485
1807
        if timezone is None:
2486
 
            self._timezone = local_time_offset()
 
1808
            self._timezone = osutils.local_time_offset()
2487
1809
        else:
2488
1810
            self._timezone = int(timezone)
2489
1811