/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

  • Committer: John Arbash Meinel
  • Date: 2007-10-10 21:18:06 UTC
  • mto: This revision was merged to the branch mainline in revision 2909.
  • Revision ID: john@arbash-meinel.com-20071010211806-2j9rg6wzrqh7yy4u
Switch from __new__ to __init__ to avoid potential pyrex upgrade problems.

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
    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
 
 
52
    _serializer = xml5.serializer_v5
 
53
 
 
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
 
 
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
 
 
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)
 
123
        result = WeaveCommitBuilder(self, parents, config, timestamp, timezone,
 
124
                              committer, revprops, revision_id)
 
125
        self.start_write_group()
 
126
        return result
 
127
 
 
128
    @needs_read_lock
 
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
 
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
 
 
200
 
 
201
class WeaveMetaDirRepository(MetaDirRepository):
 
202
    """A subclass of MetaDirRepository to set weave specific policy."""
 
203
 
 
204
    _serializer = xml5.serializer_v5
 
205
 
 
206
    @needs_read_lock
 
207
    def _all_possible_ids(self):
 
208
        """Return all the possible revisions that we could find."""
 
209
        if 'evil' in debug.debug_flags:
 
210
            mutter_callsite(3, "_all_possible_ids scales with size of history.")
 
211
        return self.get_inventory_weave().versions()
 
212
 
 
213
    @needs_read_lock
 
214
    def _all_revision_ids(self):
 
215
        """Returns a list of all the revision ids in the repository. 
 
216
 
 
217
        These are in as much topological order as the underlying store can 
 
218
        present: for weaves ghosts may lead to a lack of correctness until
 
219
        the reweave updates the parents list.
 
220
        """
 
221
        if self._revision_store.text_store.listable():
 
222
            return self._revision_store.all_revision_ids(self.get_transaction())
 
223
        result = self._all_possible_ids()
 
224
        # TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
 
225
        #       ids. (It should, since _revision_store's API should change to
 
226
        #       return utf8 revision_ids)
 
227
        return self._eliminate_revisions_not_present(result)
 
228
 
 
229
    def _check_revision_parents(self, revision, inventory):
 
230
        """Private to Repository and Fetch.
 
231
        
 
232
        This checks the parentage of revision in an inventory weave for 
 
233
        consistency and is only applicable to inventory-weave-for-ancestry
 
234
        using repository formats & fetchers.
 
235
        """
 
236
        weave_parents = inventory.get_parents(revision.revision_id)
 
237
        weave_names = inventory.versions()
 
238
        for parent_id in revision.parent_ids:
 
239
            if parent_id in weave_names:
 
240
                # this parent must not be a ghost.
 
241
                if not parent_id in weave_parents:
 
242
                    # but it is a ghost
 
243
                    raise errors.CorruptRepository(self)
 
244
 
 
245
    def get_commit_builder(self, branch, parents, config, timestamp=None,
 
246
                           timezone=None, committer=None, revprops=None,
 
247
                           revision_id=None):
 
248
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
 
249
        result = WeaveCommitBuilder(self, parents, config, timestamp, timezone,
 
250
                              committer, revprops, revision_id)
 
251
        self.start_write_group()
 
252
        return result
 
253
 
 
254
    @needs_read_lock
 
255
    def get_revision(self, revision_id):
 
256
        """Return the Revision object for a named revision"""
 
257
        # TODO: jam 20070210 get_revision_reconcile should do this for us
 
258
        r = self.get_revision_reconcile(revision_id)
 
259
        # weave corruption can lead to absent revision markers that should be
 
260
        # present.
 
261
        # the following test is reasonably cheap (it needs a single weave read)
 
262
        # and the weave is cached in read transactions. In write transactions
 
263
        # it is not cached but typically we only read a small number of
 
264
        # revisions. For knits when they are introduced we will probably want
 
265
        # to ensure that caching write transactions are in use.
 
266
        inv = self.get_inventory_weave()
 
267
        self._check_revision_parents(r, inv)
 
268
        return r
 
269
 
 
270
    @needs_read_lock
 
271
    def get_revision_graph(self, revision_id=None):
 
272
        """Return a dictionary containing the revision graph.
 
273
        
 
274
        :param revision_id: The revision_id to get a graph from. If None, then
 
275
        the entire revision graph is returned. This is a deprecated mode of
 
276
        operation and will be removed in the future.
 
277
        :return: a dictionary of revision_id->revision_parents_list.
 
278
        """
 
279
        if 'evil' in debug.debug_flags:
 
280
            mutter_callsite(3,
 
281
                "get_revision_graph scales with size of history.")
 
282
        # special case NULL_REVISION
 
283
        if revision_id == _mod_revision.NULL_REVISION:
 
284
            return {}
 
285
        a_weave = self.get_inventory_weave()
 
286
        all_revisions = self._eliminate_revisions_not_present(
 
287
                                a_weave.versions())
 
288
        entire_graph = dict([(node, tuple(a_weave.get_parents(node))) for 
 
289
                             node in all_revisions])
 
290
        if revision_id is None:
 
291
            return entire_graph
 
292
        elif revision_id not in entire_graph:
 
293
            raise errors.NoSuchRevision(self, revision_id)
 
294
        else:
 
295
            # add what can be reached from revision_id
 
296
            result = {}
 
297
            pending = set([revision_id])
 
298
            while len(pending) > 0:
 
299
                node = pending.pop()
 
300
                result[node] = entire_graph[node]
 
301
                for revision_id in result[node]:
 
302
                    if revision_id not in result:
 
303
                        pending.add(revision_id)
 
304
            return result
 
305
 
 
306
 
 
307
class PreSplitOutRepositoryFormat(RepositoryFormat):
 
308
    """Base class for the pre split out repository formats."""
 
309
 
 
310
    rich_root_data = False
 
311
    supports_tree_reference = False
 
312
 
 
313
    def initialize(self, a_bzrdir, shared=False, _internal=False):
 
314
        """Create a weave repository.
 
315
        
 
316
        TODO: when creating split out bzr branch formats, move this to a common
 
317
        base for Format5, Format6. or something like that.
 
318
        """
 
319
        if shared:
 
320
            raise errors.IncompatibleFormat(self, a_bzrdir._format)
 
321
 
 
322
        if not _internal:
 
323
            # always initialized when the bzrdir is.
 
324
            return self.open(a_bzrdir, _found=True)
 
325
        
 
326
        # Create an empty weave
 
327
        sio = StringIO()
 
328
        weavefile.write_weave_v5(weave.Weave(), sio)
 
329
        empty_weave = sio.getvalue()
 
330
 
 
331
        mutter('creating repository in %s.', a_bzrdir.transport.base)
 
332
        dirs = ['revision-store', 'weaves']
 
333
        files = [('inventory.weave', StringIO(empty_weave)),
 
334
                 ]
 
335
        
 
336
        # FIXME: RBC 20060125 don't peek under the covers
 
337
        # NB: no need to escape relative paths that are url safe.
 
338
        control_files = lockable_files.LockableFiles(a_bzrdir.transport,
 
339
                                'branch-lock', lockable_files.TransportLock)
 
340
        control_files.create_lock()
 
341
        control_files.lock_write()
 
342
        control_files._transport.mkdir_multi(dirs,
 
343
                mode=control_files._dir_mode)
 
344
        try:
 
345
            for file, content in files:
 
346
                control_files.put(file, content)
 
347
        finally:
 
348
            control_files.unlock()
 
349
        return self.open(a_bzrdir, _found=True)
 
350
 
 
351
    def _get_control_store(self, repo_transport, control_files):
 
352
        """Return the control store for this repository."""
 
353
        return self._get_versioned_file_store('',
 
354
                                              repo_transport,
 
355
                                              control_files,
 
356
                                              prefixed=False)
 
357
 
 
358
    def _get_text_store(self, transport, control_files):
 
359
        """Get a store for file texts for this format."""
 
360
        raise NotImplementedError(self._get_text_store)
 
361
 
 
362
    def open(self, a_bzrdir, _found=False):
 
363
        """See RepositoryFormat.open()."""
 
364
        if not _found:
 
365
            # we are being called directly and must probe.
 
366
            raise NotImplementedError
 
367
 
 
368
        repo_transport = a_bzrdir.get_repository_transport(None)
 
369
        control_files = a_bzrdir._control_files
 
370
        text_store = self._get_text_store(repo_transport, control_files)
 
371
        control_store = self._get_control_store(repo_transport, control_files)
 
372
        _revision_store = self._get_revision_store(repo_transport, control_files)
 
373
        return AllInOneRepository(_format=self,
 
374
                                  a_bzrdir=a_bzrdir,
 
375
                                  _revision_store=_revision_store,
 
376
                                  control_store=control_store,
 
377
                                  text_store=text_store)
 
378
 
 
379
    def check_conversion_target(self, target_format):
 
380
        pass
 
381
 
 
382
 
 
383
class RepositoryFormat4(PreSplitOutRepositoryFormat):
 
384
    """Bzr repository format 4.
 
385
 
 
386
    This repository format has:
 
387
     - flat stores
 
388
     - TextStores for texts, inventories,revisions.
 
389
 
 
390
    This format is deprecated: it indexes texts using a text id which is
 
391
    removed in format 5; initialization and write support for this format
 
392
    has been removed.
 
393
    """
 
394
 
 
395
    _matchingbzrdir = bzrdir.BzrDirFormat4()
 
396
 
 
397
    def __init__(self):
 
398
        super(RepositoryFormat4, self).__init__()
 
399
 
 
400
    def get_format_description(self):
 
401
        """See RepositoryFormat.get_format_description()."""
 
402
        return "Repository format 4"
 
403
 
 
404
    def initialize(self, url, shared=False, _internal=False):
 
405
        """Format 4 branches cannot be created."""
 
406
        raise errors.UninitializableFormat(self)
 
407
 
 
408
    def is_supported(self):
 
409
        """Format 4 is not supported.
 
410
 
 
411
        It is not supported because the model changed from 4 to 5 and the
 
412
        conversion logic is expensive - so doing it on the fly was not 
 
413
        feasible.
 
414
        """
 
415
        return False
 
416
 
 
417
    def _get_control_store(self, repo_transport, control_files):
 
418
        """Format 4 repositories have no formal control store at this point.
 
419
        
 
420
        This will cause any control-file-needing apis to fail - this is desired.
 
421
        """
 
422
        return None
 
423
    
 
424
    def _get_revision_store(self, repo_transport, control_files):
 
425
        """See RepositoryFormat._get_revision_store()."""
 
426
        from bzrlib.xml4 import serializer_v4
 
427
        return self._get_text_rev_store(repo_transport,
 
428
                                        control_files,
 
429
                                        'revision-store',
 
430
                                        serializer=serializer_v4)
 
431
 
 
432
    def _get_text_store(self, transport, control_files):
 
433
        """See RepositoryFormat._get_text_store()."""
 
434
 
 
435
 
 
436
class RepositoryFormat5(PreSplitOutRepositoryFormat):
 
437
    """Bzr control format 5.
 
438
 
 
439
    This repository format has:
 
440
     - weaves for file texts and inventory
 
441
     - flat stores
 
442
     - TextStores for revisions and signatures.
 
443
    """
 
444
 
 
445
    _versionedfile_class = weave.WeaveFile
 
446
    _matchingbzrdir = bzrdir.BzrDirFormat5()
 
447
 
 
448
    def __init__(self):
 
449
        super(RepositoryFormat5, self).__init__()
 
450
 
 
451
    def get_format_description(self):
 
452
        """See RepositoryFormat.get_format_description()."""
 
453
        return "Weave repository format 5"
 
454
 
 
455
    def _get_revision_store(self, repo_transport, control_files):
 
456
        """See RepositoryFormat._get_revision_store()."""
 
457
        """Return the revision store object for this a_bzrdir."""
 
458
        return self._get_text_rev_store(repo_transport,
 
459
                                        control_files,
 
460
                                        'revision-store',
 
461
                                        compressed=False)
 
462
 
 
463
    def _get_text_store(self, transport, control_files):
 
464
        """See RepositoryFormat._get_text_store()."""
 
465
        return self._get_versioned_file_store('weaves', transport, control_files, prefixed=False)
 
466
 
 
467
 
 
468
class RepositoryFormat6(PreSplitOutRepositoryFormat):
 
469
    """Bzr control format 6.
 
470
 
 
471
    This repository format has:
 
472
     - weaves for file texts and inventory
 
473
     - hash subdirectory based stores.
 
474
     - TextStores for revisions and signatures.
 
475
    """
 
476
 
 
477
    _versionedfile_class = weave.WeaveFile
 
478
    _matchingbzrdir = bzrdir.BzrDirFormat6()
 
479
 
 
480
    def __init__(self):
 
481
        super(RepositoryFormat6, self).__init__()
 
482
 
 
483
    def get_format_description(self):
 
484
        """See RepositoryFormat.get_format_description()."""
 
485
        return "Weave repository format 6"
 
486
 
 
487
    def _get_revision_store(self, repo_transport, control_files):
 
488
        """See RepositoryFormat._get_revision_store()."""
 
489
        return self._get_text_rev_store(repo_transport,
 
490
                                        control_files,
 
491
                                        'revision-store',
 
492
                                        compressed=False,
 
493
                                        prefixed=True)
 
494
 
 
495
    def _get_text_store(self, transport, control_files):
 
496
        """See RepositoryFormat._get_text_store()."""
 
497
        return self._get_versioned_file_store('weaves', transport, control_files)
 
498
 
 
499
 
 
500
class RepositoryFormat7(MetaDirRepositoryFormat):
 
501
    """Bzr repository 7.
 
502
 
 
503
    This repository format has:
 
504
     - weaves for file texts and inventory
 
505
     - hash subdirectory based stores.
 
506
     - TextStores for revisions and signatures.
 
507
     - a format marker of its own
 
508
     - an optional 'shared-storage' flag
 
509
     - an optional 'no-working-trees' flag
 
510
    """
 
511
 
 
512
    _versionedfile_class = weave.WeaveFile
 
513
 
 
514
    def _get_control_store(self, repo_transport, control_files):
 
515
        """Return the control store for this repository."""
 
516
        return self._get_versioned_file_store('',
 
517
                                              repo_transport,
 
518
                                              control_files,
 
519
                                              prefixed=False)
 
520
 
 
521
    def get_format_string(self):
 
522
        """See RepositoryFormat.get_format_string()."""
 
523
        return "Bazaar-NG Repository format 7"
 
524
 
 
525
    def get_format_description(self):
 
526
        """See RepositoryFormat.get_format_description()."""
 
527
        return "Weave repository format 7"
 
528
 
 
529
    def check_conversion_target(self, target_format):
 
530
        pass
 
531
 
 
532
    def _get_revision_store(self, repo_transport, control_files):
 
533
        """See RepositoryFormat._get_revision_store()."""
 
534
        return self._get_text_rev_store(repo_transport,
 
535
                                        control_files,
 
536
                                        'revision-store',
 
537
                                        compressed=False,
 
538
                                        prefixed=True,
 
539
                                        )
 
540
 
 
541
    def _get_text_store(self, transport, control_files):
 
542
        """See RepositoryFormat._get_text_store()."""
 
543
        return self._get_versioned_file_store('weaves',
 
544
                                              transport,
 
545
                                              control_files)
 
546
 
 
547
    def initialize(self, a_bzrdir, shared=False):
 
548
        """Create a weave repository.
 
549
 
 
550
        :param shared: If true the repository will be initialized as a shared
 
551
                       repository.
 
552
        """
 
553
        # Create an empty weave
 
554
        sio = StringIO()
 
555
        weavefile.write_weave_v5(weave.Weave(), sio)
 
556
        empty_weave = sio.getvalue()
 
557
 
 
558
        mutter('creating repository in %s.', a_bzrdir.transport.base)
 
559
        dirs = ['revision-store', 'weaves']
 
560
        files = [('inventory.weave', StringIO(empty_weave)), 
 
561
                 ]
 
562
        utf8_files = [('format', self.get_format_string())]
 
563
 
 
564
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
 
565
        return self.open(a_bzrdir=a_bzrdir, _found=True)
 
566
 
 
567
    def open(self, a_bzrdir, _found=False, _override_transport=None):
 
568
        """See RepositoryFormat.open().
 
569
        
 
570
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
 
571
                                    repository at a slightly different url
 
572
                                    than normal. I.e. during 'upgrade'.
 
573
        """
 
574
        if not _found:
 
575
            format = RepositoryFormat.find_format(a_bzrdir)
 
576
            assert format.__class__ ==  self.__class__
 
577
        if _override_transport is not None:
 
578
            repo_transport = _override_transport
 
579
        else:
 
580
            repo_transport = a_bzrdir.get_repository_transport(None)
 
581
        control_files = lockable_files.LockableFiles(repo_transport,
 
582
                                'lock', lockdir.LockDir)
 
583
        text_store = self._get_text_store(repo_transport, control_files)
 
584
        control_store = self._get_control_store(repo_transport, control_files)
 
585
        _revision_store = self._get_revision_store(repo_transport, control_files)
 
586
        return WeaveMetaDirRepository(_format=self,
 
587
            a_bzrdir=a_bzrdir,
 
588
            control_files=control_files,
 
589
            _revision_store=_revision_store,
 
590
            control_store=control_store,
 
591
            text_store=text_store)
 
592
 
 
593
 
 
594
class WeaveCommitBuilder(CommitBuilder):
 
595
    """A builder for weave based repos that don't support ghosts."""
 
596
 
 
597
    def _add_text_to_weave(self, file_id, new_lines, parents, nostore_sha):
 
598
        versionedfile = self.repository.weave_store.get_weave_or_empty(
 
599
            file_id, self.repository.get_transaction())
 
600
        result = versionedfile.add_lines(
 
601
            self._new_revision_id, parents, new_lines,
 
602
            nostore_sha=nostore_sha)[0:2]
 
603
        versionedfile.clear_cache()
 
604
        return result
 
605
 
 
606
 
 
607
_legacy_formats = [RepositoryFormat4(),
 
608
                   RepositoryFormat5(),
 
609
                   RepositoryFormat6()]