~bzr-pqm/bzr/bzr.dev

2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
17
"""Deprecated weave-based repository formats.
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
18
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
19
Weave based formats scaled linearly with history size and could not represent
20
ghosts.
21
"""
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
22
23
from StringIO import StringIO
24
25
from bzrlib import (
26
    bzrdir,
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
27
    debug,
28
    errors,
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
29
    lockable_files,
30
    lockdir,
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
31
    osutils,
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
32
    revision as _mod_revision,
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
33
    weave,
34
    weavefile,
2241.1.8 by Martin Pool
Set the repository's serializer in the places it's needed, not in the base class
35
    xml5,
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
36
    )
37
from bzrlib.decorators import needs_read_lock, needs_write_lock
38
from bzrlib.repository import (
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
39
    CommitBuilder,
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
40
    MetaDirRepository,
41
    MetaDirRepositoryFormat,
42
    Repository,
43
    RepositoryFormat,
44
    )
45
from bzrlib.store.text import TextStore
3287.6.1 by Robert Collins
* ``VersionedFile.get_graph`` is deprecated, with no replacement method.
46
from bzrlib.symbol_versioning import deprecated_method, one_four
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
47
from bzrlib.trace import mutter
48
49
50
class AllInOneRepository(Repository):
51
    """Legacy support - the repository behaviour for all-in-one branches."""
52
2241.1.8 by Martin Pool
Set the repository's serializer in the places it's needed, not in the base class
53
    _serializer = xml5.serializer_v5
54
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
55
    def __init__(self, _format, a_bzrdir, _revision_store, control_store, text_store):
56
        # we reuse one control files instance.
57
        dir_mode = a_bzrdir._control_files._dir_mode
58
        file_mode = a_bzrdir._control_files._file_mode
59
60
        def get_store(name, compressed=True, prefixed=False):
61
            # FIXME: This approach of assuming stores are all entirely compressed
62
            # or entirely uncompressed is tidy, but breaks upgrade from 
63
            # some existing branches where there's a mixture; we probably 
64
            # still want the option to look for both.
65
            relpath = a_bzrdir._control_files._escape(name)
66
            store = TextStore(a_bzrdir._control_files._transport.clone(relpath),
67
                              prefixed=prefixed, compressed=compressed,
68
                              dir_mode=dir_mode,
69
                              file_mode=file_mode)
70
            return store
71
72
        # not broken out yet because the controlweaves|inventory_store
73
        # and text_store | weave_store bits are still different.
74
        if isinstance(_format, RepositoryFormat4):
75
            # cannot remove these - there is still no consistent api 
76
            # which allows access to this old info.
77
            self.inventory_store = get_store('inventory-store')
78
            text_store = get_store('text-store')
79
        super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files, _revision_store, control_store, text_store)
80
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
81
    @needs_read_lock
82
    def _all_possible_ids(self):
83
        """Return all the possible revisions that we could find."""
84
        if 'evil' in debug.debug_flags:
85
            mutter_callsite(3, "_all_possible_ids scales with size of history.")
86
        return self.get_inventory_weave().versions()
87
88
    @needs_read_lock
89
    def _all_revision_ids(self):
90
        """Returns a list of all the revision ids in the repository. 
91
92
        These are in as much topological order as the underlying store can 
93
        present: for weaves ghosts may lead to a lack of correctness until
94
        the reweave updates the parents list.
95
        """
96
        if self._revision_store.text_store.listable():
97
            return self._revision_store.all_revision_ids(self.get_transaction())
98
        result = self._all_possible_ids()
99
        # TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
100
        #       ids. (It should, since _revision_store's API should change to
101
        #       return utf8 revision_ids)
102
        return self._eliminate_revisions_not_present(result)
103
104
    def _check_revision_parents(self, revision, inventory):
105
        """Private to Repository and Fetch.
106
        
107
        This checks the parentage of revision in an inventory weave for 
108
        consistency and is only applicable to inventory-weave-for-ancestry
109
        using repository formats & fetchers.
110
        """
3287.5.2 by Robert Collins
Deprecate VersionedFile.get_parents, breaking pulling from a ghost containing knit or pack repository to weaves, which improves correctness and allows simplification of core code.
111
        weave_parents = inventory.get_parent_map(
112
            [revision.revision_id])[revision.revision_id]
113
        parent_map = inventory.get_parent_map(revision.parent_ids)
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
114
        for parent_id in revision.parent_ids:
3287.5.2 by Robert Collins
Deprecate VersionedFile.get_parents, breaking pulling from a ghost containing knit or pack repository to weaves, which improves correctness and allows simplification of core code.
115
            if parent_id in parent_map:
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
116
                # this parent must not be a ghost.
117
                if not parent_id in weave_parents:
118
                    # but it is a ghost
119
                    raise errors.CorruptRepository(self)
120
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
121
    def get_commit_builder(self, branch, parents, config, timestamp=None,
122
                           timezone=None, committer=None, revprops=None,
123
                           revision_id=None):
124
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
125
        result = WeaveCommitBuilder(self, parents, config, timestamp, timezone,
126
                              committer, revprops, revision_id)
127
        self.start_write_group()
128
        return result
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
129
130
    @needs_read_lock
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
131
    def get_revisions(self, revision_ids):
132
        revs = self._get_revisions(revision_ids)
133
        # weave corruption can lead to absent revision markers that should be
134
        # present.
135
        # the following test is reasonably cheap (it needs a single weave read)
136
        # and the weave is cached in read transactions. In write transactions
137
        # it is not cached but typically we only read a small number of
138
        # revisions. For knits when they are introduced we will probably want
139
        # to ensure that caching write transactions are in use.
140
        inv = self.get_inventory_weave()
141
        for rev in revs:
142
            self._check_revision_parents(rev, inv)
143
        return revs
144
3287.6.1 by Robert Collins
* ``VersionedFile.get_graph`` is deprecated, with no replacement method.
145
    @deprecated_method(one_four)
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
146
    @needs_read_lock
147
    def get_revision_graph(self, revision_id=None):
148
        """Return a dictionary containing the revision graph.
149
        
150
        :param revision_id: The revision_id to get a graph from. If None, then
151
        the entire revision graph is returned. This is a deprecated mode of
152
        operation and will be removed in the future.
153
        :return: a dictionary of revision_id->revision_parents_list.
154
        """
155
        if 'evil' in debug.debug_flags:
156
            mutter_callsite(2,
157
                "get_revision_graph scales with size of history.")
158
        # special case NULL_REVISION
159
        if revision_id == _mod_revision.NULL_REVISION:
160
            return {}
161
        a_weave = self.get_inventory_weave()
162
        all_revisions = self._eliminate_revisions_not_present(
163
                                a_weave.versions())
3287.5.2 by Robert Collins
Deprecate VersionedFile.get_parents, breaking pulling from a ghost containing knit or pack repository to weaves, which improves correctness and allows simplification of core code.
164
        entire_graph = a_weave.get_parent_map(all_revisions)
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
165
        if revision_id is None:
166
            return entire_graph
167
        elif revision_id not in entire_graph:
168
            raise errors.NoSuchRevision(self, revision_id)
169
        else:
170
            # add what can be reached from revision_id
171
            result = {}
172
            pending = set([revision_id])
173
            while len(pending) > 0:
174
                node = pending.pop()
175
                result[node] = entire_graph[node]
176
                for revision_id in result[node]:
177
                    if revision_id not in result:
178
                        pending.add(revision_id)
179
            return result
180
3172.3.1 by Robert Collins
Repository has a new method ``has_revisions`` which signals the presence
181
    def has_revisions(self, revision_ids):
182
        """See Repository.has_revisions()."""
183
        result = set()
184
        transaction = self.get_transaction()
185
        for revision_id in revision_ids:
186
            if self._revision_store.has_revision_id(revision_id, transaction):
187
                result.add(revision_id)
188
        return result
189
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
190
    @needs_read_lock
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
191
    def is_shared(self):
192
        """AllInOne repositories cannot be shared."""
193
        return False
194
195
    @needs_write_lock
196
    def set_make_working_trees(self, new_value):
197
        """Set the policy flag for making working trees when creating branches.
198
199
        This only applies to branches that use this repository.
200
201
        The default is 'True'.
202
        :param new_value: True to restore the default, False to disable making
203
                          working trees.
204
        """
205
        raise NotImplementedError(self.set_make_working_trees)
206
    
207
    def make_working_trees(self):
208
        """Returns the policy for making working trees on new branches."""
209
        return True
210
2819.2.4 by Andrew Bennetts
Add a 'revision_graph_can_have_wrong_parents' method to repository.
211
    def revision_graph_can_have_wrong_parents(self):
212
        # XXX: This is an old format that we don't support full checking on, so
213
        # just claim that checking for this inconsistency is not required.
214
        return False
215
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
216
217
class WeaveMetaDirRepository(MetaDirRepository):
218
    """A subclass of MetaDirRepository to set weave specific policy."""
219
2241.1.8 by Martin Pool
Set the repository's serializer in the places it's needed, not in the base class
220
    _serializer = xml5.serializer_v5
221
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
222
    @needs_read_lock
223
    def _all_possible_ids(self):
224
        """Return all the possible revisions that we could find."""
225
        if 'evil' in debug.debug_flags:
226
            mutter_callsite(3, "_all_possible_ids scales with size of history.")
227
        return self.get_inventory_weave().versions()
228
229
    @needs_read_lock
230
    def _all_revision_ids(self):
231
        """Returns a list of all the revision ids in the repository. 
232
233
        These are in as much topological order as the underlying store can 
234
        present: for weaves ghosts may lead to a lack of correctness until
235
        the reweave updates the parents list.
236
        """
237
        if self._revision_store.text_store.listable():
238
            return self._revision_store.all_revision_ids(self.get_transaction())
239
        result = self._all_possible_ids()
240
        # TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
241
        #       ids. (It should, since _revision_store's API should change to
242
        #       return utf8 revision_ids)
243
        return self._eliminate_revisions_not_present(result)
244
245
    def _check_revision_parents(self, revision, inventory):
246
        """Private to Repository and Fetch.
247
        
248
        This checks the parentage of revision in an inventory weave for 
249
        consistency and is only applicable to inventory-weave-for-ancestry
250
        using repository formats & fetchers.
251
        """
3287.5.2 by Robert Collins
Deprecate VersionedFile.get_parents, breaking pulling from a ghost containing knit or pack repository to weaves, which improves correctness and allows simplification of core code.
252
        weave_parents = inventory.get_parent_map(
253
            [revision.revision_id])[revision.revision_id]
254
        parent_map = inventory.get_parent_map(revision.parent_ids)
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
255
        for parent_id in revision.parent_ids:
3287.5.2 by Robert Collins
Deprecate VersionedFile.get_parents, breaking pulling from a ghost containing knit or pack repository to weaves, which improves correctness and allows simplification of core code.
256
            if parent_id in parent_map:
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
257
                # this parent must not be a ghost.
258
                if not parent_id in weave_parents:
259
                    # but it is a ghost
260
                    raise errors.CorruptRepository(self)
261
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
262
    def get_commit_builder(self, branch, parents, config, timestamp=None,
263
                           timezone=None, committer=None, revprops=None,
264
                           revision_id=None):
265
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
266
        result = WeaveCommitBuilder(self, parents, config, timestamp, timezone,
267
                              committer, revprops, revision_id)
268
        self.start_write_group()
269
        return result
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
270
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
271
    @needs_read_lock
272
    def get_revision(self, revision_id):
273
        """Return the Revision object for a named revision"""
274
        # TODO: jam 20070210 get_revision_reconcile should do this for us
275
        r = self.get_revision_reconcile(revision_id)
276
        # weave corruption can lead to absent revision markers that should be
277
        # present.
278
        # the following test is reasonably cheap (it needs a single weave read)
279
        # and the weave is cached in read transactions. In write transactions
280
        # it is not cached but typically we only read a small number of
281
        # revisions. For knits when they are introduced we will probably want
282
        # to ensure that caching write transactions are in use.
283
        inv = self.get_inventory_weave()
284
        self._check_revision_parents(r, inv)
285
        return r
286
3287.6.1 by Robert Collins
* ``VersionedFile.get_graph`` is deprecated, with no replacement method.
287
    @deprecated_method(one_four)
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
288
    @needs_read_lock
289
    def get_revision_graph(self, revision_id=None):
290
        """Return a dictionary containing the revision graph.
291
        
292
        :param revision_id: The revision_id to get a graph from. If None, then
293
        the entire revision graph is returned. This is a deprecated mode of
294
        operation and will be removed in the future.
295
        :return: a dictionary of revision_id->revision_parents_list.
296
        """
297
        if 'evil' in debug.debug_flags:
298
            mutter_callsite(3,
299
                "get_revision_graph scales with size of history.")
300
        # special case NULL_REVISION
301
        if revision_id == _mod_revision.NULL_REVISION:
302
            return {}
303
        a_weave = self.get_inventory_weave()
304
        all_revisions = self._eliminate_revisions_not_present(
305
                                a_weave.versions())
3287.5.2 by Robert Collins
Deprecate VersionedFile.get_parents, breaking pulling from a ghost containing knit or pack repository to weaves, which improves correctness and allows simplification of core code.
306
        entire_graph = a_weave.get_parent_map(all_revisions)
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
307
        if revision_id is None:
308
            return entire_graph
309
        elif revision_id not in entire_graph:
310
            raise errors.NoSuchRevision(self, revision_id)
311
        else:
312
            # add what can be reached from revision_id
313
            result = {}
314
            pending = set([revision_id])
315
            while len(pending) > 0:
316
                node = pending.pop()
317
                result[node] = entire_graph[node]
318
                for revision_id in result[node]:
319
                    if revision_id not in result:
320
                        pending.add(revision_id)
321
            return result
322
3172.3.1 by Robert Collins
Repository has a new method ``has_revisions`` which signals the presence
323
    def has_revisions(self, revision_ids):
324
        """See Repository.has_revisions()."""
325
        result = set()
326
        transaction = self.get_transaction()
327
        for revision_id in revision_ids:
328
            if self._revision_store.has_revision_id(revision_id, transaction):
329
                result.add(revision_id)
330
        return result
331
2819.2.4 by Andrew Bennetts
Add a 'revision_graph_can_have_wrong_parents' method to repository.
332
    def revision_graph_can_have_wrong_parents(self):
333
        # XXX: This is an old format that we don't support full checking on, so
334
        # just claim that checking for this inconsistency is not required.
335
        return False
336
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
337
338
class PreSplitOutRepositoryFormat(RepositoryFormat):
339
    """Base class for the pre split out repository formats."""
340
341
    rich_root_data = False
2323.5.17 by Martin Pool
Add supports_tree_reference to all repo formats (robert)
342
    supports_tree_reference = False
2949.1.2 by Robert Collins
* Fetch with pack repositories will no longer read the entire history graph.
343
    supports_ghosts = False
3221.3.1 by Robert Collins
* Repository formats have a new supported-feature attribute
344
    supports_external_lookups = False
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
345
346
    def initialize(self, a_bzrdir, shared=False, _internal=False):
2949.1.2 by Robert Collins
* Fetch with pack repositories will no longer read the entire history graph.
347
        """Create a weave repository."""
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
348
        if shared:
349
            raise errors.IncompatibleFormat(self, a_bzrdir._format)
350
351
        if not _internal:
352
            # always initialized when the bzrdir is.
353
            return self.open(a_bzrdir, _found=True)
354
        
355
        # Create an empty weave
356
        sio = StringIO()
357
        weavefile.write_weave_v5(weave.Weave(), sio)
358
        empty_weave = sio.getvalue()
359
360
        mutter('creating repository in %s.', a_bzrdir.transport.base)
361
        dirs = ['revision-store', 'weaves']
362
        files = [('inventory.weave', StringIO(empty_weave)),
363
                 ]
364
        
365
        # FIXME: RBC 20060125 don't peek under the covers
366
        # NB: no need to escape relative paths that are url safe.
367
        control_files = lockable_files.LockableFiles(a_bzrdir.transport,
368
                                'branch-lock', lockable_files.TransportLock)
369
        control_files.create_lock()
370
        control_files.lock_write()
371
        control_files._transport.mkdir_multi(dirs,
372
                mode=control_files._dir_mode)
373
        try:
374
            for file, content in files:
375
                control_files.put(file, content)
376
        finally:
377
            control_files.unlock()
378
        return self.open(a_bzrdir, _found=True)
379
380
    def _get_control_store(self, repo_transport, control_files):
381
        """Return the control store for this repository."""
382
        return self._get_versioned_file_store('',
383
                                              repo_transport,
384
                                              control_files,
385
                                              prefixed=False)
386
387
    def _get_text_store(self, transport, control_files):
388
        """Get a store for file texts for this format."""
389
        raise NotImplementedError(self._get_text_store)
390
391
    def open(self, a_bzrdir, _found=False):
392
        """See RepositoryFormat.open()."""
393
        if not _found:
394
            # we are being called directly and must probe.
395
            raise NotImplementedError
396
397
        repo_transport = a_bzrdir.get_repository_transport(None)
398
        control_files = a_bzrdir._control_files
399
        text_store = self._get_text_store(repo_transport, control_files)
400
        control_store = self._get_control_store(repo_transport, control_files)
401
        _revision_store = self._get_revision_store(repo_transport, control_files)
402
        return AllInOneRepository(_format=self,
403
                                  a_bzrdir=a_bzrdir,
404
                                  _revision_store=_revision_store,
405
                                  control_store=control_store,
406
                                  text_store=text_store)
407
408
    def check_conversion_target(self, target_format):
409
        pass
410
411
412
class RepositoryFormat4(PreSplitOutRepositoryFormat):
413
    """Bzr repository format 4.
414
415
    This repository format has:
416
     - flat stores
417
     - TextStores for texts, inventories,revisions.
418
419
    This format is deprecated: it indexes texts using a text id which is
420
    removed in format 5; initialization and write support for this format
421
    has been removed.
422
    """
423
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
424
    _matchingbzrdir = bzrdir.BzrDirFormat4()
425
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
426
    def __init__(self):
427
        super(RepositoryFormat4, self).__init__()
428
429
    def get_format_description(self):
430
        """See RepositoryFormat.get_format_description()."""
431
        return "Repository format 4"
432
433
    def initialize(self, url, shared=False, _internal=False):
434
        """Format 4 branches cannot be created."""
435
        raise errors.UninitializableFormat(self)
436
437
    def is_supported(self):
438
        """Format 4 is not supported.
439
440
        It is not supported because the model changed from 4 to 5 and the
441
        conversion logic is expensive - so doing it on the fly was not 
442
        feasible.
443
        """
444
        return False
445
446
    def _get_control_store(self, repo_transport, control_files):
447
        """Format 4 repositories have no formal control store at this point.
448
        
449
        This will cause any control-file-needing apis to fail - this is desired.
450
        """
451
        return None
452
    
453
    def _get_revision_store(self, repo_transport, control_files):
454
        """See RepositoryFormat._get_revision_store()."""
455
        from bzrlib.xml4 import serializer_v4
456
        return self._get_text_rev_store(repo_transport,
457
                                        control_files,
458
                                        'revision-store',
459
                                        serializer=serializer_v4)
460
461
    def _get_text_store(self, transport, control_files):
462
        """See RepositoryFormat._get_text_store()."""
463
464
465
class RepositoryFormat5(PreSplitOutRepositoryFormat):
466
    """Bzr control format 5.
467
468
    This repository format has:
469
     - weaves for file texts and inventory
470
     - flat stores
471
     - TextStores for revisions and signatures.
472
    """
473
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
474
    _versionedfile_class = weave.WeaveFile
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
475
    _matchingbzrdir = bzrdir.BzrDirFormat5()
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
476
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
477
    def __init__(self):
478
        super(RepositoryFormat5, self).__init__()
479
480
    def get_format_description(self):
481
        """See RepositoryFormat.get_format_description()."""
482
        return "Weave repository format 5"
483
484
    def _get_revision_store(self, repo_transport, control_files):
485
        """See RepositoryFormat._get_revision_store()."""
486
        """Return the revision store object for this a_bzrdir."""
487
        return self._get_text_rev_store(repo_transport,
488
                                        control_files,
489
                                        'revision-store',
490
                                        compressed=False)
491
492
    def _get_text_store(self, transport, control_files):
493
        """See RepositoryFormat._get_text_store()."""
494
        return self._get_versioned_file_store('weaves', transport, control_files, prefixed=False)
495
496
497
class RepositoryFormat6(PreSplitOutRepositoryFormat):
498
    """Bzr control format 6.
499
500
    This repository format has:
501
     - weaves for file texts and inventory
502
     - hash subdirectory based stores.
503
     - TextStores for revisions and signatures.
504
    """
505
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
506
    _versionedfile_class = weave.WeaveFile
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
507
    _matchingbzrdir = bzrdir.BzrDirFormat6()
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
508
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
509
    def __init__(self):
510
        super(RepositoryFormat6, self).__init__()
511
512
    def get_format_description(self):
513
        """See RepositoryFormat.get_format_description()."""
514
        return "Weave repository format 6"
515
516
    def _get_revision_store(self, repo_transport, control_files):
517
        """See RepositoryFormat._get_revision_store()."""
518
        return self._get_text_rev_store(repo_transport,
519
                                        control_files,
520
                                        'revision-store',
521
                                        compressed=False,
522
                                        prefixed=True)
523
524
    def _get_text_store(self, transport, control_files):
525
        """See RepositoryFormat._get_text_store()."""
526
        return self._get_versioned_file_store('weaves', transport, control_files)
527
528
class RepositoryFormat7(MetaDirRepositoryFormat):
529
    """Bzr repository 7.
530
531
    This repository format has:
532
     - weaves for file texts and inventory
533
     - hash subdirectory based stores.
534
     - TextStores for revisions and signatures.
535
     - a format marker of its own
536
     - an optional 'shared-storage' flag
537
     - an optional 'no-working-trees' flag
538
    """
539
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
540
    _versionedfile_class = weave.WeaveFile
2949.1.2 by Robert Collins
* Fetch with pack repositories will no longer read the entire history graph.
541
    supports_ghosts = False
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
542
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
543
    def _get_control_store(self, repo_transport, control_files):
544
        """Return the control store for this repository."""
545
        return self._get_versioned_file_store('',
546
                                              repo_transport,
547
                                              control_files,
548
                                              prefixed=False)
549
550
    def get_format_string(self):
551
        """See RepositoryFormat.get_format_string()."""
552
        return "Bazaar-NG Repository format 7"
553
554
    def get_format_description(self):
555
        """See RepositoryFormat.get_format_description()."""
556
        return "Weave repository format 7"
557
558
    def check_conversion_target(self, target_format):
559
        pass
560
561
    def _get_revision_store(self, repo_transport, control_files):
562
        """See RepositoryFormat._get_revision_store()."""
563
        return self._get_text_rev_store(repo_transport,
564
                                        control_files,
565
                                        'revision-store',
566
                                        compressed=False,
567
                                        prefixed=True,
568
                                        )
569
570
    def _get_text_store(self, transport, control_files):
571
        """See RepositoryFormat._get_text_store()."""
572
        return self._get_versioned_file_store('weaves',
573
                                              transport,
574
                                              control_files)
575
576
    def initialize(self, a_bzrdir, shared=False):
577
        """Create a weave repository.
578
579
        :param shared: If true the repository will be initialized as a shared
580
                       repository.
581
        """
582
        # Create an empty weave
583
        sio = StringIO()
584
        weavefile.write_weave_v5(weave.Weave(), sio)
585
        empty_weave = sio.getvalue()
586
587
        mutter('creating repository in %s.', a_bzrdir.transport.base)
588
        dirs = ['revision-store', 'weaves']
589
        files = [('inventory.weave', StringIO(empty_weave)), 
590
                 ]
591
        utf8_files = [('format', self.get_format_string())]
592
 
593
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
594
        return self.open(a_bzrdir=a_bzrdir, _found=True)
595
596
    def open(self, a_bzrdir, _found=False, _override_transport=None):
597
        """See RepositoryFormat.open().
598
        
599
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
600
                                    repository at a slightly different url
601
                                    than normal. I.e. during 'upgrade'.
602
        """
603
        if not _found:
604
            format = RepositoryFormat.find_format(a_bzrdir)
605
            assert format.__class__ ==  self.__class__
606
        if _override_transport is not None:
607
            repo_transport = _override_transport
608
        else:
609
            repo_transport = a_bzrdir.get_repository_transport(None)
610
        control_files = lockable_files.LockableFiles(repo_transport,
611
                                'lock', lockdir.LockDir)
612
        text_store = self._get_text_store(repo_transport, control_files)
613
        control_store = self._get_control_store(repo_transport, control_files)
614
        _revision_store = self._get_revision_store(repo_transport, control_files)
615
        return WeaveMetaDirRepository(_format=self,
616
            a_bzrdir=a_bzrdir,
617
            control_files=control_files,
618
            _revision_store=_revision_store,
619
            control_store=control_store,
620
            text_store=text_store)
621
622
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
623
class WeaveCommitBuilder(CommitBuilder):
624
    """A builder for weave based repos that don't support ghosts."""
625
2592.3.131 by Robert Collins
Fix weaverepo commits due to api change.
626
    def _add_text_to_weave(self, file_id, new_lines, parents, nostore_sha):
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
627
        versionedfile = self.repository.weave_store.get_weave_or_empty(
628
            file_id, self.repository.get_transaction())
629
        result = versionedfile.add_lines(
2776.4.9 by Robert Collins
Unbreak weaves.
630
            self._new_revision_id, parents, new_lines,
631
            nostore_sha=nostore_sha)[0:2]
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
632
        versionedfile.clear_cache()
633
        return result
634
635
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
636
_legacy_formats = [RepositoryFormat4(),
637
                   RepositoryFormat5(),
638
                   RepositoryFormat6()]