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