~bzr-pqm/bzr/bzr.dev

5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
1
# Copyright (C) 2006-2010 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
6379.6.7 by Jelmer Vernooij
Move importing from future until after doc string, otherwise the doc string will disappear.
17
"""Weave-era BzrDir formats."""
18
6379.6.3 by Jelmer Vernooij
Use absolute_import.
19
from __future__ import absolute_import
20
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
21
from bzrlib.bzrdir import (
22
    BzrDir,
23
    BzrDirFormat,
24
    BzrDirMetaFormat1,
25
    )
26
from bzrlib.controldir import (
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
27
    ControlDir,
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
28
    Converter,
29
    format_registry,
30
    )
31
from bzrlib.lazy_import import lazy_import
32
lazy_import(globals(), """
33
import os
34
import warnings
35
36
from bzrlib import (
37
    errors,
38
    graph,
39
    lockable_files,
40
    lockdir,
41
    osutils,
42
    revision as _mod_revision,
43
    trace,
44
    ui,
45
    urlutils,
46
    versionedfile,
47
    weave,
48
    xml5,
49
    )
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
50
from bzrlib.i18n import gettext
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
51
from bzrlib.store.versioned import VersionedFileStore
52
from bzrlib.transactions import WriteTransaction
53
from bzrlib.transport import (
54
    get_transport,
55
    local,
56
    )
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
57
from bzrlib.plugins.weave_fmt import xml4
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
58
""")
59
60
61
class BzrDirFormatAllInOne(BzrDirFormat):
62
    """Common class for formats before meta-dirs."""
63
64
    fixed_components = True
65
66
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
67
        create_prefix=False, force_new_repo=False, stacked_on=None,
68
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
69
        shared_repo=False):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
70
        """See ControlDir.initialize_on_transport_ex."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
71
        require_stacking = (stacked_on is not None)
72
        # Format 5 cannot stack, but we've been asked to - actually init
73
        # a Meta1Dir
74
        if require_stacking:
75
            format = BzrDirMetaFormat1()
76
            return format.initialize_on_transport_ex(transport,
77
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
78
                force_new_repo=force_new_repo, stacked_on=stacked_on,
79
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
80
                make_working_trees=make_working_trees, shared_repo=shared_repo)
81
        return BzrDirFormat.initialize_on_transport_ex(self, transport,
82
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
83
            force_new_repo=force_new_repo, stacked_on=stacked_on,
84
            stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
85
            make_working_trees=make_working_trees, shared_repo=shared_repo)
86
6213.1.18 by Jelmer Vernooij
Fix some more tests.
87
    @classmethod
88
    def from_string(cls, format_string):
89
        if format_string != cls.get_format_string():
90
            raise AssertionError("unexpected format string %r" % format_string)
6213.1.19 by Jelmer Vernooij
Fix tests.
91
        return cls()
6213.1.18 by Jelmer Vernooij
Fix some more tests.
92
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
93
94
class BzrDirFormat5(BzrDirFormatAllInOne):
95
    """Bzr control format 5.
96
97
    This format is a combined format for working tree, branch and repository.
98
    It has:
99
     - Format 2 working trees [always]
100
     - Format 4 branches [always]
101
     - Format 5 repositories [always]
102
       Unhashed stores in the repository.
103
    """
104
105
    _lock_class = lockable_files.TransportLock
106
5712.4.7 by Jelmer Vernooij
More fixes.
107
    def __eq__(self, other):
108
        return type(self) == type(other)
109
6213.1.16 by Jelmer Vernooij
Feature support in repository.
110
    @classmethod
111
    def get_format_string(cls):
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
112
        """See BzrDirFormat.get_format_string()."""
113
        return "Bazaar-NG branch, format 5\n"
114
115
    def get_branch_format(self):
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
116
        from bzrlib.plugins.weave_fmt.branch import BzrBranchFormat4
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
117
        return BzrBranchFormat4()
118
119
    def get_format_description(self):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
120
        """See ControlDirFormat.get_format_description()."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
121
        return "All-in-one format 5"
122
123
    def get_converter(self, format=None):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
124
        """See ControlDirFormat.get_converter()."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
125
        # there is one and only one upgrade path here.
126
        return ConvertBzrDir5To6()
127
128
    def _initialize_for_clone(self, url):
129
        return self.initialize_on_transport(get_transport(url), _cloning=True)
130
131
    def initialize_on_transport(self, transport, _cloning=False):
132
        """Format 5 dirs always have working tree, branch and repository.
133
134
        Except when they are being cloned.
135
        """
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
136
        from bzrlib.plugins.weave_fmt.branch import BzrBranchFormat4
137
        from bzrlib.plugins.weave_fmt.repository import RepositoryFormat5
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
138
        result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
139
        RepositoryFormat5().initialize(result, _internal=True)
140
        if not _cloning:
141
            branch = BzrBranchFormat4().initialize(result)
142
            result._init_workingtree()
143
        return result
144
145
    def network_name(self):
146
        return self.get_format_string()
147
148
    def _open(self, transport):
149
        """See BzrDirFormat._open."""
150
        return BzrDir5(transport, self)
151
152
    def __return_repository_format(self):
153
        """Circular import protection."""
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
154
        from bzrlib.plugins.weave_fmt.repository import RepositoryFormat5
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
155
        return RepositoryFormat5()
156
    repository_format = property(__return_repository_format)
157
158
159
class BzrDirFormat6(BzrDirFormatAllInOne):
160
    """Bzr control format 6.
161
162
    This format is a combined format for working tree, branch and repository.
163
    It has:
164
     - Format 2 working trees [always]
165
     - Format 4 branches [always]
166
     - Format 6 repositories [always]
167
    """
168
169
    _lock_class = lockable_files.TransportLock
170
5712.4.7 by Jelmer Vernooij
More fixes.
171
    def __eq__(self, other):
172
        return type(self) == type(other)
173
6213.1.16 by Jelmer Vernooij
Feature support in repository.
174
    @classmethod
175
    def get_format_string(cls):
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
176
        """See BzrDirFormat.get_format_string()."""
177
        return "Bazaar-NG branch, format 6\n"
178
179
    def get_format_description(self):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
180
        """See ControlDirFormat.get_format_description()."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
181
        return "All-in-one format 6"
182
183
    def get_branch_format(self):
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
184
        from bzrlib.plugins.weave_fmt.branch import BzrBranchFormat4
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
185
        return BzrBranchFormat4()
186
187
    def get_converter(self, format=None):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
188
        """See ControlDirFormat.get_converter()."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
189
        # there is one and only one upgrade path here.
190
        return ConvertBzrDir6ToMeta()
191
192
    def _initialize_for_clone(self, url):
193
        return self.initialize_on_transport(get_transport(url), _cloning=True)
194
195
    def initialize_on_transport(self, transport, _cloning=False):
196
        """Format 6 dirs always have working tree, branch and repository.
197
198
        Except when they are being cloned.
199
        """
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
200
        from bzrlib.plugins.weave_fmt.branch import BzrBranchFormat4
201
        from bzrlib.plugins.weave_fmt.repository import RepositoryFormat6
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
202
        result = super(BzrDirFormat6, self).initialize_on_transport(transport)
203
        RepositoryFormat6().initialize(result, _internal=True)
204
        if not _cloning:
205
            branch = BzrBranchFormat4().initialize(result)
206
            result._init_workingtree()
207
        return result
208
209
    def network_name(self):
210
        return self.get_format_string()
211
212
    def _open(self, transport):
213
        """See BzrDirFormat._open."""
214
        return BzrDir6(transport, self)
215
216
    def __return_repository_format(self):
217
        """Circular import protection."""
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
218
        from bzrlib.plugins.weave_fmt.repository import RepositoryFormat6
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
219
        return RepositoryFormat6()
220
    repository_format = property(__return_repository_format)
221
222
223
class ConvertBzrDir4To5(Converter):
224
    """Converts format 4 bzr dirs to format 5."""
225
226
    def __init__(self):
227
        super(ConvertBzrDir4To5, self).__init__()
228
        self.converted_revs = set()
229
        self.absent_revisions = set()
230
        self.text_count = 0
231
        self.revisions = {}
232
233
    def convert(self, to_convert, pb):
234
        """See Converter.convert()."""
235
        self.bzrdir = to_convert
236
        if pb is not None:
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
237
            warnings.warn(gettext("pb parameter to convert() is deprecated"))
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
238
        self.pb = ui.ui_factory.nested_progress_bar()
239
        try:
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
240
            ui.ui_factory.note(gettext('starting upgrade from format 4 to 5'))
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
241
            if isinstance(self.bzrdir.transport, local.LocalTransport):
242
                self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
243
            self._convert_to_weaves()
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
244
            return ControlDir.open(self.bzrdir.user_url)
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
245
        finally:
246
            self.pb.finished()
247
248
    def _convert_to_weaves(self):
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
249
        ui.ui_factory.note(gettext(
250
          'note: upgrade may be faster if all store files are ungzipped first'))
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
251
        try:
252
            # TODO permissions
253
            stat = self.bzrdir.transport.stat('weaves')
254
            if not S_ISDIR(stat.st_mode):
255
                self.bzrdir.transport.delete('weaves')
256
                self.bzrdir.transport.mkdir('weaves')
257
        except errors.NoSuchFile:
258
            self.bzrdir.transport.mkdir('weaves')
259
        # deliberately not a WeaveFile as we want to build it up slowly.
260
        self.inv_weave = weave.Weave('inventory')
261
        # holds in-memory weaves for all files
262
        self.text_weaves = {}
263
        self.bzrdir.transport.delete('branch-format')
264
        self.branch = self.bzrdir.open_branch()
265
        self._convert_working_inv()
6165.4.25 by Jelmer Vernooij
Fix plugin use of revision_history.
266
        rev_history = self.branch._revision_history()
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
267
        # to_read is a stack holding the revisions we still need to process;
268
        # appending to it adds new highest-priority revisions
269
        self.known_revisions = set(rev_history)
270
        self.to_read = rev_history[-1:]
271
        while self.to_read:
272
            rev_id = self.to_read.pop()
273
            if (rev_id not in self.revisions
274
                and rev_id not in self.absent_revisions):
275
                self._load_one_rev(rev_id)
276
        self.pb.clear()
277
        to_import = self._make_order()
278
        for i, rev_id in enumerate(to_import):
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
279
            self.pb.update(gettext('converting revision'), i, len(to_import))
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
280
            self._convert_one_rev(rev_id)
281
        self.pb.clear()
282
        self._write_all_weaves()
283
        self._write_all_revs()
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
284
        ui.ui_factory.note(gettext('upgraded to weaves:'))
6150.3.10 by Jonathan Riddell
do not include space padding in gettext()
285
        ui.ui_factory.note('  ' + gettext('%6d revisions and inventories') %
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
286
                                                        len(self.revisions))
6150.3.10 by Jonathan Riddell
do not include space padding in gettext()
287
        ui.ui_factory.note('  ' + gettext('%6d revisions not present') %
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
288
                                                    len(self.absent_revisions))
6150.3.10 by Jonathan Riddell
do not include space padding in gettext()
289
        ui.ui_factory.note('  ' + gettext('%6d texts') % self.text_count)
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
290
        self._cleanup_spare_files_after_format4()
291
        self.branch._transport.put_bytes(
292
            'branch-format',
293
            BzrDirFormat5().get_format_string(),
294
            mode=self.bzrdir._get_file_mode())
295
296
    def _cleanup_spare_files_after_format4(self):
297
        # FIXME working tree upgrade foo.
298
        for n in 'merged-patches', 'pending-merged-patches':
299
            try:
300
                ## assert os.path.getsize(p) == 0
301
                self.bzrdir.transport.delete(n)
302
            except errors.NoSuchFile:
303
                pass
304
        self.bzrdir.transport.delete_tree('inventory-store')
305
        self.bzrdir.transport.delete_tree('text-store')
306
307
    def _convert_working_inv(self):
308
        inv = xml4.serializer_v4.read_inventory(
309
                self.branch._transport.get('inventory'))
310
        new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv, working=True)
311
        self.branch._transport.put_bytes('inventory', new_inv_xml,
312
            mode=self.bzrdir._get_file_mode())
313
314
    def _write_all_weaves(self):
315
        controlweaves = VersionedFileStore(self.bzrdir.transport, prefixed=False,
316
            versionedfile_class=weave.WeaveFile)
317
        weave_transport = self.bzrdir.transport.clone('weaves')
318
        weaves = VersionedFileStore(weave_transport, prefixed=False,
319
                versionedfile_class=weave.WeaveFile)
320
        transaction = WriteTransaction()
321
322
        try:
323
            i = 0
324
            for file_id, file_weave in self.text_weaves.items():
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
325
                self.pb.update(gettext('writing weave'), i,
326
                                                        len(self.text_weaves))
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
327
                weaves._put_weave(file_id, file_weave, transaction)
328
                i += 1
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
329
            self.pb.update(gettext('inventory'), 0, 1)
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
330
            controlweaves._put_weave('inventory', self.inv_weave, transaction)
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
331
            self.pb.update(gettext('inventory'), 1, 1)
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
332
        finally:
333
            self.pb.clear()
334
335
    def _write_all_revs(self):
336
        """Write all revisions out in new form."""
337
        self.bzrdir.transport.delete_tree('revision-store')
338
        self.bzrdir.transport.mkdir('revision-store')
339
        revision_transport = self.bzrdir.transport.clone('revision-store')
340
        # TODO permissions
341
        from bzrlib.xml5 import serializer_v5
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
342
        from bzrlib.plugins.weave_fmt.repository import RevisionTextStore
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
343
        revision_store = RevisionTextStore(revision_transport,
344
            serializer_v5, False, versionedfile.PrefixMapper(),
345
            lambda:True, lambda:True)
346
        try:
347
            for i, rev_id in enumerate(self.converted_revs):
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
348
                self.pb.update(gettext('write revision'), i,
349
                                                len(self.converted_revs))
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
350
                text = serializer_v5.write_revision_to_string(
351
                    self.revisions[rev_id])
352
                key = (rev_id,)
353
                revision_store.add_lines(key, None, osutils.split_lines(text))
354
        finally:
355
            self.pb.clear()
356
357
    def _load_one_rev(self, rev_id):
358
        """Load a revision object into memory.
359
360
        Any parents not either loaded or abandoned get queued to be
361
        loaded."""
6150.3.11 by Jonathan Riddell
syntax fixes
362
        self.pb.update(gettext('loading revision'),
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
363
                       len(self.revisions),
364
                       len(self.known_revisions))
365
        if not self.branch.repository.has_revision(rev_id):
366
            self.pb.clear()
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
367
            ui.ui_factory.note(gettext('revision {%s} not present in branch; '
368
                         'will be converted as a ghost') %
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
369
                         rev_id)
370
            self.absent_revisions.add(rev_id)
371
        else:
372
            rev = self.branch.repository.get_revision(rev_id)
373
            for parent_id in rev.parent_ids:
374
                self.known_revisions.add(parent_id)
375
                self.to_read.append(parent_id)
376
            self.revisions[rev_id] = rev
377
378
    def _load_old_inventory(self, rev_id):
379
        f = self.branch.repository.inventory_store.get(rev_id)
380
        try:
381
            old_inv_xml = f.read()
382
        finally:
383
            f.close()
384
        inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
385
        inv.revision_id = rev_id
386
        rev = self.revisions[rev_id]
387
        return inv
388
389
    def _load_updated_inventory(self, rev_id):
390
        inv_xml = self.inv_weave.get_text(rev_id)
391
        inv = xml5.serializer_v5.read_inventory_from_string(inv_xml, rev_id)
392
        return inv
393
394
    def _convert_one_rev(self, rev_id):
395
        """Convert revision and all referenced objects to new format."""
396
        rev = self.revisions[rev_id]
397
        inv = self._load_old_inventory(rev_id)
398
        present_parents = [p for p in rev.parent_ids
399
                           if p not in self.absent_revisions]
400
        self._convert_revision_contents(rev, inv, present_parents)
401
        self._store_new_inv(rev, inv, present_parents)
402
        self.converted_revs.add(rev_id)
403
404
    def _store_new_inv(self, rev, inv, present_parents):
405
        new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
406
        new_inv_sha1 = osutils.sha_string(new_inv_xml)
407
        self.inv_weave.add_lines(rev.revision_id,
408
                                 present_parents,
409
                                 new_inv_xml.splitlines(True))
410
        rev.inventory_sha1 = new_inv_sha1
411
412
    def _convert_revision_contents(self, rev, inv, present_parents):
413
        """Convert all the files within a revision.
414
415
        Also upgrade the inventory to refer to the text revision ids."""
416
        rev_id = rev.revision_id
417
        trace.mutter('converting texts of revision {%s}', rev_id)
418
        parent_invs = map(self._load_updated_inventory, present_parents)
419
        entries = inv.iter_entries()
420
        entries.next()
421
        for path, ie in entries:
422
            self._convert_file_version(rev, ie, parent_invs)
423
424
    def _convert_file_version(self, rev, ie, parent_invs):
425
        """Convert one version of one file.
426
427
        The file needs to be added into the weave if it is a merge
428
        of >=2 parents or if it's changed from its parent.
429
        """
430
        file_id = ie.file_id
431
        rev_id = rev.revision_id
432
        w = self.text_weaves.get(file_id)
433
        if w is None:
434
            w = weave.Weave(file_id)
435
            self.text_weaves[file_id] = w
436
        text_changed = False
437
        parent_candiate_entries = ie.parent_candidates(parent_invs)
438
        heads = graph.Graph(self).heads(parent_candiate_entries.keys())
439
        # XXX: Note that this is unordered - and this is tolerable because
440
        # the previous code was also unordered.
441
        previous_entries = dict((head, parent_candiate_entries[head]) for head
442
            in heads)
443
        self.snapshot_ie(previous_entries, ie, w, rev_id)
444
445
    def get_parent_map(self, revision_ids):
446
        """See graph.StackedParentsProvider.get_parent_map"""
447
        return dict((revision_id, self.revisions[revision_id])
448
                    for revision_id in revision_ids
449
                     if revision_id in self.revisions)
450
451
    def snapshot_ie(self, previous_revisions, ie, w, rev_id):
452
        # TODO: convert this logic, which is ~= snapshot to
453
        # a call to:. This needs the path figured out. rather than a work_tree
454
        # a v4 revision_tree can be given, or something that looks enough like
455
        # one to give the file content to the entry if it needs it.
456
        # and we need something that looks like a weave store for snapshot to
457
        # save against.
458
        #ie.snapshot(rev, PATH, previous_revisions, REVISION_TREE, InMemoryWeaveStore(self.text_weaves))
459
        if len(previous_revisions) == 1:
460
            previous_ie = previous_revisions.values()[0]
461
            if ie._unchanged(previous_ie):
462
                ie.revision = previous_ie.revision
463
                return
464
        if ie.has_text():
465
            f = self.branch.repository._text_store.get(ie.text_id)
466
            try:
467
                file_lines = f.readlines()
468
            finally:
469
                f.close()
470
            w.add_lines(rev_id, previous_revisions, file_lines)
471
            self.text_count += 1
472
        else:
473
            w.add_lines(rev_id, previous_revisions, [])
474
        ie.revision = rev_id
475
476
    def _make_order(self):
477
        """Return a suitable order for importing revisions.
478
479
        The order must be such that an revision is imported after all
480
        its (present) parents.
481
        """
482
        todo = set(self.revisions.keys())
483
        done = self.absent_revisions.copy()
484
        order = []
485
        while todo:
486
            # scan through looking for a revision whose parents
487
            # are all done
488
            for rev_id in sorted(list(todo)):
489
                rev = self.revisions[rev_id]
490
                parent_ids = set(rev.parent_ids)
491
                if parent_ids.issubset(done):
492
                    # can take this one now
493
                    order.append(rev_id)
494
                    todo.remove(rev_id)
495
                    done.add(rev_id)
496
        return order
497
498
499
class ConvertBzrDir5To6(Converter):
500
    """Converts format 5 bzr dirs to format 6."""
501
502
    def convert(self, to_convert, pb):
503
        """See Converter.convert()."""
504
        self.bzrdir = to_convert
505
        pb = ui.ui_factory.nested_progress_bar()
506
        try:
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
507
            ui.ui_factory.note(gettext('starting upgrade from format 5 to 6'))
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
508
            self._convert_to_prefixed()
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
509
            return ControlDir.open(self.bzrdir.user_url)
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
510
        finally:
511
            pb.finished()
512
513
    def _convert_to_prefixed(self):
514
        from bzrlib.store import TransportStore
515
        self.bzrdir.transport.delete('branch-format')
516
        for store_name in ["weaves", "revision-store"]:
6150.3.6 by Jonathan Riddell
more gettext()ing
517
            ui.ui_factory.note(gettext("adding prefixes to %s") % store_name)
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
518
            store_transport = self.bzrdir.transport.clone(store_name)
519
            store = TransportStore(store_transport, prefixed=True)
520
            for urlfilename in store_transport.list_dir('.'):
521
                filename = urlutils.unescape(urlfilename)
522
                if (filename.endswith(".weave") or
523
                    filename.endswith(".gz") or
524
                    filename.endswith(".sig")):
525
                    file_id, suffix = os.path.splitext(filename)
526
                else:
527
                    file_id = filename
528
                    suffix = ''
529
                new_name = store._mapper.map((file_id,)) + suffix
530
                # FIXME keep track of the dirs made RBC 20060121
531
                try:
532
                    store_transport.move(filename, new_name)
533
                except errors.NoSuchFile: # catches missing dirs strangely enough
534
                    store_transport.mkdir(osutils.dirname(new_name))
535
                    store_transport.move(filename, new_name)
536
        self.bzrdir.transport.put_bytes(
537
            'branch-format',
538
            BzrDirFormat6().get_format_string(),
539
            mode=self.bzrdir._get_file_mode())
540
541
542
class ConvertBzrDir6ToMeta(Converter):
543
    """Converts format 6 bzr dirs to metadirs."""
544
545
    def convert(self, to_convert, pb):
546
        """See Converter.convert()."""
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
547
        from bzrlib.plugins.weave_fmt.repository import RepositoryFormat7
6517.1.6 by Jelmer Vernooij
Fix remaining tests.
548
        from bzrlib.branchfmt.fullhistory import BzrBranchFormat5
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
549
        self.bzrdir = to_convert
550
        self.pb = ui.ui_factory.nested_progress_bar()
551
        self.count = 0
552
        self.total = 20 # the steps we know about
553
        self.garbage_inventories = []
554
        self.dir_mode = self.bzrdir._get_dir_mode()
555
        self.file_mode = self.bzrdir._get_file_mode()
556
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
557
        ui.ui_factory.note(gettext('starting upgrade from format 6 to metadir'))
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
558
        self.bzrdir.transport.put_bytes(
559
                'branch-format',
560
                "Converting to format 6",
561
                mode=self.file_mode)
562
        # its faster to move specific files around than to open and use the apis...
563
        # first off, nuke ancestry.weave, it was never used.
564
        try:
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
565
            self.step(gettext('Removing ancestry.weave'))
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
566
            self.bzrdir.transport.delete('ancestry.weave')
567
        except errors.NoSuchFile:
568
            pass
569
        # find out whats there
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
570
        self.step(gettext('Finding branch files'))
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
571
        last_revision = self.bzrdir.open_branch().last_revision()
572
        bzrcontents = self.bzrdir.transport.list_dir('.')
573
        for name in bzrcontents:
574
            if name.startswith('basis-inventory.'):
575
                self.garbage_inventories.append(name)
576
        # create new directories for repository, working tree and branch
577
        repository_names = [('inventory.weave', True),
578
                            ('revision-store', True),
579
                            ('weaves', True)]
6150.3.10 by Jonathan Riddell
do not include space padding in gettext()
580
        self.step(gettext('Upgrading repository') + '  ')
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
581
        self.bzrdir.transport.mkdir('repository', mode=self.dir_mode)
582
        self.make_lock('repository')
583
        # we hard code the formats here because we are converting into
584
        # the meta format. The meta format upgrader can take this to a
585
        # future format within each component.
586
        self.put_format('repository', RepositoryFormat7())
587
        for entry in repository_names:
588
            self.move_entry('repository', entry)
589
6150.3.10 by Jonathan Riddell
do not include space padding in gettext()
590
        self.step(gettext('Upgrading branch') + '      ')
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
591
        self.bzrdir.transport.mkdir('branch', mode=self.dir_mode)
592
        self.make_lock('branch')
593
        self.put_format('branch', BzrBranchFormat5())
594
        branch_files = [('revision-history', True),
595
                        ('branch-name', True),
596
                        ('parent', False)]
597
        for entry in branch_files:
598
            self.move_entry('branch', entry)
599
600
        checkout_files = [('pending-merges', True),
601
                          ('inventory', True),
602
                          ('stat-cache', False)]
603
        # If a mandatory checkout file is not present, the branch does not have
604
        # a functional checkout. Do not create a checkout in the converted
605
        # branch.
606
        for name, mandatory in checkout_files:
607
            if mandatory and name not in bzrcontents:
608
                has_checkout = False
609
                break
610
        else:
611
            has_checkout = True
612
        if not has_checkout:
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
613
            ui.ui_factory.note(gettext('No working tree.'))
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
614
            # If some checkout files are there, we may as well get rid of them.
615
            for name, mandatory in checkout_files:
616
                if name in bzrcontents:
617
                    self.bzrdir.transport.delete(name)
618
        else:
5816.5.4 by Jelmer Vernooij
Merge bzr.dev.
619
            from bzrlib.workingtree_3 import WorkingTreeFormat3
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
620
            self.step(gettext('Upgrading working tree'))
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
621
            self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
622
            self.make_lock('checkout')
623
            self.put_format(
624
                'checkout', WorkingTreeFormat3())
625
            self.bzrdir.transport.delete_multi(
626
                self.garbage_inventories, self.pb)
627
            for entry in checkout_files:
628
                self.move_entry('checkout', entry)
629
            if last_revision is not None:
630
                self.bzrdir.transport.put_bytes(
631
                    'checkout/last-revision', last_revision)
632
        self.bzrdir.transport.put_bytes(
633
            'branch-format',
634
            BzrDirMetaFormat1().get_format_string(),
635
            mode=self.file_mode)
636
        self.pb.finished()
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
637
        return ControlDir.open(self.bzrdir.user_url)
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
638
639
    def make_lock(self, name):
640
        """Make a lock for the new control dir name."""
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
641
        self.step(gettext('Make %s lock') % name)
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
642
        ld = lockdir.LockDir(self.bzrdir.transport,
643
                             '%s/lock' % name,
644
                             file_modebits=self.file_mode,
645
                             dir_modebits=self.dir_mode)
646
        ld.create()
647
648
    def move_entry(self, new_dir, entry):
649
        """Move then entry name into new_dir."""
650
        name = entry[0]
651
        mandatory = entry[1]
6150.3.2 by Jonathan Riddell
gettext() on weave plugin
652
        self.step(gettext('Moving %s') % name)
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
653
        try:
654
            self.bzrdir.transport.move(name, '%s/%s' % (new_dir, name))
655
        except errors.NoSuchFile:
656
            if mandatory:
657
                raise
658
659
    def put_format(self, dirname, format):
660
        self.bzrdir.transport.put_bytes('%s/format' % dirname,
661
            format.get_format_string(),
662
            self.file_mode)
663
664
665
class BzrDirFormat4(BzrDirFormat):
666
    """Bzr dir format 4.
667
668
    This format is a combined format for working tree, branch and repository.
669
    It has:
670
     - Format 1 working trees [always]
671
     - Format 4 branches [always]
672
     - Format 4 repositories [always]
673
674
    This format is deprecated: it indexes texts using a text it which is
675
    removed in format 5; write support for this format has been removed.
676
    """
677
678
    _lock_class = lockable_files.TransportLock
679
5712.4.7 by Jelmer Vernooij
More fixes.
680
    def __eq__(self, other):
681
        return type(self) == type(other)
682
6213.1.16 by Jelmer Vernooij
Feature support in repository.
683
    @classmethod
684
    def get_format_string(cls):
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
685
        """See BzrDirFormat.get_format_string()."""
686
        return "Bazaar-NG branch, format 0.0.4\n"
687
688
    def get_format_description(self):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
689
        """See ControlDirFormat.get_format_description()."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
690
        return "All-in-one format 4"
691
692
    def get_converter(self, format=None):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
693
        """See ControlDirFormat.get_converter()."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
694
        # there is one and only one upgrade path here.
695
        return ConvertBzrDir4To5()
696
697
    def initialize_on_transport(self, transport):
698
        """Format 4 branches cannot be created."""
699
        raise errors.UninitializableFormat(self)
700
701
    def is_supported(self):
702
        """Format 4 is not supported.
703
704
        It is not supported because the model changed from 4 to 5 and the
705
        conversion logic is expensive - so doing it on the fly was not
706
        feasible.
707
        """
708
        return False
709
710
    def network_name(self):
711
        return self.get_format_string()
712
713
    def _open(self, transport):
714
        """See BzrDirFormat._open."""
715
        return BzrDir4(transport, self)
716
717
    def __return_repository_format(self):
718
        """Circular import protection."""
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
719
        from bzrlib.plugins.weave_fmt.repository import RepositoryFormat4
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
720
        return RepositoryFormat4()
721
    repository_format = property(__return_repository_format)
722
6213.1.19 by Jelmer Vernooij
Fix tests.
723
    @classmethod
724
    def from_string(cls, format_string):
725
        if format_string != cls.get_format_string():
726
            raise AssertionError("unexpected format string %r" % format_string)
727
        return cls()
728
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
729
730
class BzrDirPreSplitOut(BzrDir):
731
    """A common class for the all-in-one formats."""
732
733
    def __init__(self, _transport, _format):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
734
        """See ControlDir.__init__."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
735
        super(BzrDirPreSplitOut, self).__init__(_transport, _format)
736
        self._control_files = lockable_files.LockableFiles(
737
                                            self.get_branch_transport(None),
738
                                            self._format._lock_file_name,
739
                                            self._format._lock_class)
740
741
    def break_lock(self):
742
        """Pre-splitout bzrdirs do not suffer from stale locks."""
743
        raise NotImplementedError(self.break_lock)
744
745
    def cloning_metadir(self, require_stacking=False):
746
        """Produce a metadir suitable for cloning with."""
747
        if require_stacking:
748
            return format_registry.make_bzrdir('1.6')
749
        return self._format.__class__()
750
751
    def clone(self, url, revision_id=None, force_new_repo=False,
752
              preserve_stacking=False):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
753
        """See ControlDir.clone().
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
754
755
        force_new_repo has no effect, since this family of formats always
756
        require a new repository.
757
        preserve_stacking has no effect, since no source branch using this
758
        family of formats can be stacked, so there is no stacking to preserve.
759
        """
760
        self._make_tail(url)
761
        result = self._format._initialize_for_clone(url)
762
        self.open_repository().clone(result, revision_id=revision_id)
763
        from_branch = self.open_branch()
764
        from_branch.clone(result, revision_id=revision_id)
765
        try:
766
            tree = self.open_workingtree()
767
        except errors.NotLocalUrl:
768
            # make a new one, this format always has to have one.
769
            result._init_workingtree()
770
        else:
771
            tree.clone(result)
772
        return result
773
6123.9.12 by Jelmer Vernooij
Add append_revisions_only argument to BranchFormat.initialize.
774
    def create_branch(self, name=None, repository=None,
775
                      append_revisions_only=None):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
776
        """See ControlDir.create_branch."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
777
        if repository is not None:
778
            raise NotImplementedError(
779
                "create_branch(repository=<not None>) on %r" % (self,))
6123.9.12 by Jelmer Vernooij
Add append_revisions_only argument to BranchFormat.initialize.
780
        return self._format.get_branch_format().initialize(self, name=name,
781
            append_revisions_only=append_revisions_only)
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
782
783
    def destroy_branch(self, name=None):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
784
        """See ControlDir.destroy_branch."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
785
        raise errors.UnsupportedOperation(self.destroy_branch, self)
786
787
    def create_repository(self, shared=False):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
788
        """See ControlDir.create_repository."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
789
        if shared:
790
            raise errors.IncompatibleFormat('shared repository', self._format)
791
        return self.open_repository()
792
793
    def destroy_repository(self):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
794
        """See ControlDir.destroy_repository."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
795
        raise errors.UnsupportedOperation(self.destroy_repository, self)
796
797
    def create_workingtree(self, revision_id=None, from_branch=None,
798
                           accelerator_tree=None, hardlink=False):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
799
        """See ControlDir.create_workingtree."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
800
        # The workingtree is sometimes created when the bzrdir is created,
801
        # but not when cloning.
802
803
        # this looks buggy but is not -really-
804
        # because this format creates the workingtree when the bzrdir is
805
        # created
806
        # clone and sprout will have set the revision_id
807
        # and that will have set it for us, its only
808
        # specific uses of create_workingtree in isolation
809
        # that can do wonky stuff here, and that only
810
        # happens for creating checkouts, which cannot be
811
        # done on this format anyway. So - acceptable wart.
812
        if hardlink:
813
            warning("can't support hardlinked working trees in %r"
814
                % (self,))
815
        try:
816
            result = self.open_workingtree(recommend_upgrade=False)
817
        except errors.NoSuchFile:
818
            result = self._init_workingtree()
819
        if revision_id is not None:
820
            if revision_id == _mod_revision.NULL_REVISION:
821
                result.set_parent_ids([])
822
            else:
823
                result.set_parent_ids([revision_id])
824
        return result
825
826
    def _init_workingtree(self):
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
827
        from bzrlib.plugins.weave_fmt.workingtree import WorkingTreeFormat2
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
828
        try:
829
            return WorkingTreeFormat2().initialize(self)
830
        except errors.NotLocalUrl:
831
            # Even though we can't access the working tree, we need to
832
            # create its control files.
833
            return WorkingTreeFormat2()._stub_initialize_on_transport(
834
                self.transport, self._control_files._file_mode)
835
836
    def destroy_workingtree(self):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
837
        """See ControlDir.destroy_workingtree."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
838
        raise errors.UnsupportedOperation(self.destroy_workingtree, self)
839
840
    def destroy_workingtree_metadata(self):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
841
        """See ControlDir.destroy_workingtree_metadata."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
842
        raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
843
                                          self)
844
845
    def get_branch_transport(self, branch_format, name=None):
846
        """See BzrDir.get_branch_transport()."""
847
        if name is not None:
848
            raise errors.NoColocatedBranchSupport(self)
849
        if branch_format is None:
850
            return self.transport
851
        try:
852
            branch_format.get_format_string()
853
        except NotImplementedError:
854
            return self.transport
855
        raise errors.IncompatibleFormat(branch_format, self._format)
856
857
    def get_repository_transport(self, repository_format):
858
        """See BzrDir.get_repository_transport()."""
859
        if repository_format is None:
860
            return self.transport
861
        try:
862
            repository_format.get_format_string()
863
        except NotImplementedError:
864
            return self.transport
865
        raise errors.IncompatibleFormat(repository_format, self._format)
866
867
    def get_workingtree_transport(self, workingtree_format):
868
        """See BzrDir.get_workingtree_transport()."""
869
        if workingtree_format is None:
870
            return self.transport
871
        try:
872
            workingtree_format.get_format_string()
873
        except NotImplementedError:
874
            return self.transport
875
        raise errors.IncompatibleFormat(workingtree_format, self._format)
876
877
    def needs_format_conversion(self, format=None):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
878
        """See ControlDir.needs_format_conversion()."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
879
        # if the format is not the same as the system default,
880
        # an upgrade is needed.
881
        if format is None:
882
            symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
883
                % 'needs_format_conversion(format=None)')
884
            format = BzrDirFormat.get_default_format()
885
        return not isinstance(self._format, format.__class__)
886
887
    def open_branch(self, name=None, unsupported=False,
6305.3.3 by Jelmer Vernooij
Fix use of possible_transports.
888
                    ignore_fallbacks=False, possible_transports=None):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
889
        """See ControlDir.open_branch."""
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
890
        from bzrlib.plugins.weave_fmt.branch import BzrBranchFormat4
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
891
        format = BzrBranchFormat4()
5717.1.10 by Jelmer Vernooij
Fix typo.
892
        format.check_support_status(unsupported)
6305.3.3 by Jelmer Vernooij
Fix use of possible_transports.
893
        return format.open(self, name, _found=True,
894
            possible_transports=possible_transports)
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
895
896
    def sprout(self, url, revision_id=None, force_new_repo=False,
897
               possible_transports=None, accelerator_tree=None,
898
               hardlink=False, stacked=False, create_tree_if_local=True,
899
               source_branch=None):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
900
        """See ControlDir.sprout()."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
901
        if source_branch is not None:
902
            my_branch = self.open_branch()
903
            if source_branch.base != my_branch.base:
904
                raise AssertionError(
905
                    "source branch %r is not within %r with branch %r" %
906
                    (source_branch, self, my_branch))
907
        if stacked:
908
            raise errors.UnstackableBranchFormat(
909
                self._format, self.root_transport.base)
910
        if not create_tree_if_local:
911
            raise errors.MustHaveWorkingTree(
912
                self._format, self.root_transport.base)
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
913
        from bzrlib.plugins.weave_fmt.workingtree import WorkingTreeFormat2
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
914
        self._make_tail(url)
915
        result = self._format._initialize_for_clone(url)
916
        try:
917
            self.open_repository().clone(result, revision_id=revision_id)
918
        except errors.NoRepositoryPresent:
919
            pass
920
        try:
921
            self.open_branch().sprout(result, revision_id=revision_id)
922
        except errors.NotBranchError:
923
            pass
924
925
        # we always want a working tree
926
        WorkingTreeFormat2().initialize(result,
927
                                        accelerator_tree=accelerator_tree,
928
                                        hardlink=hardlink)
929
        return result
930
6437.7.1 by Jelmer Vernooij
Add ControlDir.set_branch_reference.
931
    def set_branch_reference(self, target_branch, name=None):
932
        from bzrlib.branch import BranchReferenceFormat
6437.7.4 by Jelmer Vernooij
Fix test.
933
        if name is not None:
934
            raise errors.NoColocatedBranchSupport(self)
6437.7.1 by Jelmer Vernooij
Add ControlDir.set_branch_reference.
935
        raise errors.IncompatibleFormat(BranchReferenceFormat, self._format)
936
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
937
938
class BzrDir4(BzrDirPreSplitOut):
939
    """A .bzr version 4 control object.
940
941
    This is a deprecated format and may be removed after sept 2006.
942
    """
943
944
    def create_repository(self, shared=False):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
945
        """See ControlDir.create_repository."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
946
        return self._format.repository_format.initialize(self, shared)
947
948
    def needs_format_conversion(self, format=None):
949
        """Format 4 dirs are always in need of conversion."""
950
        if format is None:
951
            symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
952
                % 'needs_format_conversion(format=None)')
953
        return True
954
955
    def open_repository(self):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
956
        """See ControlDir.open_repository."""
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
957
        from bzrlib.plugins.weave_fmt.repository import RepositoryFormat4
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
958
        return RepositoryFormat4().open(self, _found=True)
959
960
961
class BzrDir5(BzrDirPreSplitOut):
962
    """A .bzr version 5 control object.
963
964
    This is a deprecated format and may be removed after sept 2006.
965
    """
966
967
    def has_workingtree(self):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
968
        """See ControlDir.has_workingtree."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
969
        return True
970
    
971
    def open_repository(self):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
972
        """See ControlDir.open_repository."""
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
973
        from bzrlib.plugins.weave_fmt.repository import RepositoryFormat5
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
974
        return RepositoryFormat5().open(self, _found=True)
975
6402.1.2 by Jelmer Vernooij
Fix tests.
976
    def open_workingtree(self, unsupported=False,
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
977
            recommend_upgrade=True):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
978
        """See ControlDir.create_workingtree."""
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
979
        from bzrlib.plugins.weave_fmt.workingtree import WorkingTreeFormat2
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
980
        wt_format = WorkingTreeFormat2()
981
        # we don't warn here about upgrades; that ought to be handled for the
982
        # bzrdir as a whole
983
        return wt_format.open(self, _found=True)
984
985
986
class BzrDir6(BzrDirPreSplitOut):
987
    """A .bzr version 6 control object.
988
989
    This is a deprecated format and may be removed after sept 2006.
990
    """
991
992
    def has_workingtree(self):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
993
        """See ControlDir.has_workingtree."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
994
        return True
995
996
    def open_repository(self):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
997
        """See ControlDir.open_repository."""
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
998
        from bzrlib.plugins.weave_fmt.repository import RepositoryFormat6
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
999
        return RepositoryFormat6().open(self, _found=True)
1000
6402.1.2 by Jelmer Vernooij
Fix tests.
1001
    def open_workingtree(self, unsupported=False, recommend_upgrade=True):
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
1002
        """See ControlDir.create_workingtree."""
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
1003
        # we don't warn here about upgrades; that ought to be handled for the
1004
        # bzrdir as a whole
5582.10.90 by Jelmer Vernooij
Merge weave-bzrdir branch.
1005
        from bzrlib.plugins.weave_fmt.workingtree import WorkingTreeFormat2
5712.4.1 by Jelmer Vernooij
Move weave-era BzrDir directories to a separate file.
1006
        return WorkingTreeFormat2().open(self, _found=True)