/brz/remove-bazaar

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