~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/weaverepo.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-08-17 07:52:09 UTC
  • mfrom: (1910.3.4 trivial)
  • Revision ID: pqm@pqm.ubuntu.com-20060817075209-e85a1f9e05ff8b87
(andrew) Trivial fixes to NotImplemented errors.

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
 
    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
 
 
205
 
 
206
 
class WeaveMetaDirRepository(MetaDirRepository):
207
 
    """A subclass of MetaDirRepository to set weave specific policy."""
208
 
 
209
 
    _serializer = xml5.serializer_v5
210
 
 
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
 
 
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)
254
 
        result = WeaveCommitBuilder(self, parents, config, timestamp, timezone,
255
 
                              committer, revprops, revision_id)
256
 
        self.start_write_group()
257
 
        return result
258
 
 
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
 
 
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
 
 
316
 
 
317
 
class PreSplitOutRepositoryFormat(RepositoryFormat):
318
 
    """Base class for the pre split out repository formats."""
319
 
 
320
 
    rich_root_data = False
321
 
    supports_tree_reference = False
322
 
 
323
 
    def initialize(self, a_bzrdir, shared=False, _internal=False):
324
 
        """Create a weave repository.
325
 
        
326
 
        TODO: when creating split out bzr branch formats, move this to a common
327
 
        base for Format5, Format6. or something like that.
328
 
        """
329
 
        if shared:
330
 
            raise errors.IncompatibleFormat(self, a_bzrdir._format)
331
 
 
332
 
        if not _internal:
333
 
            # always initialized when the bzrdir is.
334
 
            return self.open(a_bzrdir, _found=True)
335
 
        
336
 
        # Create an empty weave
337
 
        sio = StringIO()
338
 
        weavefile.write_weave_v5(weave.Weave(), sio)
339
 
        empty_weave = sio.getvalue()
340
 
 
341
 
        mutter('creating repository in %s.', a_bzrdir.transport.base)
342
 
        dirs = ['revision-store', 'weaves']
343
 
        files = [('inventory.weave', StringIO(empty_weave)),
344
 
                 ]
345
 
        
346
 
        # FIXME: RBC 20060125 don't peek under the covers
347
 
        # NB: no need to escape relative paths that are url safe.
348
 
        control_files = lockable_files.LockableFiles(a_bzrdir.transport,
349
 
                                'branch-lock', lockable_files.TransportLock)
350
 
        control_files.create_lock()
351
 
        control_files.lock_write()
352
 
        control_files._transport.mkdir_multi(dirs,
353
 
                mode=control_files._dir_mode)
354
 
        try:
355
 
            for file, content in files:
356
 
                control_files.put(file, content)
357
 
        finally:
358
 
            control_files.unlock()
359
 
        return self.open(a_bzrdir, _found=True)
360
 
 
361
 
    def _get_control_store(self, repo_transport, control_files):
362
 
        """Return the control store for this repository."""
363
 
        return self._get_versioned_file_store('',
364
 
                                              repo_transport,
365
 
                                              control_files,
366
 
                                              prefixed=False)
367
 
 
368
 
    def _get_text_store(self, transport, control_files):
369
 
        """Get a store for file texts for this format."""
370
 
        raise NotImplementedError(self._get_text_store)
371
 
 
372
 
    def open(self, a_bzrdir, _found=False):
373
 
        """See RepositoryFormat.open()."""
374
 
        if not _found:
375
 
            # we are being called directly and must probe.
376
 
            raise NotImplementedError
377
 
 
378
 
        repo_transport = a_bzrdir.get_repository_transport(None)
379
 
        control_files = a_bzrdir._control_files
380
 
        text_store = self._get_text_store(repo_transport, control_files)
381
 
        control_store = self._get_control_store(repo_transport, control_files)
382
 
        _revision_store = self._get_revision_store(repo_transport, control_files)
383
 
        return AllInOneRepository(_format=self,
384
 
                                  a_bzrdir=a_bzrdir,
385
 
                                  _revision_store=_revision_store,
386
 
                                  control_store=control_store,
387
 
                                  text_store=text_store)
388
 
 
389
 
    def check_conversion_target(self, target_format):
390
 
        pass
391
 
 
392
 
 
393
 
class RepositoryFormat4(PreSplitOutRepositoryFormat):
394
 
    """Bzr repository format 4.
395
 
 
396
 
    This repository format has:
397
 
     - flat stores
398
 
     - TextStores for texts, inventories,revisions.
399
 
 
400
 
    This format is deprecated: it indexes texts using a text id which is
401
 
    removed in format 5; initialization and write support for this format
402
 
    has been removed.
403
 
    """
404
 
 
405
 
    _matchingbzrdir = bzrdir.BzrDirFormat4()
406
 
 
407
 
    def __init__(self):
408
 
        super(RepositoryFormat4, self).__init__()
409
 
 
410
 
    def get_format_description(self):
411
 
        """See RepositoryFormat.get_format_description()."""
412
 
        return "Repository format 4"
413
 
 
414
 
    def initialize(self, url, shared=False, _internal=False):
415
 
        """Format 4 branches cannot be created."""
416
 
        raise errors.UninitializableFormat(self)
417
 
 
418
 
    def is_supported(self):
419
 
        """Format 4 is not supported.
420
 
 
421
 
        It is not supported because the model changed from 4 to 5 and the
422
 
        conversion logic is expensive - so doing it on the fly was not 
423
 
        feasible.
424
 
        """
425
 
        return False
426
 
 
427
 
    def _get_control_store(self, repo_transport, control_files):
428
 
        """Format 4 repositories have no formal control store at this point.
429
 
        
430
 
        This will cause any control-file-needing apis to fail - this is desired.
431
 
        """
432
 
        return None
433
 
    
434
 
    def _get_revision_store(self, repo_transport, control_files):
435
 
        """See RepositoryFormat._get_revision_store()."""
436
 
        from bzrlib.xml4 import serializer_v4
437
 
        return self._get_text_rev_store(repo_transport,
438
 
                                        control_files,
439
 
                                        'revision-store',
440
 
                                        serializer=serializer_v4)
441
 
 
442
 
    def _get_text_store(self, transport, control_files):
443
 
        """See RepositoryFormat._get_text_store()."""
444
 
 
445
 
 
446
 
class RepositoryFormat5(PreSplitOutRepositoryFormat):
447
 
    """Bzr control format 5.
448
 
 
449
 
    This repository format has:
450
 
     - weaves for file texts and inventory
451
 
     - flat stores
452
 
     - TextStores for revisions and signatures.
453
 
    """
454
 
 
455
 
    _versionedfile_class = weave.WeaveFile
456
 
    _matchingbzrdir = bzrdir.BzrDirFormat5()
457
 
 
458
 
    def __init__(self):
459
 
        super(RepositoryFormat5, self).__init__()
460
 
 
461
 
    def get_format_description(self):
462
 
        """See RepositoryFormat.get_format_description()."""
463
 
        return "Weave repository format 5"
464
 
 
465
 
    def _get_revision_store(self, repo_transport, control_files):
466
 
        """See RepositoryFormat._get_revision_store()."""
467
 
        """Return the revision store object for this a_bzrdir."""
468
 
        return self._get_text_rev_store(repo_transport,
469
 
                                        control_files,
470
 
                                        'revision-store',
471
 
                                        compressed=False)
472
 
 
473
 
    def _get_text_store(self, transport, control_files):
474
 
        """See RepositoryFormat._get_text_store()."""
475
 
        return self._get_versioned_file_store('weaves', transport, control_files, prefixed=False)
476
 
 
477
 
 
478
 
class RepositoryFormat6(PreSplitOutRepositoryFormat):
479
 
    """Bzr control format 6.
480
 
 
481
 
    This repository format has:
482
 
     - weaves for file texts and inventory
483
 
     - hash subdirectory based stores.
484
 
     - TextStores for revisions and signatures.
485
 
    """
486
 
 
487
 
    _versionedfile_class = weave.WeaveFile
488
 
    _matchingbzrdir = bzrdir.BzrDirFormat6()
489
 
 
490
 
    def __init__(self):
491
 
        super(RepositoryFormat6, self).__init__()
492
 
 
493
 
    def get_format_description(self):
494
 
        """See RepositoryFormat.get_format_description()."""
495
 
        return "Weave repository format 6"
496
 
 
497
 
    def _get_revision_store(self, repo_transport, control_files):
498
 
        """See RepositoryFormat._get_revision_store()."""
499
 
        return self._get_text_rev_store(repo_transport,
500
 
                                        control_files,
501
 
                                        'revision-store',
502
 
                                        compressed=False,
503
 
                                        prefixed=True)
504
 
 
505
 
    def _get_text_store(self, transport, control_files):
506
 
        """See RepositoryFormat._get_text_store()."""
507
 
        return self._get_versioned_file_store('weaves', transport, control_files)
508
 
 
509
 
class RepositoryFormat7(MetaDirRepositoryFormat):
510
 
    """Bzr repository 7.
511
 
 
512
 
    This repository format has:
513
 
     - weaves for file texts and inventory
514
 
     - hash subdirectory based stores.
515
 
     - TextStores for revisions and signatures.
516
 
     - a format marker of its own
517
 
     - an optional 'shared-storage' flag
518
 
     - an optional 'no-working-trees' flag
519
 
    """
520
 
 
521
 
    _versionedfile_class = weave.WeaveFile
522
 
 
523
 
    def _get_control_store(self, repo_transport, control_files):
524
 
        """Return the control store for this repository."""
525
 
        return self._get_versioned_file_store('',
526
 
                                              repo_transport,
527
 
                                              control_files,
528
 
                                              prefixed=False)
529
 
 
530
 
    def get_format_string(self):
531
 
        """See RepositoryFormat.get_format_string()."""
532
 
        return "Bazaar-NG Repository format 7"
533
 
 
534
 
    def get_format_description(self):
535
 
        """See RepositoryFormat.get_format_description()."""
536
 
        return "Weave repository format 7"
537
 
 
538
 
    def check_conversion_target(self, target_format):
539
 
        pass
540
 
 
541
 
    def _get_revision_store(self, repo_transport, control_files):
542
 
        """See RepositoryFormat._get_revision_store()."""
543
 
        return self._get_text_rev_store(repo_transport,
544
 
                                        control_files,
545
 
                                        'revision-store',
546
 
                                        compressed=False,
547
 
                                        prefixed=True,
548
 
                                        )
549
 
 
550
 
    def _get_text_store(self, transport, control_files):
551
 
        """See RepositoryFormat._get_text_store()."""
552
 
        return self._get_versioned_file_store('weaves',
553
 
                                              transport,
554
 
                                              control_files)
555
 
 
556
 
    def initialize(self, a_bzrdir, shared=False):
557
 
        """Create a weave repository.
558
 
 
559
 
        :param shared: If true the repository will be initialized as a shared
560
 
                       repository.
561
 
        """
562
 
        # Create an empty weave
563
 
        sio = StringIO()
564
 
        weavefile.write_weave_v5(weave.Weave(), sio)
565
 
        empty_weave = sio.getvalue()
566
 
 
567
 
        mutter('creating repository in %s.', a_bzrdir.transport.base)
568
 
        dirs = ['revision-store', 'weaves']
569
 
        files = [('inventory.weave', StringIO(empty_weave)), 
570
 
                 ]
571
 
        utf8_files = [('format', self.get_format_string())]
572
 
 
573
 
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
574
 
        return self.open(a_bzrdir=a_bzrdir, _found=True)
575
 
 
576
 
    def open(self, a_bzrdir, _found=False, _override_transport=None):
577
 
        """See RepositoryFormat.open().
578
 
        
579
 
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
580
 
                                    repository at a slightly different url
581
 
                                    than normal. I.e. during 'upgrade'.
582
 
        """
583
 
        if not _found:
584
 
            format = RepositoryFormat.find_format(a_bzrdir)
585
 
            assert format.__class__ ==  self.__class__
586
 
        if _override_transport is not None:
587
 
            repo_transport = _override_transport
588
 
        else:
589
 
            repo_transport = a_bzrdir.get_repository_transport(None)
590
 
        control_files = lockable_files.LockableFiles(repo_transport,
591
 
                                'lock', lockdir.LockDir)
592
 
        text_store = self._get_text_store(repo_transport, control_files)
593
 
        control_store = self._get_control_store(repo_transport, control_files)
594
 
        _revision_store = self._get_revision_store(repo_transport, control_files)
595
 
        return WeaveMetaDirRepository(_format=self,
596
 
            a_bzrdir=a_bzrdir,
597
 
            control_files=control_files,
598
 
            _revision_store=_revision_store,
599
 
            control_store=control_store,
600
 
            text_store=text_store)
601
 
 
602
 
 
603
 
class WeaveCommitBuilder(CommitBuilder):
604
 
    """A builder for weave based repos that don't support ghosts."""
605
 
 
606
 
    def _add_text_to_weave(self, file_id, new_lines, parents, nostore_sha):
607
 
        versionedfile = self.repository.weave_store.get_weave_or_empty(
608
 
            file_id, self.repository.get_transaction())
609
 
        result = versionedfile.add_lines(
610
 
            self._new_revision_id, parents, new_lines,
611
 
            nostore_sha=nostore_sha)[0:2]
612
 
        versionedfile.clear_cache()
613
 
        return result
614
 
 
615
 
 
616
 
_legacy_formats = [RepositoryFormat4(),
617
 
                   RepositoryFormat5(),
618
 
                   RepositoryFormat6()]