/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1
# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
16
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
17
"""Deprecated weave-based repository formats.
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
18
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
19
Weave based formats scaled linearly with history size and could not represent
20
ghosts.
21
"""
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
22
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
23
import os
24
from cStringIO import StringIO
25
import urllib
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
26
3224.5.1 by Andrew Bennetts
Lots of assorted hackery to reduce the number of imports for common operations. Improves 'rocks', 'st' and 'help' times by ~50ms on my laptop.
27
from bzrlib.lazy_import import lazy_import
28
lazy_import(globals(), """
29
from bzrlib import (
30
    xml5,
31
    )
32
""")
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
33
from bzrlib import (
34
    bzrdir,
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
35
    debug,
36
    errors,
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
37
    lockable_files,
38
    lockdir,
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
39
    osutils,
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
40
    revision as _mod_revision,
3834.2.2 by Martin Pool
Deprecated LockableFiles._escape
41
    urlutils,
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
42
    versionedfile,
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
43
    weave,
44
    weavefile,
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
45
    )
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
46
from bzrlib.decorators import needs_read_lock, needs_write_lock
47
from bzrlib.repository import (
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
48
    CommitBuilder,
3316.2.3 by Robert Collins
Remove manual notification of transaction finishing on versioned files.
49
    MetaDirVersionedFileRepository,
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
50
    MetaDirRepositoryFormat,
51
    Repository,
52
    RepositoryFormat,
53
    )
54
from bzrlib.store.text import TextStore
55
from bzrlib.trace import mutter
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
56
from bzrlib.tuned_gzip import GzipFile, bytes_to_gzip
57
from bzrlib.versionedfile import (
58
    AbsentContentFactory,
59
    FulltextContentFactory,
60
    VersionedFiles,
61
    )
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
62
63
64
class AllInOneRepository(Repository):
65
    """Legacy support - the repository behaviour for all-in-one branches."""
66
3224.5.1 by Andrew Bennetts
Lots of assorted hackery to reduce the number of imports for common operations. Improves 'rocks', 'st' and 'help' times by ~50ms on my laptop.
67
    @property
68
    def _serializer(self):
69
        return xml5.serializer_v5
2241.1.8 by Martin Pool
Set the repository's serializer in the places it's needed, not in the base class
70
3834.2.2 by Martin Pool
Deprecated LockableFiles._escape
71
    def _escape(self, file_or_path):
72
        if not isinstance(file_or_path, basestring):
73
            file_or_path = '/'.join(file_or_path)
74
        if file_or_path == '':
75
            return u''
76
        return urlutils.escape(osutils.safe_unicode(file_or_path))
77
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
78
    def __init__(self, _format, a_bzrdir):
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
79
        # we reuse one control files instance.
3416.2.3 by Martin Pool
typo
80
        dir_mode = a_bzrdir._get_dir_mode()
81
        file_mode = a_bzrdir._get_file_mode()
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
82
83
        def get_store(name, compressed=True, prefixed=False):
84
            # FIXME: This approach of assuming stores are all entirely compressed
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
85
            # or entirely uncompressed is tidy, but breaks upgrade from
86
            # some existing branches where there's a mixture; we probably
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
87
            # still want the option to look for both.
3834.2.2 by Martin Pool
Deprecated LockableFiles._escape
88
            relpath = self._escape(name)
3407.2.13 by Martin Pool
Remove indirection through control_files to get transports
89
            store = TextStore(a_bzrdir.transport.clone(relpath),
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
90
                              prefixed=prefixed, compressed=compressed,
91
                              dir_mode=dir_mode,
92
                              file_mode=file_mode)
93
            return store
94
95
        # not broken out yet because the controlweaves|inventory_store
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
96
        # and texts bits are still different.
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
97
        if isinstance(_format, RepositoryFormat4):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
98
            # cannot remove these - there is still no consistent api
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
99
            # which allows access to this old info.
100
            self.inventory_store = get_store('inventory-store')
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
101
            self._text_store = get_store('text-store')
102
        super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files)
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
103
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
104
    @needs_read_lock
105
    def _all_possible_ids(self):
106
        """Return all the possible revisions that we could find."""
107
        if 'evil' in debug.debug_flags:
108
            mutter_callsite(3, "_all_possible_ids scales with size of history.")
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
109
        return [key[-1] for key in self.inventories.keys()]
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
110
111
    @needs_read_lock
112
    def _all_revision_ids(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
113
        """Returns a list of all the revision ids in the repository.
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
114
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
115
        These are in as much topological order as the underlying store can
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
116
        present: for weaves ghosts may lead to a lack of correctness until
117
        the reweave updates the parents list.
118
        """
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
119
        return [key[-1] for key in self.revisions.keys()]
120
121
    def _activate_new_inventory(self):
122
        """Put a replacement inventory.new into use as inventories."""
123
        # Copy the content across
124
        t = self.bzrdir._control_files._transport
125
        t.copy('inventory.new.weave', 'inventory.weave')
126
        # delete the temp inventory
127
        t.delete('inventory.new.weave')
128
        # Check we can parse the new weave properly as a sanity check
129
        self.inventories.keys()
130
131
    def _backup_inventory(self):
132
        t = self.bzrdir._control_files._transport
133
        t.copy('inventory.weave', 'inventory.backup.weave')
134
135
    def _temp_inventories(self):
136
        t = self.bzrdir._control_files._transport
137
        return self._format._get_inventories(t, self, 'inventory.new')
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
138
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
139
    def get_commit_builder(self, branch, parents, config, timestamp=None,
140
                           timezone=None, committer=None, revprops=None,
141
                           revision_id=None):
142
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
143
        result = CommitBuilder(self, parents, config, timestamp, timezone,
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
144
                              committer, revprops, revision_id)
145
        self.start_write_group()
146
        return result
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
147
148
    @needs_read_lock
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
149
    def get_revisions(self, revision_ids):
150
        revs = self._get_revisions(revision_ids)
151
        return revs
152
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
153
    def _inventory_add_lines(self, revision_id, parents, lines,
154
        check_content=True):
155
        """Store lines in inv_vf and return the sha1 of the inventory."""
156
        present_parents = self.get_graph().get_parent_map(parents)
157
        final_parents = []
158
        for parent in parents:
159
            if parent in present_parents:
160
                final_parents.append((parent,))
161
        return self.inventories.add_lines((revision_id,), final_parents, lines,
162
            check_content=check_content)[0]
3172.3.1 by Robert Collins
Repository has a new method ``has_revisions`` which signals the presence
163
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
164
    def is_shared(self):
165
        """AllInOne repositories cannot be shared."""
166
        return False
167
168
    @needs_write_lock
169
    def set_make_working_trees(self, new_value):
170
        """Set the policy flag for making working trees when creating branches.
171
172
        This only applies to branches that use this repository.
173
174
        The default is 'True'.
175
        :param new_value: True to restore the default, False to disable making
176
                          working trees.
177
        """
3349.1.2 by Aaron Bentley
Change ValueError to RepositoryUpgradeRequired
178
        raise errors.RepositoryUpgradeRequired(self.bzrdir.root_transport.base)
3349.1.1 by Aaron Bentley
Enable setting and getting make_working_trees for all repositories
179
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
180
    def make_working_trees(self):
181
        """Returns the policy for making working trees on new branches."""
182
        return True
183
2819.2.4 by Andrew Bennetts
Add a 'revision_graph_can_have_wrong_parents' method to repository.
184
    def revision_graph_can_have_wrong_parents(self):
185
        # XXX: This is an old format that we don't support full checking on, so
186
        # just claim that checking for this inconsistency is not required.
187
        return False
188
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
189
3316.2.3 by Robert Collins
Remove manual notification of transaction finishing on versioned files.
190
class WeaveMetaDirRepository(MetaDirVersionedFileRepository):
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
191
    """A subclass of MetaDirRepository to set weave specific policy."""
192
3565.3.1 by Robert Collins
* The generic fetch code now uses two attributes on Repository objects
193
    def __init__(self, _format, a_bzrdir, control_files):
194
        super(WeaveMetaDirRepository, self).__init__(_format, a_bzrdir, control_files)
4022.1.1 by Robert Collins
Refactoring of fetch to have a sender and sink component enabling splitting the logic over a network stream. (Robert Collins, Andrew Bennetts)
195
        self._serializer = _format._serializer
3565.3.1 by Robert Collins
* The generic fetch code now uses two attributes on Repository objects
196
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
197
    @needs_read_lock
198
    def _all_possible_ids(self):
199
        """Return all the possible revisions that we could find."""
200
        if 'evil' in debug.debug_flags:
201
            mutter_callsite(3, "_all_possible_ids scales with size of history.")
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
202
        return [key[-1] for key in self.inventories.keys()]
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
203
204
    @needs_read_lock
205
    def _all_revision_ids(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
206
        """Returns a list of all the revision ids in the repository.
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
207
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
208
        These are in as much topological order as the underlying store can
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
209
        present: for weaves ghosts may lead to a lack of correctness until
210
        the reweave updates the parents list.
211
        """
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
212
        return [key[-1] for key in self.revisions.keys()]
213
214
    def _activate_new_inventory(self):
215
        """Put a replacement inventory.new into use as inventories."""
216
        # Copy the content across
217
        t = self._transport
218
        t.copy('inventory.new.weave', 'inventory.weave')
219
        # delete the temp inventory
220
        t.delete('inventory.new.weave')
221
        # Check we can parse the new weave properly as a sanity check
222
        self.inventories.keys()
223
224
    def _backup_inventory(self):
225
        t = self._transport
226
        t.copy('inventory.weave', 'inventory.backup.weave')
227
228
    def _temp_inventories(self):
229
        t = self._transport
230
        return self._format._get_inventories(t, self, 'inventory.new')
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
231
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
232
    def get_commit_builder(self, branch, parents, config, timestamp=None,
233
                           timezone=None, committer=None, revprops=None,
234
                           revision_id=None):
235
        self._check_ascii_revisionid(revision_id, self.get_commit_builder)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
236
        result = CommitBuilder(self, parents, config, timestamp, timezone,
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
237
                              committer, revprops, revision_id)
238
        self.start_write_group()
239
        return result
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
240
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
241
    @needs_read_lock
242
    def get_revision(self, revision_id):
243
        """Return the Revision object for a named revision"""
244
        r = self.get_revision_reconcile(revision_id)
245
        return r
246
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
247
    def _inventory_add_lines(self, revision_id, parents, lines,
248
        check_content=True):
249
        """Store lines in inv_vf and return the sha1 of the inventory."""
250
        present_parents = self.get_graph().get_parent_map(parents)
251
        final_parents = []
252
        for parent in parents:
253
            if parent in present_parents:
254
                final_parents.append((parent,))
255
        return self.inventories.add_lines((revision_id,), final_parents, lines,
256
            check_content=check_content)[0]
3172.3.1 by Robert Collins
Repository has a new method ``has_revisions`` which signals the presence
257
2819.2.4 by Andrew Bennetts
Add a 'revision_graph_can_have_wrong_parents' method to repository.
258
    def revision_graph_can_have_wrong_parents(self):
259
        return False
260
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
261
262
class PreSplitOutRepositoryFormat(RepositoryFormat):
263
    """Base class for the pre split out repository formats."""
264
265
    rich_root_data = False
2323.5.17 by Martin Pool
Add supports_tree_reference to all repo formats (robert)
266
    supports_tree_reference = False
2949.1.2 by Robert Collins
* Fetch with pack repositories will no longer read the entire history graph.
267
    supports_ghosts = False
3221.3.1 by Robert Collins
* Repository formats have a new supported-feature attribute
268
    supports_external_lookups = False
4246.2.1 by Ian Clatworthy
supports_chks flag on repo formats & log tuning
269
    supports_chks = False
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
270
    _fetch_order = 'topological'
271
    _fetch_reconcile = True
4183.5.1 by Robert Collins
Add RepositoryFormat.fast_deltas to signal fast delta creation.
272
    fast_deltas = False
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
273
274
    def initialize(self, a_bzrdir, shared=False, _internal=False):
2949.1.2 by Robert Collins
* Fetch with pack repositories will no longer read the entire history graph.
275
        """Create a weave repository."""
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
276
        if shared:
277
            raise errors.IncompatibleFormat(self, a_bzrdir._format)
278
279
        if not _internal:
280
            # always initialized when the bzrdir is.
281
            return self.open(a_bzrdir, _found=True)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
282
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
283
        # Create an empty weave
284
        sio = StringIO()
285
        weavefile.write_weave_v5(weave.Weave(), sio)
286
        empty_weave = sio.getvalue()
287
288
        mutter('creating repository in %s.', a_bzrdir.transport.base)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
289
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
290
        # FIXME: RBC 20060125 don't peek under the covers
291
        # NB: no need to escape relative paths that are url safe.
292
        control_files = lockable_files.LockableFiles(a_bzrdir.transport,
3407.2.4 by Martin Pool
Small cleanups to initial creation of repository files
293
            'branch-lock', lockable_files.TransportLock)
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
294
        control_files.create_lock()
295
        control_files.lock_write()
3407.2.13 by Martin Pool
Remove indirection through control_files to get transports
296
        transport = a_bzrdir.transport
3407.2.4 by Martin Pool
Small cleanups to initial creation of repository files
297
        try:
298
            transport.mkdir_multi(['revision-store', 'weaves'],
3407.2.18 by Martin Pool
BzrDir takes responsibility for default file/dir modes
299
                mode=a_bzrdir._get_dir_mode())
300
            transport.put_bytes_non_atomic('inventory.weave', empty_weave,
301
                mode=a_bzrdir._get_file_mode())
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
302
        finally:
303
            control_files.unlock()
304
        return self.open(a_bzrdir, _found=True)
305
306
    def open(self, a_bzrdir, _found=False):
307
        """See RepositoryFormat.open()."""
308
        if not _found:
309
            # we are being called directly and must probe.
310
            raise NotImplementedError
311
312
        repo_transport = a_bzrdir.get_repository_transport(None)
313
        control_files = a_bzrdir._control_files
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
314
        result = AllInOneRepository(_format=self, a_bzrdir=a_bzrdir)
315
        result.revisions = self._get_revisions(repo_transport, result)
316
        result.signatures = self._get_signatures(repo_transport, result)
317
        result.inventories = self._get_inventories(repo_transport, result)
318
        result.texts = self._get_texts(repo_transport, result)
4246.2.1 by Ian Clatworthy
supports_chks flag on repo formats & log tuning
319
        result.chk_bytes = None
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
320
        return result
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
321
322
    def check_conversion_target(self, target_format):
323
        pass
324
325
326
class RepositoryFormat4(PreSplitOutRepositoryFormat):
327
    """Bzr repository format 4.
328
329
    This repository format has:
330
     - flat stores
331
     - TextStores for texts, inventories,revisions.
332
333
    This format is deprecated: it indexes texts using a text id which is
334
    removed in format 5; initialization and write support for this format
335
    has been removed.
336
    """
337
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
338
    _matchingbzrdir = bzrdir.BzrDirFormat4()
339
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
340
    def get_format_description(self):
341
        """See RepositoryFormat.get_format_description()."""
342
        return "Repository format 4"
343
344
    def initialize(self, url, shared=False, _internal=False):
345
        """Format 4 branches cannot be created."""
346
        raise errors.UninitializableFormat(self)
347
348
    def is_supported(self):
349
        """Format 4 is not supported.
350
351
        It is not supported because the model changed from 4 to 5 and the
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
352
        conversion logic is expensive - so doing it on the fly was not
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
353
        feasible.
354
        """
355
        return False
356
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
357
    def _get_inventories(self, repo_transport, repo, name='inventory'):
358
        # No inventories store written so far.
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
359
        return None
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
360
361
    def _get_revisions(self, repo_transport, repo):
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
362
        from bzrlib.xml4 import serializer_v4
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
363
        return RevisionTextStore(repo_transport.clone('revision-store'),
364
            serializer_v4, True, versionedfile.PrefixMapper(),
365
            repo.is_locked, repo.is_write_locked)
366
367
    def _get_signatures(self, repo_transport, repo):
368
        return SignatureTextStore(repo_transport.clone('revision-store'),
369
            False, versionedfile.PrefixMapper(),
370
            repo.is_locked, repo.is_write_locked)
371
372
    def _get_texts(self, repo_transport, repo):
373
        return None
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
374
375
376
class RepositoryFormat5(PreSplitOutRepositoryFormat):
377
    """Bzr control format 5.
378
379
    This repository format has:
380
     - weaves for file texts and inventory
381
     - flat stores
382
     - TextStores for revisions and signatures.
383
    """
384
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
385
    _versionedfile_class = weave.WeaveFile
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
386
    _matchingbzrdir = bzrdir.BzrDirFormat5()
4022.1.1 by Robert Collins
Refactoring of fetch to have a sender and sink component enabling splitting the logic over a network stream. (Robert Collins, Andrew Bennetts)
387
    @property
388
    def _serializer(self):
389
        return xml5.serializer_v5
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
390
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
391
    def get_format_description(self):
392
        """See RepositoryFormat.get_format_description()."""
393
        return "Weave repository format 5"
4032.1.2 by John Arbash Meinel
Track down a few more files that have trailing whitespace.
394
3990.5.1 by Andrew Bennetts
Add network_name() to RepositoryFormat.
395
    def network_name(self):
3990.5.3 by Robert Collins
Docs and polish on RepositoryFormat.network_name.
396
        """The network name for this format is the control dirs disk label."""
3990.5.1 by Andrew Bennetts
Add network_name() to RepositoryFormat.
397
        return self._matchingbzrdir.get_format_string()
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
398
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
399
    def _get_inventories(self, repo_transport, repo, name='inventory'):
400
        mapper = versionedfile.ConstantMapper(name)
401
        return versionedfile.ThunkedVersionedFiles(repo_transport,
402
            weave.WeaveFile, mapper, repo.is_locked)
403
404
    def _get_revisions(self, repo_transport, repo):
405
        return RevisionTextStore(repo_transport.clone('revision-store'),
4022.1.1 by Robert Collins
Refactoring of fetch to have a sender and sink component enabling splitting the logic over a network stream. (Robert Collins, Andrew Bennetts)
406
            xml5.serializer_v5, False, versionedfile.PrefixMapper(),
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
407
            repo.is_locked, repo.is_write_locked)
408
409
    def _get_signatures(self, repo_transport, repo):
410
        return SignatureTextStore(repo_transport.clone('revision-store'),
411
            False, versionedfile.PrefixMapper(),
412
            repo.is_locked, repo.is_write_locked)
413
414
    def _get_texts(self, repo_transport, repo):
415
        mapper = versionedfile.PrefixMapper()
416
        base_transport = repo_transport.clone('weaves')
417
        return versionedfile.ThunkedVersionedFiles(base_transport,
418
            weave.WeaveFile, mapper, repo.is_locked)
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
419
420
421
class RepositoryFormat6(PreSplitOutRepositoryFormat):
422
    """Bzr control format 6.
423
424
    This repository format has:
425
     - weaves for file texts and inventory
426
     - hash subdirectory based stores.
427
     - TextStores for revisions and signatures.
428
    """
429
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
430
    _versionedfile_class = weave.WeaveFile
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
431
    _matchingbzrdir = bzrdir.BzrDirFormat6()
4022.1.1 by Robert Collins
Refactoring of fetch to have a sender and sink component enabling splitting the logic over a network stream. (Robert Collins, Andrew Bennetts)
432
    @property
433
    def _serializer(self):
434
        return xml5.serializer_v5
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
435
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
436
    def get_format_description(self):
437
        """See RepositoryFormat.get_format_description()."""
438
        return "Weave repository format 6"
439
3990.5.1 by Andrew Bennetts
Add network_name() to RepositoryFormat.
440
    def network_name(self):
3990.5.3 by Robert Collins
Docs and polish on RepositoryFormat.network_name.
441
        """The network name for this format is the control dirs disk label."""
3990.5.1 by Andrew Bennetts
Add network_name() to RepositoryFormat.
442
        return self._matchingbzrdir.get_format_string()
443
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
444
    def _get_inventories(self, repo_transport, repo, name='inventory'):
445
        mapper = versionedfile.ConstantMapper(name)
446
        return versionedfile.ThunkedVersionedFiles(repo_transport,
447
            weave.WeaveFile, mapper, repo.is_locked)
448
449
    def _get_revisions(self, repo_transport, repo):
450
        return RevisionTextStore(repo_transport.clone('revision-store'),
4022.1.1 by Robert Collins
Refactoring of fetch to have a sender and sink component enabling splitting the logic over a network stream. (Robert Collins, Andrew Bennetts)
451
            xml5.serializer_v5, False, versionedfile.HashPrefixMapper(),
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
452
            repo.is_locked, repo.is_write_locked)
453
454
    def _get_signatures(self, repo_transport, repo):
455
        return SignatureTextStore(repo_transport.clone('revision-store'),
456
            False, versionedfile.HashPrefixMapper(),
457
            repo.is_locked, repo.is_write_locked)
458
459
    def _get_texts(self, repo_transport, repo):
460
        mapper = versionedfile.HashPrefixMapper()
461
        base_transport = repo_transport.clone('weaves')
462
        return versionedfile.ThunkedVersionedFiles(base_transport,
463
            weave.WeaveFile, mapper, repo.is_locked)
464
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
465
466
class RepositoryFormat7(MetaDirRepositoryFormat):
467
    """Bzr repository 7.
468
469
    This repository format has:
470
     - weaves for file texts and inventory
471
     - hash subdirectory based stores.
472
     - TextStores for revisions and signatures.
473
     - a format marker of its own
474
     - an optional 'shared-storage' flag
475
     - an optional 'no-working-trees' flag
476
    """
477
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
478
    _versionedfile_class = weave.WeaveFile
2949.1.2 by Robert Collins
* Fetch with pack repositories will no longer read the entire history graph.
479
    supports_ghosts = False
4246.2.1 by Ian Clatworthy
supports_chks flag on repo formats & log tuning
480
    supports_chks = False
481
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
482
    _fetch_order = 'topological'
483
    _fetch_reconcile = True
4183.5.1 by Robert Collins
Add RepositoryFormat.fast_deltas to signal fast delta creation.
484
    fast_deltas = False
4022.1.1 by Robert Collins
Refactoring of fetch to have a sender and sink component enabling splitting the logic over a network stream. (Robert Collins, Andrew Bennetts)
485
    @property
486
    def _serializer(self):
487
        return xml5.serializer_v5
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
488
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
489
    def get_format_string(self):
490
        """See RepositoryFormat.get_format_string()."""
491
        return "Bazaar-NG Repository format 7"
492
493
    def get_format_description(self):
494
        """See RepositoryFormat.get_format_description()."""
495
        return "Weave repository format 7"
496
497
    def check_conversion_target(self, target_format):
498
        pass
499
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
500
    def _get_inventories(self, repo_transport, repo, name='inventory'):
501
        mapper = versionedfile.ConstantMapper(name)
502
        return versionedfile.ThunkedVersionedFiles(repo_transport,
503
            weave.WeaveFile, mapper, repo.is_locked)
504
505
    def _get_revisions(self, repo_transport, repo):
506
        return RevisionTextStore(repo_transport.clone('revision-store'),
4022.1.1 by Robert Collins
Refactoring of fetch to have a sender and sink component enabling splitting the logic over a network stream. (Robert Collins, Andrew Bennetts)
507
            xml5.serializer_v5, True, versionedfile.HashPrefixMapper(),
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
508
            repo.is_locked, repo.is_write_locked)
509
510
    def _get_signatures(self, repo_transport, repo):
511
        return SignatureTextStore(repo_transport.clone('revision-store'),
512
            True, versionedfile.HashPrefixMapper(),
513
            repo.is_locked, repo.is_write_locked)
514
515
    def _get_texts(self, repo_transport, repo):
516
        mapper = versionedfile.HashPrefixMapper()
517
        base_transport = repo_transport.clone('weaves')
518
        return versionedfile.ThunkedVersionedFiles(base_transport,
519
            weave.WeaveFile, mapper, repo.is_locked)
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
520
521
    def initialize(self, a_bzrdir, shared=False):
522
        """Create a weave repository.
523
524
        :param shared: If true the repository will be initialized as a shared
525
                       repository.
526
        """
527
        # Create an empty weave
528
        sio = StringIO()
529
        weavefile.write_weave_v5(weave.Weave(), sio)
530
        empty_weave = sio.getvalue()
531
532
        mutter('creating repository in %s.', a_bzrdir.transport.base)
533
        dirs = ['revision-store', 'weaves']
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
534
        files = [('inventory.weave', StringIO(empty_weave)),
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
535
                 ]
536
        utf8_files = [('format', self.get_format_string())]
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
537
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
538
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
539
        return self.open(a_bzrdir=a_bzrdir, _found=True)
540
541
    def open(self, a_bzrdir, _found=False, _override_transport=None):
542
        """See RepositoryFormat.open().
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
543
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
544
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
545
                                    repository at a slightly different url
546
                                    than normal. I.e. during 'upgrade'.
547
        """
548
        if not _found:
549
            format = RepositoryFormat.find_format(a_bzrdir)
550
        if _override_transport is not None:
551
            repo_transport = _override_transport
552
        else:
553
            repo_transport = a_bzrdir.get_repository_transport(None)
554
        control_files = lockable_files.LockableFiles(repo_transport,
555
                                'lock', lockdir.LockDir)
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
556
        result = WeaveMetaDirRepository(_format=self, a_bzrdir=a_bzrdir,
557
            control_files=control_files)
558
        result.revisions = self._get_revisions(repo_transport, result)
559
        result.signatures = self._get_signatures(repo_transport, result)
560
        result.inventories = self._get_inventories(repo_transport, result)
561
        result.texts = self._get_texts(repo_transport, result)
4246.2.1 by Ian Clatworthy
supports_chks flag on repo formats & log tuning
562
        result.chk_bytes = None
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
563
        result._transport = repo_transport
564
        return result
565
566
567
class TextVersionedFiles(VersionedFiles):
568
    """Just-a-bunch-of-files based VersionedFile stores."""
569
570
    def __init__(self, transport, compressed, mapper, is_locked, can_write):
571
        self._compressed = compressed
572
        self._transport = transport
573
        self._mapper = mapper
574
        if self._compressed:
575
            self._ext = '.gz'
576
        else:
577
            self._ext = ''
578
        self._is_locked = is_locked
579
        self._can_write = can_write
580
581
    def add_lines(self, key, parents, lines):
582
        """Add a revision to the store."""
583
        if not self._is_locked():
584
            raise errors.ObjectNotLocked(self)
585
        if not self._can_write():
586
            raise errors.ReadOnlyError(self)
587
        if '/' in key[-1]:
3350.6.10 by Martin Pool
VersionedFiles review cleanups
588
            raise ValueError('bad idea to put / in %r' % (key,))
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
589
        text = ''.join(lines)
590
        if self._compressed:
591
            text = bytes_to_gzip(text)
592
        path = self._map(key)
593
        self._transport.put_bytes_non_atomic(path, text, create_parent_dir=True)
594
595
    def insert_record_stream(self, stream):
596
        adapters = {}
597
        for record in stream:
598
            # Raise an error when a record is missing.
599
            if record.storage_kind == 'absent':
600
                raise errors.RevisionNotPresent([record.key[0]], self)
601
            # adapt to non-tuple interface
602
            if record.storage_kind == 'fulltext':
603
                self.add_lines(record.key, None,
604
                    osutils.split_lines(record.get_bytes_as('fulltext')))
605
            else:
606
                adapter_key = record.storage_kind, 'fulltext'
607
                try:
608
                    adapter = adapters[adapter_key]
609
                except KeyError:
610
                    adapter_factory = adapter_registry.get(adapter_key)
611
                    adapter = adapter_factory(self)
612
                    adapters[adapter_key] = adapter
613
                lines = osutils.split_lines(adapter.get_bytes(
614
                    record, record.get_bytes_as(record.storage_kind)))
615
                try:
616
                    self.add_lines(record.key, None, lines)
617
                except RevisionAlreadyPresent:
618
                    pass
619
620
    def _load_text(self, key):
621
        if not self._is_locked():
622
            raise errors.ObjectNotLocked(self)
623
        path = self._map(key)
624
        try:
625
            text = self._transport.get_bytes(path)
626
            compressed = self._compressed
627
        except errors.NoSuchFile:
628
            if self._compressed:
629
                # try without the .gz
630
                path = path[:-3]
631
                try:
632
                    text = self._transport.get_bytes(path)
633
                    compressed = False
634
                except errors.NoSuchFile:
635
                    return None
636
            else:
637
                return None
638
        if compressed:
639
            text = GzipFile(mode='rb', fileobj=StringIO(text)).read()
640
        return text
641
642
    def _map(self, key):
643
        return self._mapper.map(key) + self._ext
644
645
646
class RevisionTextStore(TextVersionedFiles):
647
    """Legacy thunk for format 4 repositories."""
648
649
    def __init__(self, transport, serializer, compressed, mapper, is_locked,
650
        can_write):
651
        """Create a RevisionTextStore at transport with serializer."""
652
        TextVersionedFiles.__init__(self, transport, compressed, mapper,
653
            is_locked, can_write)
654
        self._serializer = serializer
655
656
    def _load_text_parents(self, key):
657
        text = self._load_text(key)
658
        if text is None:
659
            return None, None
660
        parents = self._serializer.read_revision_from_string(text).parent_ids
661
        return text, tuple((parent,) for parent in parents)
662
663
    def get_parent_map(self, keys):
664
        result = {}
665
        for key in keys:
666
            parents = self._load_text_parents(key)[1]
667
            if parents is None:
668
                continue
669
            result[key] = parents
670
        return result
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
671
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
672
    def get_record_stream(self, keys, sort_order, include_delta_closure):
673
        for key in keys:
674
            text, parents = self._load_text_parents(key)
675
            if text is None:
676
                yield AbsentContentFactory(key)
677
            else:
678
                yield FulltextContentFactory(key, parents, None, text)
679
680
    def keys(self):
681
        if not self._is_locked():
682
            raise errors.ObjectNotLocked(self)
683
        relpaths = set()
684
        for quoted_relpath in self._transport.iter_files_recursive():
685
            relpath = urllib.unquote(quoted_relpath)
686
            path, ext = os.path.splitext(relpath)
687
            if ext == '.gz':
688
                relpath = path
689
            if '.sig' not in relpath:
690
                relpaths.add(relpath)
691
        paths = list(relpaths)
692
        return set([self._mapper.unmap(path) for path in paths])
693
694
695
class SignatureTextStore(TextVersionedFiles):
696
    """Legacy thunk for format 4-7 repositories."""
697
698
    def __init__(self, transport, compressed, mapper, is_locked, can_write):
699
        TextVersionedFiles.__init__(self, transport, compressed, mapper,
700
            is_locked, can_write)
701
        self._ext = '.sig' + self._ext
702
703
    def get_parent_map(self, keys):
704
        result = {}
705
        for key in keys:
706
            text = self._load_text(key)
707
            if text is None:
708
                continue
709
            result[key] = None
710
        return result
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
711
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
712
    def get_record_stream(self, keys, sort_order, include_delta_closure):
713
        for key in keys:
714
            text = self._load_text(key)
715
            if text is None:
716
                yield AbsentContentFactory(key)
717
            else:
718
                yield FulltextContentFactory(key, None, None, text)
719
720
    def keys(self):
721
        if not self._is_locked():
722
            raise errors.ObjectNotLocked(self)
723
        relpaths = set()
724
        for quoted_relpath in self._transport.iter_files_recursive():
725
            relpath = urllib.unquote(quoted_relpath)
726
            path, ext = os.path.splitext(relpath)
727
            if ext == '.gz':
728
                relpath = path
729
            if not relpath.endswith('.sig'):
730
                continue
731
            relpaths.add(relpath[:-4])
732
        paths = list(relpaths)
733
        return set([self._mapper.unmap(path) for path in paths])
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
734
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
735
_legacy_formats = [RepositoryFormat4(),
736
                   RepositoryFormat5(),
737
                   RepositoryFormat6()]