~bzr-pqm/bzr/bzr.dev

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