/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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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)
3565.3.1 by Robert Collins
* The generic fetch code now uses two attributes on Repository objects
103
        self._fetch_order = 'topological'
3565.3.4 by Robert Collins
Defer decision to reconcile to the repository being fetched into.
104
        self._fetch_reconcile = True
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
105
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
106
    @needs_read_lock
107
    def _all_possible_ids(self):
108
        """Return all the possible revisions that we could find."""
109
        if 'evil' in debug.debug_flags:
110
            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.
111
        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.
112
113
    @needs_read_lock
114
    def _all_revision_ids(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
115
        """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.
116
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
117
        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.
118
        present: for weaves ghosts may lead to a lack of correctness until
119
        the reweave updates the parents list.
120
        """
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.
121
        return [key[-1] for key in self.revisions.keys()]
122
123
    def _activate_new_inventory(self):
124
        """Put a replacement inventory.new into use as inventories."""
125
        # Copy the content across
126
        t = self.bzrdir._control_files._transport
127
        t.copy('inventory.new.weave', 'inventory.weave')
128
        # delete the temp inventory
129
        t.delete('inventory.new.weave')
130
        # Check we can parse the new weave properly as a sanity check
131
        self.inventories.keys()
132
133
    def _backup_inventory(self):
134
        t = self.bzrdir._control_files._transport
135
        t.copy('inventory.weave', 'inventory.backup.weave')
136
137
    def _temp_inventories(self):
138
        t = self.bzrdir._control_files._transport
139
        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.
140
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
141
    def get_commit_builder(self, branch, parents, config, timestamp=None,
142
                           timezone=None, committer=None, revprops=None,
143
                           revision_id=None):
144
        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.
145
        result = CommitBuilder(self, parents, config, timestamp, timezone,
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
146
                              committer, revprops, revision_id)
147
        self.start_write_group()
148
        return result
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
149
150
    @needs_read_lock
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
151
    def get_revisions(self, revision_ids):
152
        revs = self._get_revisions(revision_ids)
153
        return revs
154
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.
155
    def _inventory_add_lines(self, revision_id, parents, lines,
156
        check_content=True):
157
        """Store lines in inv_vf and return the sha1 of the inventory."""
158
        present_parents = self.get_graph().get_parent_map(parents)
159
        final_parents = []
160
        for parent in parents:
161
            if parent in present_parents:
162
                final_parents.append((parent,))
163
        return self.inventories.add_lines((revision_id,), final_parents, lines,
164
            check_content=check_content)[0]
3172.3.1 by Robert Collins
Repository has a new method ``has_revisions`` which signals the presence
165
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
166
    def is_shared(self):
167
        """AllInOne repositories cannot be shared."""
168
        return False
169
170
    @needs_write_lock
171
    def set_make_working_trees(self, new_value):
172
        """Set the policy flag for making working trees when creating branches.
173
174
        This only applies to branches that use this repository.
175
176
        The default is 'True'.
177
        :param new_value: True to restore the default, False to disable making
178
                          working trees.
179
        """
3349.1.2 by Aaron Bentley
Change ValueError to RepositoryUpgradeRequired
180
        raise errors.RepositoryUpgradeRequired(self.bzrdir.root_transport.base)
3349.1.1 by Aaron Bentley
Enable setting and getting make_working_trees for all repositories
181
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
182
    def make_working_trees(self):
183
        """Returns the policy for making working trees on new branches."""
184
        return True
185
2819.2.4 by Andrew Bennetts
Add a 'revision_graph_can_have_wrong_parents' method to repository.
186
    def revision_graph_can_have_wrong_parents(self):
187
        # XXX: This is an old format that we don't support full checking on, so
188
        # just claim that checking for this inconsistency is not required.
189
        return False
190
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
191
3316.2.3 by Robert Collins
Remove manual notification of transaction finishing on versioned files.
192
class WeaveMetaDirRepository(MetaDirVersionedFileRepository):
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
193
    """A subclass of MetaDirRepository to set weave specific policy."""
194
3565.3.1 by Robert Collins
* The generic fetch code now uses two attributes on Repository objects
195
    def __init__(self, _format, a_bzrdir, control_files):
196
        super(WeaveMetaDirRepository, self).__init__(_format, a_bzrdir, control_files)
197
        self._fetch_order = 'topological'
3565.3.4 by Robert Collins
Defer decision to reconcile to the repository being fetched into.
198
        self._fetch_reconcile = True
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)
199
        self._serializer = _format._serializer
3565.3.1 by Robert Collins
* The generic fetch code now uses two attributes on Repository objects
200
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
201
    @needs_read_lock
202
    def _all_possible_ids(self):
203
        """Return all the possible revisions that we could find."""
204
        if 'evil' in debug.debug_flags:
205
            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.
206
        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.
207
208
    @needs_read_lock
209
    def _all_revision_ids(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
210
        """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.
211
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
212
        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.
213
        present: for weaves ghosts may lead to a lack of correctness until
214
        the reweave updates the parents list.
215
        """
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.
216
        return [key[-1] for key in self.revisions.keys()]
217
218
    def _activate_new_inventory(self):
219
        """Put a replacement inventory.new into use as inventories."""
220
        # Copy the content across
221
        t = self._transport
222
        t.copy('inventory.new.weave', 'inventory.weave')
223
        # delete the temp inventory
224
        t.delete('inventory.new.weave')
225
        # Check we can parse the new weave properly as a sanity check
226
        self.inventories.keys()
227
228
    def _backup_inventory(self):
229
        t = self._transport
230
        t.copy('inventory.weave', 'inventory.backup.weave')
231
232
    def _temp_inventories(self):
233
        t = self._transport
234
        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.
235
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
236
    def get_commit_builder(self, branch, parents, config, timestamp=None,
237
                           timezone=None, committer=None, revprops=None,
238
                           revision_id=None):
239
        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.
240
        result = CommitBuilder(self, parents, config, timestamp, timezone,
2803.2.1 by Robert Collins
* CommitBuilder now advertises itself as requiring the root entry to be
241
                              committer, revprops, revision_id)
242
        self.start_write_group()
243
        return result
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
244
2850.3.1 by Robert Collins
Move various weave specific code out of the base Repository class to weaverepo.py.
245
    @needs_read_lock
246
    def get_revision(self, revision_id):
247
        """Return the Revision object for a named revision"""
248
        r = self.get_revision_reconcile(revision_id)
249
        return r
250
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.
251
    def _inventory_add_lines(self, revision_id, parents, lines,
252
        check_content=True):
253
        """Store lines in inv_vf and return the sha1 of the inventory."""
254
        present_parents = self.get_graph().get_parent_map(parents)
255
        final_parents = []
256
        for parent in parents:
257
            if parent in present_parents:
258
                final_parents.append((parent,))
259
        return self.inventories.add_lines((revision_id,), final_parents, lines,
260
            check_content=check_content)[0]
3172.3.1 by Robert Collins
Repository has a new method ``has_revisions`` which signals the presence
261
2819.2.4 by Andrew Bennetts
Add a 'revision_graph_can_have_wrong_parents' method to repository.
262
    def revision_graph_can_have_wrong_parents(self):
263
        return False
264
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
265
266
class PreSplitOutRepositoryFormat(RepositoryFormat):
267
    """Base class for the pre split out repository formats."""
268
269
    rich_root_data = False
2323.5.17 by Martin Pool
Add supports_tree_reference to all repo formats (robert)
270
    supports_tree_reference = False
2949.1.2 by Robert Collins
* Fetch with pack repositories will no longer read the entire history graph.
271
    supports_ghosts = False
3221.3.1 by Robert Collins
* Repository formats have a new supported-feature attribute
272
    supports_external_lookups = 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'],
3446.1.1 by Martin Pool
merge further LockableFile deprecations
299
                mode=a_bzrdir._get_dir_mode())
3407.2.4 by Martin Pool
Small cleanups to initial creation of repository files
300
            transport.put_bytes_non_atomic('inventory.weave', empty_weave)
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
301
        finally:
302
            control_files.unlock()
303
        return self.open(a_bzrdir, _found=True)
304
305
    def open(self, a_bzrdir, _found=False):
306
        """See RepositoryFormat.open()."""
307
        if not _found:
308
            # we are being called directly and must probe.
309
            raise NotImplementedError
310
311
        repo_transport = a_bzrdir.get_repository_transport(None)
312
        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.
313
        result = AllInOneRepository(_format=self, a_bzrdir=a_bzrdir)
314
        result.revisions = self._get_revisions(repo_transport, result)
315
        result.signatures = self._get_signatures(repo_transport, result)
316
        result.inventories = self._get_inventories(repo_transport, result)
317
        result.texts = self._get_texts(repo_transport, result)
318
        return result
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
319
320
    def check_conversion_target(self, target_format):
321
        pass
322
323
324
class RepositoryFormat4(PreSplitOutRepositoryFormat):
325
    """Bzr repository format 4.
326
327
    This repository format has:
328
     - flat stores
329
     - TextStores for texts, inventories,revisions.
330
331
    This format is deprecated: it indexes texts using a text id which is
332
    removed in format 5; initialization and write support for this format
333
    has been removed.
334
    """
335
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
336
    _matchingbzrdir = bzrdir.BzrDirFormat4()
337
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
338
    def __init__(self):
339
        super(RepositoryFormat4, self).__init__()
3565.3.1 by Robert Collins
* The generic fetch code now uses two attributes on Repository objects
340
        self._fetch_order = 'topological'
3565.3.4 by Robert Collins
Defer decision to reconcile to the repository being fetched into.
341
        self._fetch_reconcile = True
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
342
343
    def get_format_description(self):
344
        """See RepositoryFormat.get_format_description()."""
345
        return "Repository format 4"
346
347
    def initialize(self, url, shared=False, _internal=False):
348
        """Format 4 branches cannot be created."""
349
        raise errors.UninitializableFormat(self)
350
351
    def is_supported(self):
352
        """Format 4 is not supported.
353
354
        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
355
        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.
356
        feasible.
357
        """
358
        return False
359
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
    def _get_inventories(self, repo_transport, repo, name='inventory'):
361
        # No inventories store written so far.
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
362
        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.
363
364
    def _get_revisions(self, repo_transport, repo):
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
365
        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.
366
        return RevisionTextStore(repo_transport.clone('revision-store'),
367
            serializer_v4, True, versionedfile.PrefixMapper(),
368
            repo.is_locked, repo.is_write_locked)
369
370
    def _get_signatures(self, repo_transport, repo):
371
        return SignatureTextStore(repo_transport.clone('revision-store'),
372
            False, versionedfile.PrefixMapper(),
373
            repo.is_locked, repo.is_write_locked)
374
375
    def _get_texts(self, repo_transport, repo):
376
        return None
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
377
378
379
class RepositoryFormat5(PreSplitOutRepositoryFormat):
380
    """Bzr control format 5.
381
382
    This repository format has:
383
     - weaves for file texts and inventory
384
     - flat stores
385
     - TextStores for revisions and signatures.
386
    """
387
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
388
    _versionedfile_class = weave.WeaveFile
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
389
    _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)
390
    @property
391
    def _serializer(self):
392
        return xml5.serializer_v5
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
393
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
394
    def __init__(self):
395
        super(RepositoryFormat5, self).__init__()
3565.3.1 by Robert Collins
* The generic fetch code now uses two attributes on Repository objects
396
        self._fetch_order = 'topological'
3565.3.4 by Robert Collins
Defer decision to reconcile to the repository being fetched into.
397
        self._fetch_reconcile = True
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
398
399
    def get_format_description(self):
400
        """See RepositoryFormat.get_format_description()."""
401
        return "Weave repository format 5"
4032.1.2 by John Arbash Meinel
Track down a few more files that have trailing whitespace.
402
3990.5.1 by Andrew Bennetts
Add network_name() to RepositoryFormat.
403
    def network_name(self):
3990.5.3 by Robert Collins
Docs and polish on RepositoryFormat.network_name.
404
        """The network name for this format is the control dirs disk label."""
3990.5.1 by Andrew Bennetts
Add network_name() to RepositoryFormat.
405
        return self._matchingbzrdir.get_format_string()
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
406
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
    def _get_inventories(self, repo_transport, repo, name='inventory'):
408
        mapper = versionedfile.ConstantMapper(name)
409
        return versionedfile.ThunkedVersionedFiles(repo_transport,
410
            weave.WeaveFile, mapper, repo.is_locked)
411
412
    def _get_revisions(self, repo_transport, repo):
413
        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)
414
            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.
415
            repo.is_locked, repo.is_write_locked)
416
417
    def _get_signatures(self, repo_transport, repo):
418
        return SignatureTextStore(repo_transport.clone('revision-store'),
419
            False, versionedfile.PrefixMapper(),
420
            repo.is_locked, repo.is_write_locked)
421
422
    def _get_texts(self, repo_transport, repo):
423
        mapper = versionedfile.PrefixMapper()
424
        base_transport = repo_transport.clone('weaves')
425
        return versionedfile.ThunkedVersionedFiles(base_transport,
426
            weave.WeaveFile, mapper, repo.is_locked)
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
427
428
429
class RepositoryFormat6(PreSplitOutRepositoryFormat):
430
    """Bzr control format 6.
431
432
    This repository format has:
433
     - weaves for file texts and inventory
434
     - hash subdirectory based stores.
435
     - TextStores for revisions and signatures.
436
    """
437
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
438
    _versionedfile_class = weave.WeaveFile
2241.1.11 by Martin Pool
Get rid of RepositoryFormat*_instance objects. Instead the format
439
    _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)
440
    @property
441
    def _serializer(self):
442
        return xml5.serializer_v5
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
443
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
444
    def __init__(self):
445
        super(RepositoryFormat6, self).__init__()
3565.3.1 by Robert Collins
* The generic fetch code now uses two attributes on Repository objects
446
        self._fetch_order = 'topological'
3565.3.4 by Robert Collins
Defer decision to reconcile to the repository being fetched into.
447
        self._fetch_reconcile = True
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
448
449
    def get_format_description(self):
450
        """See RepositoryFormat.get_format_description()."""
451
        return "Weave repository format 6"
452
3990.5.1 by Andrew Bennetts
Add network_name() to RepositoryFormat.
453
    def network_name(self):
3990.5.3 by Robert Collins
Docs and polish on RepositoryFormat.network_name.
454
        """The network name for this format is the control dirs disk label."""
3990.5.1 by Andrew Bennetts
Add network_name() to RepositoryFormat.
455
        return self._matchingbzrdir.get_format_string()
456
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.
457
    def _get_inventories(self, repo_transport, repo, name='inventory'):
458
        mapper = versionedfile.ConstantMapper(name)
459
        return versionedfile.ThunkedVersionedFiles(repo_transport,
460
            weave.WeaveFile, mapper, repo.is_locked)
461
462
    def _get_revisions(self, repo_transport, repo):
463
        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)
464
            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.
465
            repo.is_locked, repo.is_write_locked)
466
467
    def _get_signatures(self, repo_transport, repo):
468
        return SignatureTextStore(repo_transport.clone('revision-store'),
469
            False, versionedfile.HashPrefixMapper(),
470
            repo.is_locked, repo.is_write_locked)
471
472
    def _get_texts(self, repo_transport, repo):
473
        mapper = versionedfile.HashPrefixMapper()
474
        base_transport = repo_transport.clone('weaves')
475
        return versionedfile.ThunkedVersionedFiles(base_transport,
476
            weave.WeaveFile, mapper, repo.is_locked)
477
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
478
479
class RepositoryFormat7(MetaDirRepositoryFormat):
480
    """Bzr repository 7.
481
482
    This repository format has:
483
     - weaves for file texts and inventory
484
     - hash subdirectory based stores.
485
     - TextStores for revisions and signatures.
486
     - a format marker of its own
487
     - an optional 'shared-storage' flag
488
     - an optional 'no-working-trees' flag
489
    """
490
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
491
    _versionedfile_class = weave.WeaveFile
2949.1.2 by Robert Collins
* Fetch with pack repositories will no longer read the entire history graph.
492
    supports_ghosts = 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)
493
    @property
494
    def _serializer(self):
495
        return xml5.serializer_v5
2241.1.10 by Martin Pool
Remove more references to weaves from the repository.py file
496
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
497
    def get_format_string(self):
498
        """See RepositoryFormat.get_format_string()."""
499
        return "Bazaar-NG Repository format 7"
500
501
    def get_format_description(self):
502
        """See RepositoryFormat.get_format_description()."""
503
        return "Weave repository format 7"
504
505
    def check_conversion_target(self, target_format):
506
        pass
507
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
    def _get_inventories(self, repo_transport, repo, name='inventory'):
509
        mapper = versionedfile.ConstantMapper(name)
510
        return versionedfile.ThunkedVersionedFiles(repo_transport,
511
            weave.WeaveFile, mapper, repo.is_locked)
512
513
    def _get_revisions(self, repo_transport, repo):
514
        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)
515
            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.
516
            repo.is_locked, repo.is_write_locked)
517
518
    def _get_signatures(self, repo_transport, repo):
519
        return SignatureTextStore(repo_transport.clone('revision-store'),
520
            True, versionedfile.HashPrefixMapper(),
521
            repo.is_locked, repo.is_write_locked)
522
523
    def _get_texts(self, repo_transport, repo):
524
        mapper = versionedfile.HashPrefixMapper()
525
        base_transport = repo_transport.clone('weaves')
526
        return versionedfile.ThunkedVersionedFiles(base_transport,
527
            weave.WeaveFile, mapper, repo.is_locked)
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
528
529
    def initialize(self, a_bzrdir, shared=False):
530
        """Create a weave repository.
531
532
        :param shared: If true the repository will be initialized as a shared
533
                       repository.
534
        """
535
        # Create an empty weave
536
        sio = StringIO()
537
        weavefile.write_weave_v5(weave.Weave(), sio)
538
        empty_weave = sio.getvalue()
539
540
        mutter('creating repository in %s.', a_bzrdir.transport.base)
541
        dirs = ['revision-store', 'weaves']
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
542
        files = [('inventory.weave', StringIO(empty_weave)),
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
543
                 ]
544
        utf8_files = [('format', self.get_format_string())]
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
545
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
546
        self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
547
        return self.open(a_bzrdir=a_bzrdir, _found=True)
548
549
    def open(self, a_bzrdir, _found=False, _override_transport=None):
550
        """See RepositoryFormat.open().
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
551
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
552
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
553
                                    repository at a slightly different url
554
                                    than normal. I.e. during 'upgrade'.
555
        """
556
        if not _found:
557
            format = RepositoryFormat.find_format(a_bzrdir)
558
        if _override_transport is not None:
559
            repo_transport = _override_transport
560
        else:
561
            repo_transport = a_bzrdir.get_repository_transport(None)
562
        control_files = lockable_files.LockableFiles(repo_transport,
563
                                '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.
564
        result = WeaveMetaDirRepository(_format=self, a_bzrdir=a_bzrdir,
565
            control_files=control_files)
566
        result.revisions = self._get_revisions(repo_transport, result)
567
        result.signatures = self._get_signatures(repo_transport, result)
568
        result.inventories = self._get_inventories(repo_transport, result)
569
        result.texts = self._get_texts(repo_transport, result)
570
        result._transport = repo_transport
571
        return result
572
573
574
class TextVersionedFiles(VersionedFiles):
575
    """Just-a-bunch-of-files based VersionedFile stores."""
576
577
    def __init__(self, transport, compressed, mapper, is_locked, can_write):
578
        self._compressed = compressed
579
        self._transport = transport
580
        self._mapper = mapper
581
        if self._compressed:
582
            self._ext = '.gz'
583
        else:
584
            self._ext = ''
585
        self._is_locked = is_locked
586
        self._can_write = can_write
587
588
    def add_lines(self, key, parents, lines):
589
        """Add a revision to the store."""
590
        if not self._is_locked():
591
            raise errors.ObjectNotLocked(self)
592
        if not self._can_write():
593
            raise errors.ReadOnlyError(self)
594
        if '/' in key[-1]:
3350.6.10 by Martin Pool
VersionedFiles review cleanups
595
            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.
596
        text = ''.join(lines)
597
        if self._compressed:
598
            text = bytes_to_gzip(text)
599
        path = self._map(key)
600
        self._transport.put_bytes_non_atomic(path, text, create_parent_dir=True)
601
602
    def insert_record_stream(self, stream):
603
        adapters = {}
604
        for record in stream:
605
            # Raise an error when a record is missing.
606
            if record.storage_kind == 'absent':
607
                raise errors.RevisionNotPresent([record.key[0]], self)
608
            # adapt to non-tuple interface
609
            if record.storage_kind == 'fulltext':
610
                self.add_lines(record.key, None,
611
                    osutils.split_lines(record.get_bytes_as('fulltext')))
612
            else:
613
                adapter_key = record.storage_kind, 'fulltext'
614
                try:
615
                    adapter = adapters[adapter_key]
616
                except KeyError:
617
                    adapter_factory = adapter_registry.get(adapter_key)
618
                    adapter = adapter_factory(self)
619
                    adapters[adapter_key] = adapter
620
                lines = osutils.split_lines(adapter.get_bytes(
621
                    record, record.get_bytes_as(record.storage_kind)))
622
                try:
623
                    self.add_lines(record.key, None, lines)
624
                except RevisionAlreadyPresent:
625
                    pass
626
627
    def _load_text(self, key):
628
        if not self._is_locked():
629
            raise errors.ObjectNotLocked(self)
630
        path = self._map(key)
631
        try:
632
            text = self._transport.get_bytes(path)
633
            compressed = self._compressed
634
        except errors.NoSuchFile:
635
            if self._compressed:
636
                # try without the .gz
637
                path = path[:-3]
638
                try:
639
                    text = self._transport.get_bytes(path)
640
                    compressed = False
641
                except errors.NoSuchFile:
642
                    return None
643
            else:
644
                return None
645
        if compressed:
646
            text = GzipFile(mode='rb', fileobj=StringIO(text)).read()
647
        return text
648
649
    def _map(self, key):
650
        return self._mapper.map(key) + self._ext
651
652
653
class RevisionTextStore(TextVersionedFiles):
654
    """Legacy thunk for format 4 repositories."""
655
656
    def __init__(self, transport, serializer, compressed, mapper, is_locked,
657
        can_write):
658
        """Create a RevisionTextStore at transport with serializer."""
659
        TextVersionedFiles.__init__(self, transport, compressed, mapper,
660
            is_locked, can_write)
661
        self._serializer = serializer
662
663
    def _load_text_parents(self, key):
664
        text = self._load_text(key)
665
        if text is None:
666
            return None, None
667
        parents = self._serializer.read_revision_from_string(text).parent_ids
668
        return text, tuple((parent,) for parent in parents)
669
670
    def get_parent_map(self, keys):
671
        result = {}
672
        for key in keys:
673
            parents = self._load_text_parents(key)[1]
674
            if parents is None:
675
                continue
676
            result[key] = parents
677
        return result
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
678
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.
679
    def get_record_stream(self, keys, sort_order, include_delta_closure):
680
        for key in keys:
681
            text, parents = self._load_text_parents(key)
682
            if text is None:
683
                yield AbsentContentFactory(key)
684
            else:
685
                yield FulltextContentFactory(key, parents, None, text)
686
687
    def keys(self):
688
        if not self._is_locked():
689
            raise errors.ObjectNotLocked(self)
690
        relpaths = set()
691
        for quoted_relpath in self._transport.iter_files_recursive():
692
            relpath = urllib.unquote(quoted_relpath)
693
            path, ext = os.path.splitext(relpath)
694
            if ext == '.gz':
695
                relpath = path
696
            if '.sig' not in relpath:
697
                relpaths.add(relpath)
698
        paths = list(relpaths)
699
        return set([self._mapper.unmap(path) for path in paths])
700
701
702
class SignatureTextStore(TextVersionedFiles):
703
    """Legacy thunk for format 4-7 repositories."""
704
705
    def __init__(self, transport, compressed, mapper, is_locked, can_write):
706
        TextVersionedFiles.__init__(self, transport, compressed, mapper,
707
            is_locked, can_write)
708
        self._ext = '.sig' + self._ext
709
710
    def get_parent_map(self, keys):
711
        result = {}
712
        for key in keys:
713
            text = self._load_text(key)
714
            if text is None:
715
                continue
716
            result[key] = None
717
        return result
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
718
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.
719
    def get_record_stream(self, keys, sort_order, include_delta_closure):
720
        for key in keys:
721
            text = self._load_text(key)
722
            if text is None:
723
                yield AbsentContentFactory(key)
724
            else:
725
                yield FulltextContentFactory(key, None, None, text)
726
727
    def keys(self):
728
        if not self._is_locked():
729
            raise errors.ObjectNotLocked(self)
730
        relpaths = set()
731
        for quoted_relpath in self._transport.iter_files_recursive():
732
            relpath = urllib.unquote(quoted_relpath)
733
            path, ext = os.path.splitext(relpath)
734
            if ext == '.gz':
735
                relpath = path
736
            if not relpath.endswith('.sig'):
737
                continue
738
            relpaths.add(relpath[:-4])
739
        paths = list(relpaths)
740
        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
741
2241.1.4 by Martin Pool
Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.
742
_legacy_formats = [RepositoryFormat4(),
743
                   RepositoryFormat5(),
744
                   RepositoryFormat6()]