/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/repofmt/weaverepo.py

Deprecate LockableFiles.put_utf8 and put_bytes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
17
"""Deprecated weave-based repository formats.
 
18
 
 
19
Weave based formats scaled linearly with history size and could not represent
 
20
ghosts.
 
21
"""
 
22
 
 
23
from StringIO import StringIO
 
24
 
 
25
from bzrlib import (
 
26
    bzrdir,
 
27
    debug,
 
28
    errors,
 
29
    lockable_files,
 
30
    lockdir,
 
31
    osutils,
 
32
    revision as _mod_revision,
 
33
    weave,
 
34
    weavefile,
 
35
    xml5,
 
36
    )
 
37
from bzrlib.decorators import needs_read_lock, needs_write_lock
 
38
from bzrlib.repository import (
 
39
    CommitBuilder,
 
40
    MetaDirVersionedFileRepository,
 
41
    MetaDirRepositoryFormat,
 
42
    Repository,
 
43
    RepositoryFormat,
 
44
    )
 
45
from bzrlib.store.text import TextStore
 
46
from bzrlib.symbol_versioning import deprecated_method, one_four
 
47
from bzrlib.trace import mutter
 
48
 
 
49
 
 
50
class AllInOneRepository(Repository):
 
51
    """Legacy support - the repository behaviour for all-in-one branches."""
 
52
 
 
53
    _serializer = xml5.serializer_v5
 
54
 
 
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
        if control_store is not None:
 
81
            control_store.get_scope = self.get_transaction
 
82
        text_store.get_scope = self.get_transaction
 
83
 
 
84
    @needs_read_lock
 
85
    def _all_possible_ids(self):
 
86
        """Return all the possible revisions that we could find."""
 
87
        if 'evil' in debug.debug_flags:
 
88
            mutter_callsite(3, "_all_possible_ids scales with size of history.")
 
89
        return self.get_inventory_weave().versions()
 
90
 
 
91
    @needs_read_lock
 
92
    def _all_revision_ids(self):
 
93
        """Returns a list of all the revision ids in the repository. 
 
94
 
 
95
        These are in as much topological order as the underlying store can 
 
96
        present: for weaves ghosts may lead to a lack of correctness until
 
97
        the reweave updates the parents list.
 
98
        """
 
99
        if self._revision_store.text_store.listable():
 
100
            return self._revision_store.all_revision_ids(self.get_transaction())
 
101
        result = self._all_possible_ids()
 
102
        # TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
 
103
        #       ids. (It should, since _revision_store's API should change to
 
104
        #       return utf8 revision_ids)
 
105
        return self._eliminate_revisions_not_present(result)
 
106
 
 
107
    def _check_revision_parents(self, revision, inventory):
 
108
        """Private to Repository and Fetch.
 
109
        
 
110
        This checks the parentage of revision in an inventory weave for 
 
111
        consistency and is only applicable to inventory-weave-for-ancestry
 
112
        using repository formats & fetchers.
 
113
        """
 
114
        weave_parents = inventory.get_parent_map(
 
115
            [revision.revision_id])[revision.revision_id]
 
116
        parent_map = inventory.get_parent_map(revision.parent_ids)
 
117
        for parent_id in revision.parent_ids:
 
118
            if parent_id in parent_map:
 
119
                # this parent must not be a ghost.
 
120
                if not parent_id in weave_parents:
 
121
                    # but it is a ghost
 
122
                    raise errors.CorruptRepository(self)
 
123
 
 
124
    def get_commit_builder(self, branch, parents, config, timestamp=None,
 
125
                           timezone=None, committer=None, revprops=None,
 
126
                           revision_id=None):
 
127
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
 
128
        result = WeaveCommitBuilder(self, parents, config, timestamp, timezone,
 
129
                              committer, revprops, revision_id)
 
130
        self.start_write_group()
 
131
        return result
 
132
 
 
133
    @needs_read_lock
 
134
    def get_revisions(self, revision_ids):
 
135
        revs = self._get_revisions(revision_ids)
 
136
        # weave corruption can lead to absent revision markers that should be
 
137
        # present.
 
138
        # the following test is reasonably cheap (it needs a single weave read)
 
139
        # and the weave is cached in read transactions. In write transactions
 
140
        # it is not cached but typically we only read a small number of
 
141
        # revisions. For knits when they are introduced we will probably want
 
142
        # to ensure that caching write transactions are in use.
 
143
        inv = self.get_inventory_weave()
 
144
        for rev in revs:
 
145
            self._check_revision_parents(rev, inv)
 
146
        return revs
 
147
 
 
148
    @deprecated_method(one_four)
 
149
    @needs_read_lock
 
150
    def get_revision_graph(self, revision_id=None):
 
151
        """Return a dictionary containing the revision graph.
 
152
        
 
153
        :param revision_id: The revision_id to get a graph from. If None, then
 
154
        the entire revision graph is returned. This is a deprecated mode of
 
155
        operation and will be removed in the future.
 
156
        :return: a dictionary of revision_id->revision_parents_list.
 
157
        """
 
158
        if 'evil' in debug.debug_flags:
 
159
            mutter_callsite(2,
 
160
                "get_revision_graph scales with size of history.")
 
161
        # special case NULL_REVISION
 
162
        if revision_id == _mod_revision.NULL_REVISION:
 
163
            return {}
 
164
        a_weave = self.get_inventory_weave()
 
165
        all_revisions = self._eliminate_revisions_not_present(
 
166
                                a_weave.versions())
 
167
        entire_graph = a_weave.get_parent_map(all_revisions)
 
168
        if revision_id is None:
 
169
            return entire_graph
 
170
        elif revision_id not in entire_graph:
 
171
            raise errors.NoSuchRevision(self, revision_id)
 
172
        else:
 
173
            # add what can be reached from revision_id
 
174
            result = {}
 
175
            pending = set([revision_id])
 
176
            while len(pending) > 0:
 
177
                node = pending.pop()
 
178
                result[node] = entire_graph[node]
 
179
                for revision_id in result[node]:
 
180
                    if revision_id not in result:
 
181
                        pending.add(revision_id)
 
182
            return result
 
183
 
 
184
    def has_revisions(self, revision_ids):
 
185
        """See Repository.has_revisions()."""
 
186
        result = set()
 
187
        transaction = self.get_transaction()
 
188
        for revision_id in revision_ids:
 
189
            if self._revision_store.has_revision_id(revision_id, transaction):
 
190
                result.add(revision_id)
 
191
        return result
 
192
 
 
193
    @needs_read_lock
 
194
    def is_shared(self):
 
195
        """AllInOne repositories cannot be shared."""
 
196
        return False
 
197
 
 
198
    @needs_write_lock
 
199
    def set_make_working_trees(self, new_value):
 
200
        """Set the policy flag for making working trees when creating branches.
 
201
 
 
202
        This only applies to branches that use this repository.
 
203
 
 
204
        The default is 'True'.
 
205
        :param new_value: True to restore the default, False to disable making
 
206
                          working trees.
 
207
        """
 
208
        raise errors.RepositoryUpgradeRequired(self.bzrdir.root_transport.base)
 
209
 
 
210
    def make_working_trees(self):
 
211
        """Returns the policy for making working trees on new branches."""
 
212
        return True
 
213
 
 
214
    def revision_graph_can_have_wrong_parents(self):
 
215
        # XXX: This is an old format that we don't support full checking on, so
 
216
        # just claim that checking for this inconsistency is not required.
 
217
        return False
 
218
 
 
219
 
 
220
class WeaveMetaDirRepository(MetaDirVersionedFileRepository):
 
221
    """A subclass of MetaDirRepository to set weave specific policy."""
 
222
 
 
223
    _serializer = xml5.serializer_v5
 
224
 
 
225
    @needs_read_lock
 
226
    def _all_possible_ids(self):
 
227
        """Return all the possible revisions that we could find."""
 
228
        if 'evil' in debug.debug_flags:
 
229
            mutter_callsite(3, "_all_possible_ids scales with size of history.")
 
230
        return self.get_inventory_weave().versions()
 
231
 
 
232
    @needs_read_lock
 
233
    def _all_revision_ids(self):
 
234
        """Returns a list of all the revision ids in the repository. 
 
235
 
 
236
        These are in as much topological order as the underlying store can 
 
237
        present: for weaves ghosts may lead to a lack of correctness until
 
238
        the reweave updates the parents list.
 
239
        """
 
240
        if self._revision_store.text_store.listable():
 
241
            return self._revision_store.all_revision_ids(self.get_transaction())
 
242
        result = self._all_possible_ids()
 
243
        # TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
 
244
        #       ids. (It should, since _revision_store's API should change to
 
245
        #       return utf8 revision_ids)
 
246
        return self._eliminate_revisions_not_present(result)
 
247
 
 
248
    def _check_revision_parents(self, revision, inventory):
 
249
        """Private to Repository and Fetch.
 
250
        
 
251
        This checks the parentage of revision in an inventory weave for 
 
252
        consistency and is only applicable to inventory-weave-for-ancestry
 
253
        using repository formats & fetchers.
 
254
        """
 
255
        weave_parents = inventory.get_parent_map(
 
256
            [revision.revision_id])[revision.revision_id]
 
257
        parent_map = inventory.get_parent_map(revision.parent_ids)
 
258
        for parent_id in revision.parent_ids:
 
259
            if parent_id in parent_map:
 
260
                # this parent must not be a ghost.
 
261
                if not parent_id in weave_parents:
 
262
                    # but it is a ghost
 
263
                    raise errors.CorruptRepository(self)
 
264
 
 
265
    def get_commit_builder(self, branch, parents, config, timestamp=None,
 
266
                           timezone=None, committer=None, revprops=None,
 
267
                           revision_id=None):
 
268
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
 
269
        result = WeaveCommitBuilder(self, parents, config, timestamp, timezone,
 
270
                              committer, revprops, revision_id)
 
271
        self.start_write_group()
 
272
        return result
 
273
 
 
274
    @needs_read_lock
 
275
    def get_revision(self, revision_id):
 
276
        """Return the Revision object for a named revision"""
 
277
        # TODO: jam 20070210 get_revision_reconcile should do this for us
 
278
        r = self.get_revision_reconcile(revision_id)
 
279
        # weave corruption can lead to absent revision markers that should be
 
280
        # present.
 
281
        # the following test is reasonably cheap (it needs a single weave read)
 
282
        # and the weave is cached in read transactions. In write transactions
 
283
        # it is not cached but typically we only read a small number of
 
284
        # revisions. For knits when they are introduced we will probably want
 
285
        # to ensure that caching write transactions are in use.
 
286
        inv = self.get_inventory_weave()
 
287
        self._check_revision_parents(r, inv)
 
288
        return r
 
289
 
 
290
    @deprecated_method(one_four)
 
291
    @needs_read_lock
 
292
    def get_revision_graph(self, revision_id=None):
 
293
        """Return a dictionary containing the revision graph.
 
294
        
 
295
        :param revision_id: The revision_id to get a graph from. If None, then
 
296
        the entire revision graph is returned. This is a deprecated mode of
 
297
        operation and will be removed in the future.
 
298
        :return: a dictionary of revision_id->revision_parents_list.
 
299
        """
 
300
        if 'evil' in debug.debug_flags:
 
301
            mutter_callsite(3,
 
302
                "get_revision_graph scales with size of history.")
 
303
        # special case NULL_REVISION
 
304
        if revision_id == _mod_revision.NULL_REVISION:
 
305
            return {}
 
306
        a_weave = self.get_inventory_weave()
 
307
        all_revisions = self._eliminate_revisions_not_present(
 
308
                                a_weave.versions())
 
309
        entire_graph = a_weave.get_parent_map(all_revisions)
 
310
        if revision_id is None:
 
311
            return entire_graph
 
312
        elif revision_id not in entire_graph:
 
313
            raise errors.NoSuchRevision(self, revision_id)
 
314
        else:
 
315
            # add what can be reached from revision_id
 
316
            result = {}
 
317
            pending = set([revision_id])
 
318
            while len(pending) > 0:
 
319
                node = pending.pop()
 
320
                result[node] = entire_graph[node]
 
321
                for revision_id in result[node]:
 
322
                    if revision_id not in result:
 
323
                        pending.add(revision_id)
 
324
            return result
 
325
 
 
326
    def has_revisions(self, revision_ids):
 
327
        """See Repository.has_revisions()."""
 
328
        result = set()
 
329
        transaction = self.get_transaction()
 
330
        for revision_id in revision_ids:
 
331
            if self._revision_store.has_revision_id(revision_id, transaction):
 
332
                result.add(revision_id)
 
333
        return result
 
334
 
 
335
    def revision_graph_can_have_wrong_parents(self):
 
336
        # XXX: This is an old format that we don't support full checking on, so
 
337
        # just claim that checking for this inconsistency is not required.
 
338
        return False
 
339
 
 
340
 
 
341
class PreSplitOutRepositoryFormat(RepositoryFormat):
 
342
    """Base class for the pre split out repository formats."""
 
343
 
 
344
    rich_root_data = False
 
345
    supports_tree_reference = False
 
346
    supports_ghosts = False
 
347
    supports_external_lookups = False
 
348
 
 
349
    def initialize(self, a_bzrdir, shared=False, _internal=False):
 
350
        """Create a weave repository."""
 
351
        if shared:
 
352
            raise errors.IncompatibleFormat(self, a_bzrdir._format)
 
353
 
 
354
        if not _internal:
 
355
            # always initialized when the bzrdir is.
 
356
            return self.open(a_bzrdir, _found=True)
 
357
        
 
358
        # Create an empty weave
 
359
        sio = StringIO()
 
360
        weavefile.write_weave_v5(weave.Weave(), sio)
 
361
        empty_weave = sio.getvalue()
 
362
 
 
363
        mutter('creating repository in %s.', a_bzrdir.transport.base)
 
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
        transport = control_files._transport
 
372
        try:
 
373
            transport.mkdir_multi(['revision-store', 'weaves'],
 
374
                mode=control_files._dir_mode)
 
375
            transport.put_bytes_non_atomic('inventory.weave', empty_weave)
 
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
 
 
424
    _matchingbzrdir = bzrdir.BzrDirFormat4()
 
425
 
 
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
 
 
474
    _versionedfile_class = weave.WeaveFile
 
475
    _matchingbzrdir = bzrdir.BzrDirFormat5()
 
476
 
 
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
 
 
506
    _versionedfile_class = weave.WeaveFile
 
507
    _matchingbzrdir = bzrdir.BzrDirFormat6()
 
508
 
 
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
 
 
540
    _versionedfile_class = weave.WeaveFile
 
541
    supports_ghosts = False
 
542
 
 
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
 
 
623
class WeaveCommitBuilder(CommitBuilder):
 
624
    """A builder for weave based repos that don't support ghosts."""
 
625
 
 
626
    def _add_text_to_weave(self, file_id, new_lines, parents, nostore_sha):
 
627
        versionedfile = self.repository.weave_store.get_weave_or_empty(
 
628
            file_id, self.repository.get_transaction())
 
629
        result = versionedfile.add_lines(
 
630
            self._new_revision_id, parents, new_lines,
 
631
            nostore_sha=nostore_sha)[0:2]
 
632
        return result
 
633
 
 
634
 
 
635
_legacy_formats = [RepositoryFormat4(),
 
636
                   RepositoryFormat5(),
 
637
                   RepositoryFormat6()]