/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: Martin Pool
  • Date: 2007-09-24 06:42:21 UTC
  • mfrom: (2713.2.3 error-exitcode)
  • mto: This revision was merged to the branch mainline in revision 2874.
  • Revision ID: mbp@sourcefrog.net-20070924064221-nu12try0hbilenlj
Return exitcode 4 on internal error

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
    lockable_files,
 
28
    lockdir,
 
29
    osutils,
 
30
    weave,
 
31
    weavefile,
 
32
    xml5,
 
33
    )
 
34
from bzrlib.decorators import needs_read_lock, needs_write_lock
 
35
from bzrlib.repository import (
 
36
    CommitBuilder,
 
37
    MetaDirRepository,
 
38
    MetaDirRepositoryFormat,
 
39
    Repository,
 
40
    RepositoryFormat,
 
41
    )
 
42
from bzrlib.store.text import TextStore
 
43
from bzrlib.trace import mutter
 
44
 
 
45
 
 
46
class AllInOneRepository(Repository):
 
47
    """Legacy support - the repository behaviour for all-in-one branches."""
 
48
 
 
49
    _serializer = xml5.serializer_v5
 
50
 
 
51
    def __init__(self, _format, a_bzrdir, _revision_store, control_store, text_store):
 
52
        # we reuse one control files instance.
 
53
        dir_mode = a_bzrdir._control_files._dir_mode
 
54
        file_mode = a_bzrdir._control_files._file_mode
 
55
 
 
56
        def get_store(name, compressed=True, prefixed=False):
 
57
            # FIXME: This approach of assuming stores are all entirely compressed
 
58
            # or entirely uncompressed is tidy, but breaks upgrade from 
 
59
            # some existing branches where there's a mixture; we probably 
 
60
            # still want the option to look for both.
 
61
            relpath = a_bzrdir._control_files._escape(name)
 
62
            store = TextStore(a_bzrdir._control_files._transport.clone(relpath),
 
63
                              prefixed=prefixed, compressed=compressed,
 
64
                              dir_mode=dir_mode,
 
65
                              file_mode=file_mode)
 
66
            return store
 
67
 
 
68
        # not broken out yet because the controlweaves|inventory_store
 
69
        # and text_store | weave_store bits are still different.
 
70
        if isinstance(_format, RepositoryFormat4):
 
71
            # cannot remove these - there is still no consistent api 
 
72
            # which allows access to this old info.
 
73
            self.inventory_store = get_store('inventory-store')
 
74
            text_store = get_store('text-store')
 
75
        super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files, _revision_store, control_store, text_store)
 
76
 
 
77
    def get_commit_builder(self, branch, parents, config, timestamp=None,
 
78
                           timezone=None, committer=None, revprops=None,
 
79
                           revision_id=None):
 
80
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
 
81
        revision_id = osutils.safe_revision_id(revision_id)
 
82
        result = WeaveCommitBuilder(self, parents, config, timestamp, timezone,
 
83
                              committer, revprops, revision_id)
 
84
        self.start_write_group()
 
85
        return result
 
86
 
 
87
    @needs_read_lock
 
88
    def is_shared(self):
 
89
        """AllInOne repositories cannot be shared."""
 
90
        return False
 
91
 
 
92
    @needs_write_lock
 
93
    def set_make_working_trees(self, new_value):
 
94
        """Set the policy flag for making working trees when creating branches.
 
95
 
 
96
        This only applies to branches that use this repository.
 
97
 
 
98
        The default is 'True'.
 
99
        :param new_value: True to restore the default, False to disable making
 
100
                          working trees.
 
101
        """
 
102
        raise NotImplementedError(self.set_make_working_trees)
 
103
    
 
104
    def make_working_trees(self):
 
105
        """Returns the policy for making working trees on new branches."""
 
106
        return True
 
107
 
 
108
 
 
109
class WeaveMetaDirRepository(MetaDirRepository):
 
110
    """A subclass of MetaDirRepository to set weave specific policy."""
 
111
 
 
112
    _serializer = xml5.serializer_v5
 
113
 
 
114
    def get_commit_builder(self, branch, parents, config, timestamp=None,
 
115
                           timezone=None, committer=None, revprops=None,
 
116
                           revision_id=None):
 
117
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
 
118
        revision_id = osutils.safe_revision_id(revision_id)
 
119
        result = WeaveCommitBuilder(self, parents, config, timestamp, timezone,
 
120
                              committer, revprops, revision_id)
 
121
        self.start_write_group()
 
122
        return result
 
123
 
 
124
 
 
125
class PreSplitOutRepositoryFormat(RepositoryFormat):
 
126
    """Base class for the pre split out repository formats."""
 
127
 
 
128
    rich_root_data = False
 
129
    supports_tree_reference = False
 
130
 
 
131
    def initialize(self, a_bzrdir, shared=False, _internal=False):
 
132
        """Create a weave repository.
 
133
        
 
134
        TODO: when creating split out bzr branch formats, move this to a common
 
135
        base for Format5, Format6. or something like that.
 
136
        """
 
137
        if shared:
 
138
            raise errors.IncompatibleFormat(self, a_bzrdir._format)
 
139
 
 
140
        if not _internal:
 
141
            # always initialized when the bzrdir is.
 
142
            return self.open(a_bzrdir, _found=True)
 
143
        
 
144
        # Create an empty weave
 
145
        sio = StringIO()
 
146
        weavefile.write_weave_v5(weave.Weave(), sio)
 
147
        empty_weave = sio.getvalue()
 
148
 
 
149
        mutter('creating repository in %s.', a_bzrdir.transport.base)
 
150
        dirs = ['revision-store', 'weaves']
 
151
        files = [('inventory.weave', StringIO(empty_weave)),
 
152
                 ]
 
153
        
 
154
        # FIXME: RBC 20060125 don't peek under the covers
 
155
        # NB: no need to escape relative paths that are url safe.
 
156
        control_files = lockable_files.LockableFiles(a_bzrdir.transport,
 
157
                                'branch-lock', lockable_files.TransportLock)
 
158
        control_files.create_lock()
 
159
        control_files.lock_write()
 
160
        control_files._transport.mkdir_multi(dirs,
 
161
                mode=control_files._dir_mode)
 
162
        try:
 
163
            for file, content in files:
 
164
                control_files.put(file, content)
 
165
        finally:
 
166
            control_files.unlock()
 
167
        return self.open(a_bzrdir, _found=True)
 
168
 
 
169
    def _get_control_store(self, repo_transport, control_files):
 
170
        """Return the control store for this repository."""
 
171
        return self._get_versioned_file_store('',
 
172
                                              repo_transport,
 
173
                                              control_files,
 
174
                                              prefixed=False)
 
175
 
 
176
    def _get_text_store(self, transport, control_files):
 
177
        """Get a store for file texts for this format."""
 
178
        raise NotImplementedError(self._get_text_store)
 
179
 
 
180
    def open(self, a_bzrdir, _found=False):
 
181
        """See RepositoryFormat.open()."""
 
182
        if not _found:
 
183
            # we are being called directly and must probe.
 
184
            raise NotImplementedError
 
185
 
 
186
        repo_transport = a_bzrdir.get_repository_transport(None)
 
187
        control_files = a_bzrdir._control_files
 
188
        text_store = self._get_text_store(repo_transport, control_files)
 
189
        control_store = self._get_control_store(repo_transport, control_files)
 
190
        _revision_store = self._get_revision_store(repo_transport, control_files)
 
191
        return AllInOneRepository(_format=self,
 
192
                                  a_bzrdir=a_bzrdir,
 
193
                                  _revision_store=_revision_store,
 
194
                                  control_store=control_store,
 
195
                                  text_store=text_store)
 
196
 
 
197
    def check_conversion_target(self, target_format):
 
198
        pass
 
199
 
 
200
 
 
201
class RepositoryFormat4(PreSplitOutRepositoryFormat):
 
202
    """Bzr repository format 4.
 
203
 
 
204
    This repository format has:
 
205
     - flat stores
 
206
     - TextStores for texts, inventories,revisions.
 
207
 
 
208
    This format is deprecated: it indexes texts using a text id which is
 
209
    removed in format 5; initialization and write support for this format
 
210
    has been removed.
 
211
    """
 
212
 
 
213
    _matchingbzrdir = bzrdir.BzrDirFormat4()
 
214
 
 
215
    def __init__(self):
 
216
        super(RepositoryFormat4, self).__init__()
 
217
 
 
218
    def get_format_description(self):
 
219
        """See RepositoryFormat.get_format_description()."""
 
220
        return "Repository format 4"
 
221
 
 
222
    def initialize(self, url, shared=False, _internal=False):
 
223
        """Format 4 branches cannot be created."""
 
224
        raise errors.UninitializableFormat(self)
 
225
 
 
226
    def is_supported(self):
 
227
        """Format 4 is not supported.
 
228
 
 
229
        It is not supported because the model changed from 4 to 5 and the
 
230
        conversion logic is expensive - so doing it on the fly was not 
 
231
        feasible.
 
232
        """
 
233
        return False
 
234
 
 
235
    def _get_control_store(self, repo_transport, control_files):
 
236
        """Format 4 repositories have no formal control store at this point.
 
237
        
 
238
        This will cause any control-file-needing apis to fail - this is desired.
 
239
        """
 
240
        return None
 
241
    
 
242
    def _get_revision_store(self, repo_transport, control_files):
 
243
        """See RepositoryFormat._get_revision_store()."""
 
244
        from bzrlib.xml4 import serializer_v4
 
245
        return self._get_text_rev_store(repo_transport,
 
246
                                        control_files,
 
247
                                        'revision-store',
 
248
                                        serializer=serializer_v4)
 
249
 
 
250
    def _get_text_store(self, transport, control_files):
 
251
        """See RepositoryFormat._get_text_store()."""
 
252
 
 
253
 
 
254
class RepositoryFormat5(PreSplitOutRepositoryFormat):
 
255
    """Bzr control format 5.
 
256
 
 
257
    This repository format has:
 
258
     - weaves for file texts and inventory
 
259
     - flat stores
 
260
     - TextStores for revisions and signatures.
 
261
    """
 
262
 
 
263
    _versionedfile_class = weave.WeaveFile
 
264
    _matchingbzrdir = bzrdir.BzrDirFormat5()
 
265
 
 
266
    def __init__(self):
 
267
        super(RepositoryFormat5, self).__init__()
 
268
 
 
269
    def get_format_description(self):
 
270
        """See RepositoryFormat.get_format_description()."""
 
271
        return "Weave repository format 5"
 
272
 
 
273
    def _get_revision_store(self, repo_transport, control_files):
 
274
        """See RepositoryFormat._get_revision_store()."""
 
275
        """Return the revision store object for this a_bzrdir."""
 
276
        return self._get_text_rev_store(repo_transport,
 
277
                                        control_files,
 
278
                                        'revision-store',
 
279
                                        compressed=False)
 
280
 
 
281
    def _get_text_store(self, transport, control_files):
 
282
        """See RepositoryFormat._get_text_store()."""
 
283
        return self._get_versioned_file_store('weaves', transport, control_files, prefixed=False)
 
284
 
 
285
 
 
286
class RepositoryFormat6(PreSplitOutRepositoryFormat):
 
287
    """Bzr control format 6.
 
288
 
 
289
    This repository format has:
 
290
     - weaves for file texts and inventory
 
291
     - hash subdirectory based stores.
 
292
     - TextStores for revisions and signatures.
 
293
    """
 
294
 
 
295
    _versionedfile_class = weave.WeaveFile
 
296
    _matchingbzrdir = bzrdir.BzrDirFormat6()
 
297
 
 
298
    def __init__(self):
 
299
        super(RepositoryFormat6, self).__init__()
 
300
 
 
301
    def get_format_description(self):
 
302
        """See RepositoryFormat.get_format_description()."""
 
303
        return "Weave repository format 6"
 
304
 
 
305
    def _get_revision_store(self, repo_transport, control_files):
 
306
        """See RepositoryFormat._get_revision_store()."""
 
307
        return self._get_text_rev_store(repo_transport,
 
308
                                        control_files,
 
309
                                        'revision-store',
 
310
                                        compressed=False,
 
311
                                        prefixed=True)
 
312
 
 
313
    def _get_text_store(self, transport, control_files):
 
314
        """See RepositoryFormat._get_text_store()."""
 
315
        return self._get_versioned_file_store('weaves', transport, control_files)
 
316
 
 
317
 
 
318
class RepositoryFormat7(MetaDirRepositoryFormat):
 
319
    """Bzr repository 7.
 
320
 
 
321
    This repository format has:
 
322
     - weaves for file texts and inventory
 
323
     - hash subdirectory based stores.
 
324
     - TextStores for revisions and signatures.
 
325
     - a format marker of its own
 
326
     - an optional 'shared-storage' flag
 
327
     - an optional 'no-working-trees' flag
 
328
    """
 
329
 
 
330
    _versionedfile_class = weave.WeaveFile
 
331
 
 
332
    def _get_control_store(self, repo_transport, control_files):
 
333
        """Return the control store for this repository."""
 
334
        return self._get_versioned_file_store('',
 
335
                                              repo_transport,
 
336
                                              control_files,
 
337
                                              prefixed=False)
 
338
 
 
339
    def get_format_string(self):
 
340
        """See RepositoryFormat.get_format_string()."""
 
341
        return "Bazaar-NG Repository format 7"
 
342
 
 
343
    def get_format_description(self):
 
344
        """See RepositoryFormat.get_format_description()."""
 
345
        return "Weave repository format 7"
 
346
 
 
347
    def check_conversion_target(self, target_format):
 
348
        pass
 
349
 
 
350
    def _get_revision_store(self, repo_transport, control_files):
 
351
        """See RepositoryFormat._get_revision_store()."""
 
352
        return self._get_text_rev_store(repo_transport,
 
353
                                        control_files,
 
354
                                        'revision-store',
 
355
                                        compressed=False,
 
356
                                        prefixed=True,
 
357
                                        )
 
358
 
 
359
    def _get_text_store(self, transport, control_files):
 
360
        """See RepositoryFormat._get_text_store()."""
 
361
        return self._get_versioned_file_store('weaves',
 
362
                                              transport,
 
363
                                              control_files)
 
364
 
 
365
    def initialize(self, a_bzrdir, shared=False):
 
366
        """Create a weave repository.
 
367
 
 
368
        :param shared: If true the repository will be initialized as a shared
 
369
                       repository.
 
370
        """
 
371
        # Create an empty weave
 
372
        sio = StringIO()
 
373
        weavefile.write_weave_v5(weave.Weave(), sio)
 
374
        empty_weave = sio.getvalue()
 
375
 
 
376
        mutter('creating repository in %s.', a_bzrdir.transport.base)
 
377
        dirs = ['revision-store', 'weaves']
 
378
        files = [('inventory.weave', StringIO(empty_weave)), 
 
379
                 ]
 
380
        utf8_files = [('format', self.get_format_string())]
 
381
 
 
382
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
 
383
        return self.open(a_bzrdir=a_bzrdir, _found=True)
 
384
 
 
385
    def open(self, a_bzrdir, _found=False, _override_transport=None):
 
386
        """See RepositoryFormat.open().
 
387
        
 
388
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
 
389
                                    repository at a slightly different url
 
390
                                    than normal. I.e. during 'upgrade'.
 
391
        """
 
392
        if not _found:
 
393
            format = RepositoryFormat.find_format(a_bzrdir)
 
394
            assert format.__class__ ==  self.__class__
 
395
        if _override_transport is not None:
 
396
            repo_transport = _override_transport
 
397
        else:
 
398
            repo_transport = a_bzrdir.get_repository_transport(None)
 
399
        control_files = lockable_files.LockableFiles(repo_transport,
 
400
                                'lock', lockdir.LockDir)
 
401
        text_store = self._get_text_store(repo_transport, control_files)
 
402
        control_store = self._get_control_store(repo_transport, control_files)
 
403
        _revision_store = self._get_revision_store(repo_transport, control_files)
 
404
        return WeaveMetaDirRepository(_format=self,
 
405
            a_bzrdir=a_bzrdir,
 
406
            control_files=control_files,
 
407
            _revision_store=_revision_store,
 
408
            control_store=control_store,
 
409
            text_store=text_store)
 
410
 
 
411
 
 
412
class WeaveCommitBuilder(CommitBuilder):
 
413
    """A builder for weave based repos that don't support ghosts."""
 
414
 
 
415
    def _add_text_to_weave(self, file_id, new_lines, parents):
 
416
        versionedfile = self.repository.weave_store.get_weave_or_empty(
 
417
            file_id, self.repository.get_transaction())
 
418
        result = versionedfile.add_lines(
 
419
            self._new_revision_id, parents, new_lines)[0:2]
 
420
        versionedfile.clear_cache()
 
421
        return result
 
422
 
 
423
 
 
424
_legacy_formats = [RepositoryFormat4(),
 
425
                   RepositoryFormat5(),
 
426
                   RepositoryFormat6()]