/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/plugins/weave_fmt/bzrdir.py

  • Committer: Jelmer Vernooij
  • Date: 2017-07-23 22:06:41 UTC
  • mfrom: (6738 trunk)
  • mto: This revision was merged to the branch mainline in revision 6739.
  • Revision ID: jelmer@jelmer.uk-20170723220641-69eczax9bmv8d6kk
Merge trunk, address review comments.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Weave-era BzrDir formats."""
18
18
 
19
 
from io import BytesIO
 
19
from __future__ import absolute_import
20
20
 
21
21
from ...bzr.bzrdir import (
22
22
    BzrDir,
26
26
from ...controldir import (
27
27
    ControlDir,
28
28
    Converter,
29
 
    MustHaveWorkingTree,
30
29
    format_registry,
31
30
    )
32
 
from ... import (
33
 
    errors,
34
 
    )
35
31
from ...lazy_import import lazy_import
36
32
lazy_import(globals(), """
37
33
import os
38
34
import warnings
39
35
 
40
36
from breezy import (
41
 
    branch as _mod_branch,,
 
37
    errors,
42
38
    graph,
43
39
    lockable_files,
44
40
    lockdir,
70
66
    fixed_components = True
71
67
 
72
68
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
73
 
                                   create_prefix=False, force_new_repo=False, stacked_on=None,
74
 
                                   stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
75
 
                                   shared_repo=False):
 
69
        create_prefix=False, force_new_repo=False, stacked_on=None,
 
70
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
 
71
        shared_repo=False):
76
72
        """See ControlDir.initialize_on_transport_ex."""
77
73
        require_stacking = (stacked_on is not None)
78
74
        # Format 5 cannot stack, but we've been asked to - actually init
80
76
        if require_stacking:
81
77
            format = BzrDirMetaFormat1()
82
78
            return format.initialize_on_transport_ex(transport,
83
 
                                                     use_existing_dir=use_existing_dir, create_prefix=create_prefix,
84
 
                                                     force_new_repo=force_new_repo, stacked_on=stacked_on,
85
 
                                                     stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
86
 
                                                     make_working_trees=make_working_trees, shared_repo=shared_repo)
 
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)
87
83
        return BzrDirFormat.initialize_on_transport_ex(self, transport,
88
 
                                                       use_existing_dir=use_existing_dir, create_prefix=create_prefix,
89
 
                                                       force_new_repo=force_new_repo, stacked_on=stacked_on,
90
 
                                                       stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
91
 
                                                       make_working_trees=make_working_trees, shared_repo=shared_repo)
 
84
            use_existing_dir=use_existing_dir, create_prefix=create_prefix,
 
85
            force_new_repo=force_new_repo, stacked_on=stacked_on,
 
86
            stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
 
87
            make_working_trees=make_working_trees, shared_repo=shared_repo)
92
88
 
93
89
    @classmethod
94
90
    def from_string(cls, format_string):
116
112
    @classmethod
117
113
    def get_format_string(cls):
118
114
        """See BzrDirFormat.get_format_string()."""
119
 
        return b"Bazaar-NG branch, format 5\n"
 
115
        return "Bazaar-NG branch, format 5\n"
120
116
 
121
117
    def get_branch_format(self):
122
118
        from .branch import BzrBranchFormat4
180
176
    @classmethod
181
177
    def get_format_string(cls):
182
178
        """See BzrDirFormat.get_format_string()."""
183
 
        return b"Bazaar-NG branch, format 6\n"
 
179
        return "Bazaar-NG branch, format 6\n"
184
180
 
185
181
    def get_format_description(self):
186
182
        """See ControlDirFormat.get_format_description()."""
241
237
        self.controldir = to_convert
242
238
        if pb is not None:
243
239
            warnings.warn(gettext("pb parameter to convert() is deprecated"))
244
 
        with ui.ui_factory.nested_progress_bar() as self.pb:
 
240
        self.pb = ui.ui_factory.nested_progress_bar()
 
241
        try:
245
242
            ui.ui_factory.note(gettext('starting upgrade from format 4 to 5'))
246
243
            if isinstance(self.controldir.transport, local.LocalTransport):
247
 
                self.controldir.get_workingtree_transport(
248
 
                    None).delete('stat-cache')
 
244
                self.controldir.get_workingtree_transport(None).delete('stat-cache')
249
245
            self._convert_to_weaves()
250
246
            return ControlDir.open(self.controldir.user_url)
 
247
        finally:
 
248
            self.pb.finished()
251
249
 
252
250
    def _convert_to_weaves(self):
253
251
        ui.ui_factory.note(gettext(
254
 
            'note: upgrade may be faster if all store files are ungzipped first'))
 
252
          'note: upgrade may be faster if all store files are ungzipped first'))
255
253
        try:
256
254
            # TODO permissions
257
255
            stat = self.controldir.transport.stat('weaves')
274
272
        self.to_read = rev_history[-1:]
275
273
        while self.to_read:
276
274
            rev_id = self.to_read.pop()
277
 
            if (rev_id not in self.revisions and
278
 
                    rev_id not in self.absent_revisions):
 
275
            if (rev_id not in self.revisions
 
276
                and rev_id not in self.absent_revisions):
279
277
                self._load_one_rev(rev_id)
280
278
        self.pb.clear()
281
279
        to_import = self._make_order()
287
285
        self._write_all_revs()
288
286
        ui.ui_factory.note(gettext('upgraded to weaves:'))
289
287
        ui.ui_factory.note('  ' + gettext('%6d revisions and inventories') %
290
 
                           len(self.revisions))
 
288
                                                        len(self.revisions))
291
289
        ui.ui_factory.note('  ' + gettext('%6d revisions not present') %
292
 
                           len(self.absent_revisions))
 
290
                                                    len(self.absent_revisions))
293
291
        ui.ui_factory.note('  ' + gettext('%6d texts') % self.text_count)
294
292
        self._cleanup_spare_files_after_format4()
295
293
        self.branch._transport.put_bytes(
310
308
 
311
309
    def _convert_working_inv(self):
312
310
        inv = xml4.serializer_v4.read_inventory(
313
 
            self.branch._transport.get('inventory'))
314
 
        f = BytesIO()
315
 
        xml5.serializer_v5.write_inventory(inv, f, working=True)
316
 
        self.branch._transport.put_bytes('inventory', f.getvalue(),
317
 
                                         mode=self.controldir._get_file_mode())
 
311
                self.branch._transport.get('inventory'))
 
312
        new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv, working=True)
 
313
        self.branch._transport.put_bytes('inventory', new_inv_xml,
 
314
            mode=self.controldir._get_file_mode())
318
315
 
319
316
    def _write_all_weaves(self):
320
317
        controlweaves = VersionedFileStore(self.controldir.transport, prefixed=False,
321
 
                                           versionedfile_class=weave.WeaveFile)
 
318
            versionedfile_class=weave.WeaveFile)
322
319
        weave_transport = self.controldir.transport.clone('weaves')
323
320
        weaves = VersionedFileStore(weave_transport, prefixed=False,
324
 
                                    versionedfile_class=weave.WeaveFile)
 
321
                versionedfile_class=weave.WeaveFile)
325
322
        transaction = WriteTransaction()
326
323
 
327
324
        try:
328
325
            i = 0
329
326
            for file_id, file_weave in self.text_weaves.items():
330
327
                self.pb.update(gettext('writing weave'), i,
331
 
                               len(self.text_weaves))
 
328
                                                        len(self.text_weaves))
332
329
                weaves._put_weave(file_id, file_weave, transaction)
333
330
                i += 1
334
331
            self.pb.update(gettext('inventory'), 0, 1)
335
 
            controlweaves._put_weave(b'inventory', self.inv_weave, transaction)
 
332
            controlweaves._put_weave('inventory', self.inv_weave, transaction)
336
333
            self.pb.update(gettext('inventory'), 1, 1)
337
334
        finally:
338
335
            self.pb.clear()
346
343
        from ...bzr.xml5 import serializer_v5
347
344
        from .repository import RevisionTextStore
348
345
        revision_store = RevisionTextStore(revision_transport,
349
 
                                           serializer_v5, False, versionedfile.PrefixMapper(),
350
 
                                           lambda: True, lambda: True)
 
346
            serializer_v5, False, versionedfile.PrefixMapper(),
 
347
            lambda:True, lambda:True)
351
348
        try:
352
349
            for i, rev_id in enumerate(self.converted_revs):
353
350
                self.pb.update(gettext('write revision'), i,
354
 
                               len(self.converted_revs))
355
 
                lines = serializer_v5.write_revision_to_lines(
 
351
                                                len(self.converted_revs))
 
352
                text = serializer_v5.write_revision_to_string(
356
353
                    self.revisions[rev_id])
357
354
                key = (rev_id,)
358
 
                revision_store.add_lines(key, None, lines)
 
355
                revision_store.add_lines(key, None, osutils.split_lines(text))
359
356
        finally:
360
357
            self.pb.clear()
361
358
 
370
367
        if not self.branch.repository.has_revision(rev_id):
371
368
            self.pb.clear()
372
369
            ui.ui_factory.note(gettext('revision {%s} not present in branch; '
373
 
                                       'will be converted as a ghost') %
374
 
                               rev_id)
 
370
                         'will be converted as a ghost') %
 
371
                         rev_id)
375
372
            self.absent_revisions.add(rev_id)
376
373
        else:
377
374
            rev = self.branch.repository.get_revision(rev_id)
381
378
            self.revisions[rev_id] = rev
382
379
 
383
380
    def _load_old_inventory(self, rev_id):
384
 
        with self.branch.repository.inventory_store.get(rev_id) as f:
385
 
            inv = xml4.serializer_v4.read_inventory(f)
 
381
        f = self.branch.repository.inventory_store.get(rev_id)
 
382
        try:
 
383
            old_inv_xml = f.read()
 
384
        finally:
 
385
            f.close()
 
386
        inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
386
387
        inv.revision_id = rev_id
387
388
        rev = self.revisions[rev_id]
388
389
        return inv
389
390
 
390
391
    def _load_updated_inventory(self, rev_id):
391
 
        inv_xml = self.inv_weave.get_lines(rev_id)
392
 
        inv = xml5.serializer_v5.read_inventory_from_lines(inv_xml, rev_id)
 
392
        inv_xml = self.inv_weave.get_text(rev_id)
 
393
        inv = xml5.serializer_v5.read_inventory_from_string(inv_xml, rev_id)
393
394
        return inv
394
395
 
395
396
    def _convert_one_rev(self, rev_id):
403
404
        self.converted_revs.add(rev_id)
404
405
 
405
406
    def _store_new_inv(self, rev, inv, present_parents):
406
 
        new_inv_xml = xml5.serializer_v5.write_inventory_to_lines(inv)
407
 
        new_inv_sha1 = osutils.sha_strings(new_inv_xml)
 
407
        new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
 
408
        new_inv_sha1 = osutils.sha_string(new_inv_xml)
408
409
        self.inv_weave.add_lines(rev.revision_id,
409
410
                                 present_parents,
410
 
                                 new_inv_xml)
 
411
                                 new_inv_xml.splitlines(True))
411
412
        rev.inventory_sha1 = new_inv_sha1
412
413
 
413
414
    def _convert_revision_contents(self, rev, inv, present_parents):
439
440
        heads = graph.Graph(self).heads(parent_candiate_entries)
440
441
        # XXX: Note that this is unordered - and this is tolerable because
441
442
        # the previous code was also unordered.
442
 
        previous_entries = {head: parent_candiate_entries[head]
443
 
                            for head in heads}
 
443
        previous_entries = dict((head, parent_candiate_entries[head]) for head
 
444
            in heads)
444
445
        self.snapshot_ie(previous_entries, ie, w, rev_id)
445
446
 
446
447
    def get_parent_map(self, revision_ids):
447
448
        """See graph.StackedParentsProvider.get_parent_map"""
448
449
        return dict((revision_id, self.revisions[revision_id])
449
450
                    for revision_id in revision_ids
450
 
                    if revision_id in self.revisions)
 
451
                     if revision_id in self.revisions)
451
452
 
452
453
    def snapshot_ie(self, previous_revisions, ie, w, rev_id):
453
454
        # TODO: convert this logic, which is ~= snapshot to
463
464
                ie.revision = previous_ie.revision
464
465
                return
465
466
        if ie.has_text():
466
 
            with self.branch.repository._text_store.get(ie.text_id) as f:
 
467
            f = self.branch.repository._text_store.get(ie.text_id)
 
468
            try:
467
469
                file_lines = f.readlines()
 
470
            finally:
 
471
                f.close()
468
472
            w.add_lines(rev_id, previous_revisions, file_lines)
469
473
            self.text_count += 1
470
474
        else:
500
504
    def convert(self, to_convert, pb):
501
505
        """See Converter.convert()."""
502
506
        self.controldir = to_convert
503
 
        with ui.ui_factory.nested_progress_bar() as pb:
 
507
        pb = ui.ui_factory.nested_progress_bar()
 
508
        try:
504
509
            ui.ui_factory.note(gettext('starting upgrade from format 5 to 6'))
505
510
            self._convert_to_prefixed()
506
511
            return ControlDir.open(self.controldir.user_url)
 
512
        finally:
 
513
            pb.finished()
507
514
 
508
515
    def _convert_to_prefixed(self):
509
516
        from .store import TransportStore
514
521
            store = TransportStore(store_transport, prefixed=True)
515
522
            for urlfilename in store_transport.list_dir('.'):
516
523
                filename = urlutils.unescape(urlfilename)
517
 
                if (filename.endswith(".weave")
518
 
                    or filename.endswith(".gz")
519
 
                        or filename.endswith(".sig")):
 
524
                if (filename.endswith(".weave") or
 
525
                    filename.endswith(".gz") or
 
526
                    filename.endswith(".sig")):
520
527
                    file_id, suffix = os.path.splitext(filename)
521
528
                else:
522
529
                    file_id = filename
523
530
                    suffix = ''
524
 
                new_name = store._mapper.map(
525
 
                    (file_id.encode('utf-8'),)) + suffix
 
531
                new_name = store._mapper.map((file_id,)) + suffix
526
532
                # FIXME keep track of the dirs made RBC 20060121
527
533
                try:
528
534
                    store_transport.move(filename, new_name)
529
 
                except errors.NoSuchFile:  # catches missing dirs strangely enough
 
535
                except errors.NoSuchFile: # catches missing dirs strangely enough
530
536
                    store_transport.mkdir(osutils.dirname(new_name))
531
537
                    store_transport.move(filename, new_name)
532
538
        self.controldir.transport.put_bytes(
545
551
        self.controldir = to_convert
546
552
        self.pb = ui.ui_factory.nested_progress_bar()
547
553
        self.count = 0
548
 
        self.total = 20  # the steps we know about
 
554
        self.total = 20 # the steps we know about
549
555
        self.garbage_inventories = []
550
556
        self.dir_mode = self.controldir._get_dir_mode()
551
557
        self.file_mode = self.controldir._get_file_mode()
552
558
 
553
 
        ui.ui_factory.note(
554
 
            gettext('starting upgrade from format 6 to metadir'))
 
559
        ui.ui_factory.note(gettext('starting upgrade from format 6 to metadir'))
555
560
        self.controldir.transport.put_bytes(
556
 
            'branch-format',
557
 
            b"Converting to format 6",
558
 
            mode=self.file_mode)
 
561
                'branch-format',
 
562
                "Converting to format 6",
 
563
                mode=self.file_mode)
559
564
        # its faster to move specific files around than to open and use the apis...
560
565
        # first off, nuke ancestry.weave, it was never used.
561
566
        try:
617
622
            self.step(gettext('Upgrading working tree'))
618
623
            self.controldir.transport.mkdir('checkout', mode=self.dir_mode)
619
624
            self.make_lock('checkout')
620
 
            self.put_format('checkout', WorkingTreeFormat3())
621
 
            for path in self.garbage_inventories:
622
 
                self.controldir.transport.delete(path)
 
625
            self.put_format(
 
626
                'checkout', WorkingTreeFormat3())
 
627
            self.controldir.transport.delete_multi(
 
628
                self.garbage_inventories, self.pb)
623
629
            for entry in checkout_files:
624
630
                self.move_entry('checkout', entry)
625
631
            if last_revision is not None:
654
660
 
655
661
    def put_format(self, dirname, format):
656
662
        self.controldir.transport.put_bytes('%s/format' % dirname,
657
 
                                            format.get_format_string(),
658
 
                                            self.file_mode)
 
663
            format.get_format_string(),
 
664
            self.file_mode)
659
665
 
660
666
 
661
667
class BzrDirFormat4(BzrDirFormat):
679
685
    @classmethod
680
686
    def get_format_string(cls):
681
687
        """See BzrDirFormat.get_format_string()."""
682
 
        return b"Bazaar-NG branch, format 0.0.4\n"
 
688
        return "Bazaar-NG branch, format 0.0.4\n"
683
689
 
684
690
    def get_format_description(self):
685
691
        """See ControlDirFormat.get_format_description()."""
730
736
        """See ControlDir.__init__."""
731
737
        super(BzrDirPreSplitOut, self).__init__(_transport, _format)
732
738
        self._control_files = lockable_files.LockableFiles(
733
 
            self.get_branch_transport(None),
734
 
            self._format._lock_file_name,
735
 
            self._format._lock_class)
 
739
                                            self.get_branch_transport(None),
 
740
                                            self._format._lock_file_name,
 
741
                                            self._format._lock_class)
736
742
 
737
743
    def break_lock(self):
738
744
        """Pre-splitout bzrdirs do not suffer from stale locks."""
745
751
        return self._format.__class__()
746
752
 
747
753
    def clone(self, url, revision_id=None, force_new_repo=False,
748
 
              preserve_stacking=False, tag_selector=None):
 
754
              preserve_stacking=False):
749
755
        """See ControlDir.clone().
750
756
 
751
757
        force_new_repo has no effect, since this family of formats always
757
763
        result = self._format._initialize_for_clone(url)
758
764
        self.open_repository().clone(result, revision_id=revision_id)
759
765
        from_branch = self.open_branch()
760
 
        from_branch.clone(result, revision_id=revision_id, tag_selector=tag_selector)
 
766
        from_branch.clone(result, revision_id=revision_id)
761
767
        try:
762
768
            tree = self.open_workingtree()
763
769
        except errors.NotLocalUrl:
774
780
            raise NotImplementedError(
775
781
                "create_branch(repository=<not None>) on %r" % (self,))
776
782
        return self._format.get_branch_format().initialize(self, name=name,
777
 
                                                           append_revisions_only=append_revisions_only)
 
783
            append_revisions_only=append_revisions_only)
778
784
 
779
785
    def destroy_branch(self, name=None):
780
786
        """See ControlDir.destroy_branch."""
807
813
        # done on this format anyway. So - acceptable wart.
808
814
        if hardlink:
809
815
            warning("can't support hardlinked working trees in %r"
810
 
                    % (self,))
 
816
                % (self,))
811
817
        try:
812
818
            result = self.open_workingtree(recommend_upgrade=False)
813
819
        except errors.NoSuchFile:
840
846
 
841
847
    def get_branch_transport(self, branch_format, name=None):
842
848
        """See BzrDir.get_branch_transport()."""
843
 
        if name:
 
849
        if name is not None:
844
850
            raise errors.NoColocatedBranchSupport(self)
845
851
        if branch_format is None:
846
852
            return self.transport
883
889
        format = BzrBranchFormat4()
884
890
        format.check_support_status(unsupported)
885
891
        return format.open(self, name, _found=True,
886
 
                           possible_transports=possible_transports)
 
892
            possible_transports=possible_transports)
887
893
 
888
894
    def sprout(self, url, revision_id=None, force_new_repo=False,
889
 
               recurse=None, possible_transports=None, accelerator_tree=None,
 
895
               possible_transports=None, accelerator_tree=None,
890
896
               hardlink=False, stacked=False, create_tree_if_local=True,
891
897
               source_branch=None):
892
898
        """See ControlDir.sprout()."""
897
903
                    "source branch %r is not within %r with branch %r" %
898
904
                    (source_branch, self, my_branch))
899
905
        if stacked:
900
 
            raise _mod_branch.UnstackableBranchFormat(
 
906
            raise errors.UnstackableBranchFormat(
901
907
                self._format, self.root_transport.base)
902
908
        if not create_tree_if_local:
903
 
            raise MustHaveWorkingTree(
 
909
            raise errors.MustHaveWorkingTree(
904
910
                self._format, self.root_transport.base)
905
911
        from .workingtree import WorkingTreeFormat2
906
912
        self._make_tail(url)
956
962
    def has_workingtree(self):
957
963
        """See ControlDir.has_workingtree."""
958
964
        return True
959
 
 
 
965
    
960
966
    def open_repository(self):
961
967
        """See ControlDir.open_repository."""
962
968
        from .repository import RepositoryFormat5
963
969
        return RepositoryFormat5().open(self, _found=True)
964
970
 
965
971
    def open_workingtree(self, unsupported=False,
966
 
                         recommend_upgrade=True):
 
972
            recommend_upgrade=True):
967
973
        """See ControlDir.create_workingtree."""
968
974
        from .workingtree import WorkingTreeFormat2
969
975
        wt_format = WorkingTreeFormat2()