bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
1  | 
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 | 
2  | 
#
 | 
|
3  | 
# This program is free software; you can redistribute it and/or modify
 | 
|
4  | 
# it under the terms of the GNU General Public License as published by
 | 
|
5  | 
# the Free Software Foundation; either version 2 of the License, or
 | 
|
6  | 
# (at your option) any later version.
 | 
|
7  | 
#
 | 
|
8  | 
# This program is distributed in the hope that it will be useful,
 | 
|
9  | 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|
10  | 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|
11  | 
# GNU General Public License for more details.
 | 
|
12  | 
#
 | 
|
13  | 
# You should have received a copy of the GNU General Public License
 | 
|
14  | 
# along with this program; if not, write to the Free Software
 | 
|
15  | 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
|
16  | 
||
| 
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  | 
|
23  | 
from StringIO import StringIO  | 
|
24  | 
||
25  | 
from bzrlib import (  | 
|
26  | 
bzrdir,  | 
|
| 
2850.3.1
by Robert Collins
 Move various weave specific code out of the base Repository class to weaverepo.py.  | 
27  | 
debug,  | 
28  | 
errors,  | 
|
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
29  | 
lockable_files,  | 
30  | 
lockdir,  | 
|
| 
2803.2.1
by Robert Collins
 * CommitBuilder now advertises itself as requiring the root entry to be  | 
31  | 
osutils,  | 
| 
2850.3.1
by Robert Collins
 Move various weave specific code out of the base Repository class to weaverepo.py.  | 
32  | 
revision as _mod_revision,  | 
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
33  | 
weave,  | 
34  | 
weavefile,  | 
|
| 
2241.1.8
by Martin Pool
 Set the repository's serializer in the places it's needed, not in the base class  | 
35  | 
xml5,  | 
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
36  | 
    )
 | 
37  | 
from bzrlib.decorators import needs_read_lock, needs_write_lock  | 
|
38  | 
from bzrlib.repository import (  | 
|
| 
2803.2.1
by Robert Collins
 * CommitBuilder now advertises itself as requiring the root entry to be  | 
39  | 
CommitBuilder,  | 
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
40  | 
MetaDirRepository,  | 
41  | 
MetaDirRepositoryFormat,  | 
|
42  | 
Repository,  | 
|
43  | 
RepositoryFormat,  | 
|
44  | 
    )
 | 
|
45  | 
from bzrlib.store.text import TextStore  | 
|
46  | 
from bzrlib.trace import mutter  | 
|
47  | 
||
48  | 
||
49  | 
class AllInOneRepository(Repository):  | 
|
50  | 
"""Legacy support - the repository behaviour for all-in-one branches."""  | 
|
51  | 
||
| 
2241.1.8
by Martin Pool
 Set the repository's serializer in the places it's needed, not in the base class  | 
52  | 
_serializer = xml5.serializer_v5  | 
53  | 
||
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
54  | 
def __init__(self, _format, a_bzrdir, _revision_store, control_store, text_store):  | 
55  | 
        # we reuse one control files instance.
 | 
|
56  | 
dir_mode = a_bzrdir._control_files._dir_mode  | 
|
57  | 
file_mode = a_bzrdir._control_files._file_mode  | 
|
58  | 
||
59  | 
def get_store(name, compressed=True, prefixed=False):  | 
|
60  | 
            # FIXME: This approach of assuming stores are all entirely compressed
 | 
|
61  | 
            # or entirely uncompressed is tidy, but breaks upgrade from 
 | 
|
62  | 
            # some existing branches where there's a mixture; we probably 
 | 
|
63  | 
            # still want the option to look for both.
 | 
|
64  | 
relpath = a_bzrdir._control_files._escape(name)  | 
|
65  | 
store = TextStore(a_bzrdir._control_files._transport.clone(relpath),  | 
|
66  | 
prefixed=prefixed, compressed=compressed,  | 
|
67  | 
dir_mode=dir_mode,  | 
|
68  | 
file_mode=file_mode)  | 
|
69  | 
return store  | 
|
70  | 
||
71  | 
        # not broken out yet because the controlweaves|inventory_store
 | 
|
72  | 
        # and text_store | weave_store bits are still different.
 | 
|
73  | 
if isinstance(_format, RepositoryFormat4):  | 
|
74  | 
            # cannot remove these - there is still no consistent api 
 | 
|
75  | 
            # which allows access to this old info.
 | 
|
76  | 
self.inventory_store = get_store('inventory-store')  | 
|
77  | 
text_store = get_store('text-store')  | 
|
78  | 
super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files, _revision_store, control_store, text_store)  | 
|
79  | 
||
| 
2850.3.1
by Robert Collins
 Move various weave specific code out of the base Repository class to weaverepo.py.  | 
80  | 
    @needs_read_lock
 | 
81  | 
def _all_possible_ids(self):  | 
|
82  | 
"""Return all the possible revisions that we could find."""  | 
|
83  | 
if 'evil' in debug.debug_flags:  | 
|
84  | 
mutter_callsite(3, "_all_possible_ids scales with size of history.")  | 
|
85  | 
return self.get_inventory_weave().versions()  | 
|
86  | 
||
87  | 
    @needs_read_lock
 | 
|
88  | 
def _all_revision_ids(self):  | 
|
89  | 
"""Returns a list of all the revision ids in the repository.  | 
|
90  | 
||
91  | 
        These are in as much topological order as the underlying store can 
 | 
|
92  | 
        present: for weaves ghosts may lead to a lack of correctness until
 | 
|
93  | 
        the reweave updates the parents list.
 | 
|
94  | 
        """
 | 
|
95  | 
if self._revision_store.text_store.listable():  | 
|
96  | 
return self._revision_store.all_revision_ids(self.get_transaction())  | 
|
97  | 
result = self._all_possible_ids()  | 
|
98  | 
        # TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
 | 
|
99  | 
        #       ids. (It should, since _revision_store's API should change to
 | 
|
100  | 
        #       return utf8 revision_ids)
 | 
|
101  | 
return self._eliminate_revisions_not_present(result)  | 
|
102  | 
||
103  | 
def _check_revision_parents(self, revision, inventory):  | 
|
104  | 
"""Private to Repository and Fetch.  | 
|
105  | 
        
 | 
|
106  | 
        This checks the parentage of revision in an inventory weave for 
 | 
|
107  | 
        consistency and is only applicable to inventory-weave-for-ancestry
 | 
|
108  | 
        using repository formats & fetchers.
 | 
|
109  | 
        """
 | 
|
110  | 
weave_parents = inventory.get_parents(revision.revision_id)  | 
|
111  | 
weave_names = inventory.versions()  | 
|
112  | 
for parent_id in revision.parent_ids:  | 
|
113  | 
if parent_id in weave_names:  | 
|
114  | 
                # this parent must not be a ghost.
 | 
|
115  | 
if not parent_id in weave_parents:  | 
|
116  | 
                    # but it is a ghost
 | 
|
117  | 
raise errors.CorruptRepository(self)  | 
|
118  | 
||
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
119  | 
def get_commit_builder(self, branch, parents, config, timestamp=None,  | 
120  | 
timezone=None, committer=None, revprops=None,  | 
|
121  | 
revision_id=None):  | 
|
122  | 
self._check_ascii_revisionid(revision_id, self.get_commit_builder)  | 
|
| 
2803.2.1
by Robert Collins
 * CommitBuilder now advertises itself as requiring the root entry to be  | 
123  | 
result = WeaveCommitBuilder(self, parents, config, timestamp, timezone,  | 
124  | 
committer, revprops, revision_id)  | 
|
125  | 
self.start_write_group()  | 
|
126  | 
return result  | 
|
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
127  | 
|
128  | 
    @needs_read_lock
 | 
|
| 
2850.3.1
by Robert Collins
 Move various weave specific code out of the base Repository class to weaverepo.py.  | 
129  | 
def get_revisions(self, revision_ids):  | 
130  | 
revs = self._get_revisions(revision_ids)  | 
|
131  | 
        # weave corruption can lead to absent revision markers that should be
 | 
|
132  | 
        # present.
 | 
|
133  | 
        # the following test is reasonably cheap (it needs a single weave read)
 | 
|
134  | 
        # and the weave is cached in read transactions. In write transactions
 | 
|
135  | 
        # it is not cached but typically we only read a small number of
 | 
|
136  | 
        # revisions. For knits when they are introduced we will probably want
 | 
|
137  | 
        # to ensure that caching write transactions are in use.
 | 
|
138  | 
inv = self.get_inventory_weave()  | 
|
139  | 
for rev in revs:  | 
|
140  | 
self._check_revision_parents(rev, inv)  | 
|
141  | 
return revs  | 
|
142  | 
||
143  | 
    @needs_read_lock
 | 
|
144  | 
def get_revision_graph(self, revision_id=None):  | 
|
145  | 
"""Return a dictionary containing the revision graph.  | 
|
146  | 
        
 | 
|
147  | 
        :param revision_id: The revision_id to get a graph from. If None, then
 | 
|
148  | 
        the entire revision graph is returned. This is a deprecated mode of
 | 
|
149  | 
        operation and will be removed in the future.
 | 
|
150  | 
        :return: a dictionary of revision_id->revision_parents_list.
 | 
|
151  | 
        """
 | 
|
152  | 
if 'evil' in debug.debug_flags:  | 
|
153  | 
mutter_callsite(2,  | 
|
154  | 
"get_revision_graph scales with size of history.")  | 
|
155  | 
        # special case NULL_REVISION
 | 
|
156  | 
if revision_id == _mod_revision.NULL_REVISION:  | 
|
157  | 
return {}  | 
|
158  | 
a_weave = self.get_inventory_weave()  | 
|
159  | 
all_revisions = self._eliminate_revisions_not_present(  | 
|
160  | 
a_weave.versions())  | 
|
161  | 
entire_graph = dict([(node, tuple(a_weave.get_parents(node))) for  | 
|
162  | 
node in all_revisions])  | 
|
163  | 
if revision_id is None:  | 
|
164  | 
return entire_graph  | 
|
165  | 
elif revision_id not in entire_graph:  | 
|
166  | 
raise errors.NoSuchRevision(self, revision_id)  | 
|
167  | 
else:  | 
|
168  | 
            # add what can be reached from revision_id
 | 
|
169  | 
result = {}  | 
|
170  | 
pending = set([revision_id])  | 
|
171  | 
while len(pending) > 0:  | 
|
172  | 
node = pending.pop()  | 
|
173  | 
result[node] = entire_graph[node]  | 
|
174  | 
for revision_id in result[node]:  | 
|
175  | 
if revision_id not in result:  | 
|
176  | 
pending.add(revision_id)  | 
|
177  | 
return result  | 
|
178  | 
||
| 
3172.3.1
by Robert Collins
 Repository has a new method ``has_revisions`` which signals the presence  | 
179  | 
def has_revisions(self, revision_ids):  | 
180  | 
"""See Repository.has_revisions()."""  | 
|
181  | 
result = set()  | 
|
182  | 
transaction = self.get_transaction()  | 
|
183  | 
for revision_id in revision_ids:  | 
|
184  | 
if self._revision_store.has_revision_id(revision_id, transaction):  | 
|
185  | 
result.add(revision_id)  | 
|
186  | 
return result  | 
|
187  | 
||
| 
2850.3.1
by Robert Collins
 Move various weave specific code out of the base Repository class to weaverepo.py.  | 
188  | 
    @needs_read_lock
 | 
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
189  | 
def is_shared(self):  | 
190  | 
"""AllInOne repositories cannot be shared."""  | 
|
191  | 
return False  | 
|
192  | 
||
193  | 
    @needs_write_lock
 | 
|
194  | 
def set_make_working_trees(self, new_value):  | 
|
195  | 
"""Set the policy flag for making working trees when creating branches.  | 
|
196  | 
||
197  | 
        This only applies to branches that use this repository.
 | 
|
198  | 
||
199  | 
        The default is 'True'.
 | 
|
200  | 
        :param new_value: True to restore the default, False to disable making
 | 
|
201  | 
                          working trees.
 | 
|
202  | 
        """
 | 
|
203  | 
raise NotImplementedError(self.set_make_working_trees)  | 
|
204  | 
||
205  | 
def make_working_trees(self):  | 
|
206  | 
"""Returns the policy for making working trees on new branches."""  | 
|
207  | 
return True  | 
|
208  | 
||
| 
2819.2.4
by Andrew Bennetts
 Add a 'revision_graph_can_have_wrong_parents' method to repository.  | 
209  | 
def revision_graph_can_have_wrong_parents(self):  | 
210  | 
        # XXX: This is an old format that we don't support full checking on, so
 | 
|
211  | 
        # just claim that checking for this inconsistency is not required.
 | 
|
212  | 
return False  | 
|
213  | 
||
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
214  | 
|
215  | 
class WeaveMetaDirRepository(MetaDirRepository):  | 
|
216  | 
"""A subclass of MetaDirRepository to set weave specific policy."""  | 
|
217  | 
||
| 
2241.1.8
by Martin Pool
 Set the repository's serializer in the places it's needed, not in the base class  | 
218  | 
_serializer = xml5.serializer_v5  | 
219  | 
||
| 
2850.3.1
by Robert Collins
 Move various weave specific code out of the base Repository class to weaverepo.py.  | 
220  | 
    @needs_read_lock
 | 
221  | 
def _all_possible_ids(self):  | 
|
222  | 
"""Return all the possible revisions that we could find."""  | 
|
223  | 
if 'evil' in debug.debug_flags:  | 
|
224  | 
mutter_callsite(3, "_all_possible_ids scales with size of history.")  | 
|
225  | 
return self.get_inventory_weave().versions()  | 
|
226  | 
||
227  | 
    @needs_read_lock
 | 
|
228  | 
def _all_revision_ids(self):  | 
|
229  | 
"""Returns a list of all the revision ids in the repository.  | 
|
230  | 
||
231  | 
        These are in as much topological order as the underlying store can 
 | 
|
232  | 
        present: for weaves ghosts may lead to a lack of correctness until
 | 
|
233  | 
        the reweave updates the parents list.
 | 
|
234  | 
        """
 | 
|
235  | 
if self._revision_store.text_store.listable():  | 
|
236  | 
return self._revision_store.all_revision_ids(self.get_transaction())  | 
|
237  | 
result = self._all_possible_ids()  | 
|
238  | 
        # TODO: jam 20070210 Ensure that _all_possible_ids returns non-unicode
 | 
|
239  | 
        #       ids. (It should, since _revision_store's API should change to
 | 
|
240  | 
        #       return utf8 revision_ids)
 | 
|
241  | 
return self._eliminate_revisions_not_present(result)  | 
|
242  | 
||
243  | 
def _check_revision_parents(self, revision, inventory):  | 
|
244  | 
"""Private to Repository and Fetch.  | 
|
245  | 
        
 | 
|
246  | 
        This checks the parentage of revision in an inventory weave for 
 | 
|
247  | 
        consistency and is only applicable to inventory-weave-for-ancestry
 | 
|
248  | 
        using repository formats & fetchers.
 | 
|
249  | 
        """
 | 
|
250  | 
weave_parents = inventory.get_parents(revision.revision_id)  | 
|
251  | 
weave_names = inventory.versions()  | 
|
252  | 
for parent_id in revision.parent_ids:  | 
|
253  | 
if parent_id in weave_names:  | 
|
254  | 
                # this parent must not be a ghost.
 | 
|
255  | 
if not parent_id in weave_parents:  | 
|
256  | 
                    # but it is a ghost
 | 
|
257  | 
raise errors.CorruptRepository(self)  | 
|
258  | 
||
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
259  | 
def get_commit_builder(self, branch, parents, config, timestamp=None,  | 
260  | 
timezone=None, committer=None, revprops=None,  | 
|
261  | 
revision_id=None):  | 
|
262  | 
self._check_ascii_revisionid(revision_id, self.get_commit_builder)  | 
|
| 
2803.2.1
by Robert Collins
 * CommitBuilder now advertises itself as requiring the root entry to be  | 
263  | 
result = WeaveCommitBuilder(self, parents, config, timestamp, timezone,  | 
264  | 
committer, revprops, revision_id)  | 
|
265  | 
self.start_write_group()  | 
|
266  | 
return result  | 
|
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
267  | 
|
| 
2850.3.1
by Robert Collins
 Move various weave specific code out of the base Repository class to weaverepo.py.  | 
268  | 
    @needs_read_lock
 | 
269  | 
def get_revision(self, revision_id):  | 
|
270  | 
"""Return the Revision object for a named revision"""  | 
|
271  | 
        # TODO: jam 20070210 get_revision_reconcile should do this for us
 | 
|
272  | 
r = self.get_revision_reconcile(revision_id)  | 
|
273  | 
        # weave corruption can lead to absent revision markers that should be
 | 
|
274  | 
        # present.
 | 
|
275  | 
        # the following test is reasonably cheap (it needs a single weave read)
 | 
|
276  | 
        # and the weave is cached in read transactions. In write transactions
 | 
|
277  | 
        # it is not cached but typically we only read a small number of
 | 
|
278  | 
        # revisions. For knits when they are introduced we will probably want
 | 
|
279  | 
        # to ensure that caching write transactions are in use.
 | 
|
280  | 
inv = self.get_inventory_weave()  | 
|
281  | 
self._check_revision_parents(r, inv)  | 
|
282  | 
return r  | 
|
283  | 
||
284  | 
    @needs_read_lock
 | 
|
285  | 
def get_revision_graph(self, revision_id=None):  | 
|
286  | 
"""Return a dictionary containing the revision graph.  | 
|
287  | 
        
 | 
|
288  | 
        :param revision_id: The revision_id to get a graph from. If None, then
 | 
|
289  | 
        the entire revision graph is returned. This is a deprecated mode of
 | 
|
290  | 
        operation and will be removed in the future.
 | 
|
291  | 
        :return: a dictionary of revision_id->revision_parents_list.
 | 
|
292  | 
        """
 | 
|
293  | 
if 'evil' in debug.debug_flags:  | 
|
294  | 
mutter_callsite(3,  | 
|
295  | 
"get_revision_graph scales with size of history.")  | 
|
296  | 
        # special case NULL_REVISION
 | 
|
297  | 
if revision_id == _mod_revision.NULL_REVISION:  | 
|
298  | 
return {}  | 
|
299  | 
a_weave = self.get_inventory_weave()  | 
|
300  | 
all_revisions = self._eliminate_revisions_not_present(  | 
|
301  | 
a_weave.versions())  | 
|
302  | 
entire_graph = dict([(node, tuple(a_weave.get_parents(node))) for  | 
|
303  | 
node in all_revisions])  | 
|
304  | 
if revision_id is None:  | 
|
305  | 
return entire_graph  | 
|
306  | 
elif revision_id not in entire_graph:  | 
|
307  | 
raise errors.NoSuchRevision(self, revision_id)  | 
|
308  | 
else:  | 
|
309  | 
            # add what can be reached from revision_id
 | 
|
310  | 
result = {}  | 
|
311  | 
pending = set([revision_id])  | 
|
312  | 
while len(pending) > 0:  | 
|
313  | 
node = pending.pop()  | 
|
314  | 
result[node] = entire_graph[node]  | 
|
315  | 
for revision_id in result[node]:  | 
|
316  | 
if revision_id not in result:  | 
|
317  | 
pending.add(revision_id)  | 
|
318  | 
return result  | 
|
319  | 
||
| 
3172.3.1
by Robert Collins
 Repository has a new method ``has_revisions`` which signals the presence  | 
320  | 
def has_revisions(self, revision_ids):  | 
321  | 
"""See Repository.has_revisions()."""  | 
|
322  | 
result = set()  | 
|
323  | 
transaction = self.get_transaction()  | 
|
324  | 
for revision_id in revision_ids:  | 
|
325  | 
if self._revision_store.has_revision_id(revision_id, transaction):  | 
|
326  | 
result.add(revision_id)  | 
|
327  | 
return result  | 
|
328  | 
||
| 
2819.2.4
by Andrew Bennetts
 Add a 'revision_graph_can_have_wrong_parents' method to repository.  | 
329  | 
def revision_graph_can_have_wrong_parents(self):  | 
330  | 
        # XXX: This is an old format that we don't support full checking on, so
 | 
|
331  | 
        # just claim that checking for this inconsistency is not required.
 | 
|
332  | 
return False  | 
|
333  | 
||
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
334  | 
|
335  | 
class PreSplitOutRepositoryFormat(RepositoryFormat):  | 
|
336  | 
"""Base class for the pre split out repository formats."""  | 
|
337  | 
||
338  | 
rich_root_data = False  | 
|
| 
2323.5.17
by Martin Pool
 Add supports_tree_reference to all repo formats (robert)  | 
339  | 
supports_tree_reference = False  | 
| 
2949.1.2
by Robert Collins
 * Fetch with pack repositories will no longer read the entire history graph.  | 
340  | 
supports_ghosts = False  | 
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
341  | 
|
342  | 
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.  | 
343  | 
"""Create a weave repository."""  | 
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
344  | 
if shared:  | 
345  | 
raise errors.IncompatibleFormat(self, a_bzrdir._format)  | 
|
346  | 
||
347  | 
if not _internal:  | 
|
348  | 
            # always initialized when the bzrdir is.
 | 
|
349  | 
return self.open(a_bzrdir, _found=True)  | 
|
350  | 
||
351  | 
        # Create an empty weave
 | 
|
352  | 
sio = StringIO()  | 
|
353  | 
weavefile.write_weave_v5(weave.Weave(), sio)  | 
|
354  | 
empty_weave = sio.getvalue()  | 
|
355  | 
||
356  | 
mutter('creating repository in %s.', a_bzrdir.transport.base)  | 
|
357  | 
dirs = ['revision-store', 'weaves']  | 
|
358  | 
files = [('inventory.weave', StringIO(empty_weave)),  | 
|
359  | 
                 ]
 | 
|
360  | 
||
361  | 
        # FIXME: RBC 20060125 don't peek under the covers
 | 
|
362  | 
        # NB: no need to escape relative paths that are url safe.
 | 
|
363  | 
control_files = lockable_files.LockableFiles(a_bzrdir.transport,  | 
|
364  | 
'branch-lock', lockable_files.TransportLock)  | 
|
365  | 
control_files.create_lock()  | 
|
366  | 
control_files.lock_write()  | 
|
367  | 
control_files._transport.mkdir_multi(dirs,  | 
|
368  | 
mode=control_files._dir_mode)  | 
|
369  | 
try:  | 
|
370  | 
for file, content in files:  | 
|
371  | 
control_files.put(file, content)  | 
|
372  | 
finally:  | 
|
373  | 
control_files.unlock()  | 
|
374  | 
return self.open(a_bzrdir, _found=True)  | 
|
375  | 
||
376  | 
def _get_control_store(self, repo_transport, control_files):  | 
|
377  | 
"""Return the control store for this repository."""  | 
|
378  | 
return self._get_versioned_file_store('',  | 
|
379  | 
repo_transport,  | 
|
380  | 
control_files,  | 
|
381  | 
prefixed=False)  | 
|
382  | 
||
383  | 
def _get_text_store(self, transport, control_files):  | 
|
384  | 
"""Get a store for file texts for this format."""  | 
|
385  | 
raise NotImplementedError(self._get_text_store)  | 
|
386  | 
||
387  | 
def open(self, a_bzrdir, _found=False):  | 
|
388  | 
"""See RepositoryFormat.open()."""  | 
|
389  | 
if not _found:  | 
|
390  | 
            # we are being called directly and must probe.
 | 
|
391  | 
raise NotImplementedError  | 
|
392  | 
||
393  | 
repo_transport = a_bzrdir.get_repository_transport(None)  | 
|
394  | 
control_files = a_bzrdir._control_files  | 
|
395  | 
text_store = self._get_text_store(repo_transport, control_files)  | 
|
396  | 
control_store = self._get_control_store(repo_transport, control_files)  | 
|
397  | 
_revision_store = self._get_revision_store(repo_transport, control_files)  | 
|
398  | 
return AllInOneRepository(_format=self,  | 
|
399  | 
a_bzrdir=a_bzrdir,  | 
|
400  | 
_revision_store=_revision_store,  | 
|
401  | 
control_store=control_store,  | 
|
402  | 
text_store=text_store)  | 
|
403  | 
||
404  | 
def check_conversion_target(self, target_format):  | 
|
405  | 
        pass
 | 
|
406  | 
||
407  | 
||
408  | 
class RepositoryFormat4(PreSplitOutRepositoryFormat):  | 
|
409  | 
"""Bzr repository format 4.  | 
|
410  | 
||
411  | 
    This repository format has:
 | 
|
412  | 
     - flat stores
 | 
|
413  | 
     - TextStores for texts, inventories,revisions.
 | 
|
414  | 
||
415  | 
    This format is deprecated: it indexes texts using a text id which is
 | 
|
416  | 
    removed in format 5; initialization and write support for this format
 | 
|
417  | 
    has been removed.
 | 
|
418  | 
    """
 | 
|
419  | 
||
| 
2241.1.11
by Martin Pool
 Get rid of RepositoryFormat*_instance objects. Instead the format  | 
420  | 
_matchingbzrdir = bzrdir.BzrDirFormat4()  | 
421  | 
||
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
422  | 
def __init__(self):  | 
423  | 
super(RepositoryFormat4, self).__init__()  | 
|
424  | 
||
425  | 
def get_format_description(self):  | 
|
426  | 
"""See RepositoryFormat.get_format_description()."""  | 
|
427  | 
return "Repository format 4"  | 
|
428  | 
||
429  | 
def initialize(self, url, shared=False, _internal=False):  | 
|
430  | 
"""Format 4 branches cannot be created."""  | 
|
431  | 
raise errors.UninitializableFormat(self)  | 
|
432  | 
||
433  | 
def is_supported(self):  | 
|
434  | 
"""Format 4 is not supported.  | 
|
435  | 
||
436  | 
        It is not supported because the model changed from 4 to 5 and the
 | 
|
437  | 
        conversion logic is expensive - so doing it on the fly was not 
 | 
|
438  | 
        feasible.
 | 
|
439  | 
        """
 | 
|
440  | 
return False  | 
|
441  | 
||
442  | 
def _get_control_store(self, repo_transport, control_files):  | 
|
443  | 
"""Format 4 repositories have no formal control store at this point.  | 
|
444  | 
        
 | 
|
445  | 
        This will cause any control-file-needing apis to fail - this is desired.
 | 
|
446  | 
        """
 | 
|
447  | 
return None  | 
|
448  | 
||
449  | 
def _get_revision_store(self, repo_transport, control_files):  | 
|
450  | 
"""See RepositoryFormat._get_revision_store()."""  | 
|
451  | 
from bzrlib.xml4 import serializer_v4  | 
|
452  | 
return self._get_text_rev_store(repo_transport,  | 
|
453  | 
control_files,  | 
|
454  | 
'revision-store',  | 
|
455  | 
serializer=serializer_v4)  | 
|
456  | 
||
457  | 
def _get_text_store(self, transport, control_files):  | 
|
458  | 
"""See RepositoryFormat._get_text_store()."""  | 
|
459  | 
||
460  | 
||
461  | 
class RepositoryFormat5(PreSplitOutRepositoryFormat):  | 
|
462  | 
"""Bzr control format 5.  | 
|
463  | 
||
464  | 
    This repository format has:
 | 
|
465  | 
     - weaves for file texts and inventory
 | 
|
466  | 
     - flat stores
 | 
|
467  | 
     - TextStores for revisions and signatures.
 | 
|
468  | 
    """
 | 
|
469  | 
||
| 
2241.1.10
by Martin Pool
 Remove more references to weaves from the repository.py file  | 
470  | 
_versionedfile_class = weave.WeaveFile  | 
| 
2241.1.11
by Martin Pool
 Get rid of RepositoryFormat*_instance objects. Instead the format  | 
471  | 
_matchingbzrdir = bzrdir.BzrDirFormat5()  | 
| 
2241.1.10
by Martin Pool
 Remove more references to weaves from the repository.py file  | 
472  | 
|
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
473  | 
def __init__(self):  | 
474  | 
super(RepositoryFormat5, self).__init__()  | 
|
475  | 
||
476  | 
def get_format_description(self):  | 
|
477  | 
"""See RepositoryFormat.get_format_description()."""  | 
|
478  | 
return "Weave repository format 5"  | 
|
479  | 
||
480  | 
def _get_revision_store(self, repo_transport, control_files):  | 
|
481  | 
"""See RepositoryFormat._get_revision_store()."""  | 
|
482  | 
"""Return the revision store object for this a_bzrdir."""  | 
|
483  | 
return self._get_text_rev_store(repo_transport,  | 
|
484  | 
control_files,  | 
|
485  | 
'revision-store',  | 
|
486  | 
compressed=False)  | 
|
487  | 
||
488  | 
def _get_text_store(self, transport, control_files):  | 
|
489  | 
"""See RepositoryFormat._get_text_store()."""  | 
|
490  | 
return self._get_versioned_file_store('weaves', transport, control_files, prefixed=False)  | 
|
491  | 
||
492  | 
||
493  | 
class RepositoryFormat6(PreSplitOutRepositoryFormat):  | 
|
494  | 
"""Bzr control format 6.  | 
|
495  | 
||
496  | 
    This repository format has:
 | 
|
497  | 
     - weaves for file texts and inventory
 | 
|
498  | 
     - hash subdirectory based stores.
 | 
|
499  | 
     - TextStores for revisions and signatures.
 | 
|
500  | 
    """
 | 
|
501  | 
||
| 
2241.1.10
by Martin Pool
 Remove more references to weaves from the repository.py file  | 
502  | 
_versionedfile_class = weave.WeaveFile  | 
| 
2241.1.11
by Martin Pool
 Get rid of RepositoryFormat*_instance objects. Instead the format  | 
503  | 
_matchingbzrdir = bzrdir.BzrDirFormat6()  | 
| 
2241.1.10
by Martin Pool
 Remove more references to weaves from the repository.py file  | 
504  | 
|
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
505  | 
def __init__(self):  | 
506  | 
super(RepositoryFormat6, self).__init__()  | 
|
507  | 
||
508  | 
def get_format_description(self):  | 
|
509  | 
"""See RepositoryFormat.get_format_description()."""  | 
|
510  | 
return "Weave repository format 6"  | 
|
511  | 
||
512  | 
def _get_revision_store(self, repo_transport, control_files):  | 
|
513  | 
"""See RepositoryFormat._get_revision_store()."""  | 
|
514  | 
return self._get_text_rev_store(repo_transport,  | 
|
515  | 
control_files,  | 
|
516  | 
'revision-store',  | 
|
517  | 
compressed=False,  | 
|
518  | 
prefixed=True)  | 
|
519  | 
||
520  | 
def _get_text_store(self, transport, control_files):  | 
|
521  | 
"""See RepositoryFormat._get_text_store()."""  | 
|
522  | 
return self._get_versioned_file_store('weaves', transport, control_files)  | 
|
523  | 
||
524  | 
class RepositoryFormat7(MetaDirRepositoryFormat):  | 
|
525  | 
"""Bzr repository 7.  | 
|
526  | 
||
527  | 
    This repository format has:
 | 
|
528  | 
     - weaves for file texts and inventory
 | 
|
529  | 
     - hash subdirectory based stores.
 | 
|
530  | 
     - TextStores for revisions and signatures.
 | 
|
531  | 
     - a format marker of its own
 | 
|
532  | 
     - an optional 'shared-storage' flag
 | 
|
533  | 
     - an optional 'no-working-trees' flag
 | 
|
534  | 
    """
 | 
|
535  | 
||
| 
2241.1.10
by Martin Pool
 Remove more references to weaves from the repository.py file  | 
536  | 
_versionedfile_class = weave.WeaveFile  | 
| 
2949.1.2
by Robert Collins
 * Fetch with pack repositories will no longer read the entire history graph.  | 
537  | 
supports_ghosts = False  | 
| 
2241.1.10
by Martin Pool
 Remove more references to weaves from the repository.py file  | 
538  | 
|
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
539  | 
def _get_control_store(self, repo_transport, control_files):  | 
540  | 
"""Return the control store for this repository."""  | 
|
541  | 
return self._get_versioned_file_store('',  | 
|
542  | 
repo_transport,  | 
|
543  | 
control_files,  | 
|
544  | 
prefixed=False)  | 
|
545  | 
||
546  | 
def get_format_string(self):  | 
|
547  | 
"""See RepositoryFormat.get_format_string()."""  | 
|
548  | 
return "Bazaar-NG Repository format 7"  | 
|
549  | 
||
550  | 
def get_format_description(self):  | 
|
551  | 
"""See RepositoryFormat.get_format_description()."""  | 
|
552  | 
return "Weave repository format 7"  | 
|
553  | 
||
554  | 
def check_conversion_target(self, target_format):  | 
|
555  | 
        pass
 | 
|
556  | 
||
557  | 
def _get_revision_store(self, repo_transport, control_files):  | 
|
558  | 
"""See RepositoryFormat._get_revision_store()."""  | 
|
559  | 
return self._get_text_rev_store(repo_transport,  | 
|
560  | 
control_files,  | 
|
561  | 
'revision-store',  | 
|
562  | 
compressed=False,  | 
|
563  | 
prefixed=True,  | 
|
564  | 
                                        )
 | 
|
565  | 
||
566  | 
def _get_text_store(self, transport, control_files):  | 
|
567  | 
"""See RepositoryFormat._get_text_store()."""  | 
|
568  | 
return self._get_versioned_file_store('weaves',  | 
|
569  | 
transport,  | 
|
570  | 
control_files)  | 
|
571  | 
||
572  | 
def initialize(self, a_bzrdir, shared=False):  | 
|
573  | 
"""Create a weave repository.  | 
|
574  | 
||
575  | 
        :param shared: If true the repository will be initialized as a shared
 | 
|
576  | 
                       repository.
 | 
|
577  | 
        """
 | 
|
578  | 
        # Create an empty weave
 | 
|
579  | 
sio = StringIO()  | 
|
580  | 
weavefile.write_weave_v5(weave.Weave(), sio)  | 
|
581  | 
empty_weave = sio.getvalue()  | 
|
582  | 
||
583  | 
mutter('creating repository in %s.', a_bzrdir.transport.base)  | 
|
584  | 
dirs = ['revision-store', 'weaves']  | 
|
585  | 
files = [('inventory.weave', StringIO(empty_weave)),  | 
|
586  | 
                 ]
 | 
|
587  | 
utf8_files = [('format', self.get_format_string())]  | 
|
588  | 
||
589  | 
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)  | 
|
590  | 
return self.open(a_bzrdir=a_bzrdir, _found=True)  | 
|
591  | 
||
592  | 
def open(self, a_bzrdir, _found=False, _override_transport=None):  | 
|
593  | 
"""See RepositoryFormat.open().  | 
|
594  | 
        
 | 
|
595  | 
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
 | 
|
596  | 
                                    repository at a slightly different url
 | 
|
597  | 
                                    than normal. I.e. during 'upgrade'.
 | 
|
598  | 
        """
 | 
|
599  | 
if not _found:  | 
|
600  | 
format = RepositoryFormat.find_format(a_bzrdir)  | 
|
601  | 
assert format.__class__ == self.__class__  | 
|
602  | 
if _override_transport is not None:  | 
|
603  | 
repo_transport = _override_transport  | 
|
604  | 
else:  | 
|
605  | 
repo_transport = a_bzrdir.get_repository_transport(None)  | 
|
606  | 
control_files = lockable_files.LockableFiles(repo_transport,  | 
|
607  | 
'lock', lockdir.LockDir)  | 
|
608  | 
text_store = self._get_text_store(repo_transport, control_files)  | 
|
609  | 
control_store = self._get_control_store(repo_transport, control_files)  | 
|
610  | 
_revision_store = self._get_revision_store(repo_transport, control_files)  | 
|
611  | 
return WeaveMetaDirRepository(_format=self,  | 
|
612  | 
a_bzrdir=a_bzrdir,  | 
|
613  | 
control_files=control_files,  | 
|
614  | 
_revision_store=_revision_store,  | 
|
615  | 
control_store=control_store,  | 
|
616  | 
text_store=text_store)  | 
|
617  | 
||
618  | 
||
| 
2803.2.1
by Robert Collins
 * CommitBuilder now advertises itself as requiring the root entry to be  | 
619  | 
class WeaveCommitBuilder(CommitBuilder):  | 
620  | 
"""A builder for weave based repos that don't support ghosts."""  | 
|
621  | 
||
| 
2592.3.131
by Robert Collins
 Fix weaverepo commits due to api change.  | 
622  | 
def _add_text_to_weave(self, file_id, new_lines, parents, nostore_sha):  | 
| 
2803.2.1
by Robert Collins
 * CommitBuilder now advertises itself as requiring the root entry to be  | 
623  | 
versionedfile = self.repository.weave_store.get_weave_or_empty(  | 
624  | 
file_id, self.repository.get_transaction())  | 
|
625  | 
result = versionedfile.add_lines(  | 
|
| 
2776.4.9
by Robert Collins
 Unbreak weaves.  | 
626  | 
self._new_revision_id, parents, new_lines,  | 
627  | 
nostore_sha=nostore_sha)[0:2]  | 
|
| 
2803.2.1
by Robert Collins
 * CommitBuilder now advertises itself as requiring the root entry to be  | 
628  | 
versionedfile.clear_cache()  | 
629  | 
return result  | 
|
630  | 
||
631  | 
||
| 
2241.1.4
by Martin Pool
 Moved old weave-based repository formats into bzrlib.repofmt.weaverepo.  | 
632  | 
_legacy_formats = [RepositoryFormat4(),  | 
633  | 
RepositoryFormat5(),  | 
|
634  | 
RepositoryFormat6()]  |