/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

Implement _bisect_recursive, which uses multiple bisect calls to
handle renames and finding entries in subdirs.
As is, this could be hooked into paths2ids() if the dirstate has not been loaded yet.
However, it doesn't quite provide enough, since the parsed entries would probably not
be saved. Further, the multiple bisect calls are less efficient then they could be,
because they do not remember the last bisect call.
We should explore switching to a caching structure, which maintains all records that
have been processed, in a structure that can be in-memory searched before going back
to disk.

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